feat(dm): clickable route popup for long delivery paths

Long routes (>4 hops) show truncated with dotted underline; clicking
opens a popup with the full route and hop count, same style as channel
message path popups. Short routes (<=4 hops) display inline as before.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-03-28 14:44:40 +01:00
parent 7d8a3c895d
commit 90c1c90ba3
2 changed files with 52 additions and 4 deletions

View File

@@ -750,6 +750,13 @@ main {
margin-top: 0.1rem;
}
.dm-route-link {
cursor: pointer;
text-decoration: underline;
text-decoration-style: dotted;
position: relative;
}
.dm-delivery-popup {
position: absolute;
bottom: 100%;

View File

@@ -1195,11 +1195,10 @@ function displayMessages(messages) {
}
// Show route only for delivered messages (not failed)
if (msg.status === 'delivered') {
const hexRoute = formatDmRoute(msg.delivery_path);
if (hexRoute) {
parts.push(`Route: ${hexRoute}`);
const routeHtml = buildDmRouteHtml(msg.delivery_path);
if (routeHtml) {
parts.push(routeHtml);
} else if (msg.delivery_route) {
// Fallback: show ACK route type (e.g. FLOOD, direct)
parts.push(msg.delivery_route.replace('PATH_', ''));
}
}
@@ -1386,6 +1385,48 @@ function formatDmRoute(hexPath) {
return segments.join('\u2192');
}
/**
* Build a clickable route span for DM delivery meta.
* Short routes are plain text; long routes (>4 hops) are clickable to show full path.
*/
function buildDmRouteHtml(hexPath) {
if (!hexPath || !/^[0-9a-f]+$/i.test(hexPath)) return '';
const segments = hexPath.match(/.{1,2}/g) || [];
if (segments.length === 0) return '';
const short = segments.length > 4
? `${segments[0]}\u2192...\u2192${segments[segments.length - 1]}`
: segments.join('\u2192');
if (segments.length <= 4) return `Route: ${short}`;
const escaped = hexPath.replace(/'/g, "\\'");
return `<span class="dm-route-link" onclick="showDmRoutePopup(this, '${escaped}')">Route: ${short}</span>`;
}
/**
* Show full route popup for DM delivery path (same style as channel path popup)
*/
function showDmRoutePopup(element, hexPath) {
const existing = document.querySelector('.path-popup');
if (existing) existing.remove();
const segments = hexPath.match(/.{1,2}/g) || [];
const fullRoute = segments.join(' \u2192 ');
const popup = document.createElement('div');
popup.className = 'path-popup';
popup.innerHTML = `<div class="path-entry">${fullRoute}<span class="path-detail">Hops: ${segments.length}</span></div>`;
element.style.position = 'relative';
element.appendChild(popup);
const dismiss = () => popup.remove();
setTimeout(dismiss, 8000);
document.addEventListener('click', function handler(e) {
if (!element.contains(e.target)) {
dismiss();
document.removeEventListener('click', handler);
}
});
}
/**
* Show delivery info popup (mobile-friendly, same pattern as showPathPopup)
*/