diff --git a/app/static/js/path-analyzer.js b/app/static/js/path-analyzer.js index c8f1212..33efe97 100644 --- a/app/static/js/path-analyzer.js +++ b/app/static/js/path-analyzer.js @@ -688,6 +688,18 @@ function paBuildLegend(echo) { return legend; } +// Default echo selection: the routed echo with the fewest hops +// (ties -> first in arrival order) +function paShortestEchoIdx(msg) { + let best = null; + msg.echoView.forEach((echo, idx) => { + if (echo.hops > 0 && (best === null || echo.hops < msg.echoView[best].hops)) { + best = idx; + } + }); + return best; +} + function paRenderMapView() { paInitMap(); paPlotBaseMarkers(); @@ -715,13 +727,21 @@ function paRenderMapView() { const head = document.createElement('div'); head.className = 'd-flex justify-content-between gap-2'; + const left = document.createElement('div'); + left.className = 'd-flex align-items-baseline gap-1'; + left.style.minWidth = '0'; const senderEl = document.createElement('strong'); senderEl.className = 'text-truncate'; senderEl.textContent = msg.sender || '—'; + const chanEl = document.createElement('span'); + chanEl.className = 'pa-map-msg-chan'; + chanEl.textContent = msg.channel_name || `#${msg.channel_idx}`; + left.appendChild(senderEl); + left.appendChild(chanEl); const timeEl = document.createElement('span'); timeEl.className = 'text-muted text-nowrap'; timeEl.textContent = paFormatTime(msg).slice(5, 16); - head.appendChild(senderEl); + head.appendChild(left); head.appendChild(timeEl); entry.appendChild(head); @@ -735,7 +755,9 @@ function paRenderMapView() { } entry.addEventListener('click', () => { - paMapSelection = { msgId: msg.id, echoIdx: null }; + // Re-clicking the selected message keeps the user's echo choice + if (paMapSelection.msgId === msg.id) return; + paMapSelection = { msgId: msg.id, echoIdx: paShortestEchoIdx(msg) }; paRenderMapView(); }); diff --git a/app/templates/path-analyzer.html b/app/templates/path-analyzer.html index 0af29d5..06fde7c 100644 --- a/app/templates/path-analyzer.html +++ b/app/templates/path-analyzer.html @@ -125,11 +125,19 @@ flex-direction: column; } + /* Message/path list gets the remaining space, the map keeps a + fixed ~45% of the viewport height */ #paMapSidebar { width: auto; min-width: 0; - max-height: 40%; - flex-shrink: 1; + max-height: none; + flex: 1 1 0; + min-height: 0; + } + + #paMap { + flex: 0 0 45vh; + min-height: 0; } } @@ -364,6 +372,12 @@ color: #6f42c1; } + .pa-map-msg-chan { + font-size: 0.72rem; + color: var(--text-secondary, #6c757d); + white-space: nowrap; + } + .pa-map-msg-preview { font-size: 0.75rem; color: var(--text-secondary, #6c757d);