From 91e6f0eb08e4f9f0f040777ce01ac163b788f26f Mon Sep 17 00:00:00 2001 From: you Date: Sun, 22 Mar 2026 23:00:09 +0000 Subject: [PATCH] Packet detail: resolve location for channel texts + all node types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For packets without direct lat/lon (GRP_TXT, TXT_MSG): - Look up sender by pubKey via /api/nodes/:key - Look up sender by name via /api/nodes/search?q=name - Show location + 📍map link when node has coordinates Works for decrypted channel messages (sender field), direct messages (srcPubKey), and any packet type with a resolvable sender. --- public/index.html | 2 +- public/packets.js | 44 +++++++++++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/public/index.html b/public/index.html index c4b200d..58f49a0 100644 --- a/public/index.html +++ b/public/index.html @@ -85,7 +85,7 @@ - + diff --git a/public/packets.js b/public/packets.js index b08c266..b77769b 100644 --- a/public/packets.js +++ b/public/packets.js @@ -282,7 +282,7 @@ const newHops = hops.filter(h => !(h in hopNameCache)); if (newHops.length) await resolveHops(newHops); } catch {} - renderDetail(content, data); + await renderDetail(content, data); initPanelResize(); } } catch {} @@ -1113,14 +1113,14 @@ panel.innerHTML = isMobileNow ? '' : '
'; const content = document.createElement('div'); panel.appendChild(content); - renderDetail(content, data); + await renderDetail(content, data); if (!isMobileNow) initPanelResize(); } catch (e) { panel.innerHTML = `
Error: ${e.message}
`; } } - function renderDetail(panel, data) { + async function renderDetail(panel, data) { const pkt = data.packet; const breakdown = data.breakdown || {}; const ranges = breakdown.ranges || []; @@ -1176,18 +1176,40 @@ } } - // Location: from ADVERT lat/lon, or from known node + // Location: from ADVERT lat/lon, or from known node via pubkey/sender name let locationHtml = '—'; + let locationNodeKey = null; if (decoded.lat != null && decoded.lon != null && !(decoded.lat === 0 && decoded.lon === 0)) { - const nodeKey = decoded.pubKey || decoded.srcPubKey || ''; + locationNodeKey = decoded.pubKey || decoded.srcPubKey || ''; const nodeName = decoded.name || ''; locationHtml = `${decoded.lat.toFixed(5)}, ${decoded.lon.toFixed(5)}`; if (nodeName) locationHtml = `${escapeHtml(nodeName)} — ${locationHtml}`; - if (nodeKey) locationHtml += ` 📍map`; - } else if (decoded.srcPubKey || decoded.pubKey) { - // Try to look up sender node location from HopResolver's node list - const senderKey = decoded.srcPubKey || decoded.pubKey; - const senderNode = (window.HopResolver && HopResolver.ready()) ? null : null; // could look up but keep simple + if (locationNodeKey) locationHtml += ` 📍map`; + } else { + // Try to resolve sender node location from nodes list + const senderKey = decoded.pubKey || decoded.srcPubKey; + const senderName = decoded.sender || decoded.name; + if (senderKey || senderName) { + try { + const nodeData = senderKey ? await api(`/nodes/${senderKey}`, { ttl: 30000 }).catch(() => null) : null; + if (nodeData && nodeData.node && nodeData.node.lat && nodeData.node.lon) { + locationNodeKey = nodeData.node.public_key; + locationHtml = `${nodeData.node.lat.toFixed(5)}, ${nodeData.node.lon.toFixed(5)}`; + if (nodeData.node.name) locationHtml = `${escapeHtml(nodeData.node.name)} — ${locationHtml}`; + locationHtml += ` 📍map`; + } else if (senderName && !senderKey) { + // Search by name + const searchData = await api(`/nodes/search?q=${encodeURIComponent(senderName)}`, { ttl: 30000 }).catch(() => null); + const match = searchData && searchData.nodes && searchData.nodes[0]; + if (match && match.lat && match.lon) { + locationNodeKey = match.public_key; + locationHtml = `${match.lat.toFixed(5)}, ${match.lon.toFixed(5)}`; + locationHtml = `${escapeHtml(match.name)} — ${locationHtml}`; + locationHtml += ` 📍map`; + } + } + } catch {} + } } panel.innerHTML = ` @@ -1670,7 +1692,7 @@ container.innerHTML = `
← Back to packets
`; const detail = document.createElement('div'); container.appendChild(detail); - renderDetail(detail, data); + await renderDetail(detail, data); app.innerHTML = ''; app.appendChild(container); } catch (e) {