From 039d1fc28fb8680a34384d01cecdc730aa51b54a Mon Sep 17 00:00:00 2001 From: you Date: Fri, 20 Mar 2026 07:51:26 +0000 Subject: [PATCH] fix: resolve observer names from observers table in packets view observer_name on packets is often NULL; now cross-references the loaded observers list to display friendly names --- public/packets.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/public/packets.js b/public/packets.js index 6461e4eb..4fc139e1 100644 --- a/public/packets.js +++ b/public/packets.js @@ -3,6 +3,13 @@ (function () { let packets = []; + + // Resolve observer_id to friendly name from loaded observers list + function obsName(id) { + if (!id) return '—'; + const o = observers.find(ob => ob.id === id); + return o?.name || id; + } let selectedId = null; let groupByHash = true; let filters = {}; @@ -624,7 +631,7 @@ ${truncate(p.hash || '—', 8)} ${groupSize ? groupSize + 'B' : '—'} ${p.payload_type != null ? `${groupTypeName}` : '—'} - ${isSingle ? truncate(p.observer_name || p.observer_id || '—', 16) : truncate(p.observer_name || p.observer_id || '—', 10) + (p.observer_count > 1 ? ' +' + (p.observer_count - 1) : '')} + ${isSingle ? truncate(obsName(p.observer_id), 16) : truncate(obsName(p.observer_id), 10) + (p.observer_count > 1 ? ' +' + (p.observer_count - 1) : '')} ${groupPathStr} ${isSingle ? '' : p.count} ${getDetailPreview((() => { try { return JSON.parse(p.decoded_json || '{}'); } catch { return {}; } })())} @@ -645,7 +652,7 @@ ${truncate(c.hash || '', 8)} ${size}B ${typeName} - ${truncate(c.observer_name || c.observer_id || '—', 16)} + ${truncate(obsName(c.observer_id), 16)} ${childPathStr} ${getDetailPreview((() => { try { return JSON.parse(c.decoded_json); } catch { return {}; } })())} @@ -675,7 +682,7 @@ ${truncate(p.hash || String(p.id), 8)} ${size}B ${typeName} - ${truncate(p.observer_name || p.observer_id || '—', 16)} + ${truncate(obsName(p.observer_id), 16)} ${pathStr} ${detail} @@ -795,7 +802,7 @@
${pkt.hash || 'Packet #' + pkt.id}
${messageHtml}
-
Observer
${pkt.observer_name || pkt.observer_id || '—'}
+
Observer
${obsName(pkt.observer_id)}
SNR / RSSI
${snr != null ? snr + ' dB' : '—'} / ${rssi != null ? rssi + ' dBm' : '—'}
Route Type
${routeTypeName(pkt.route_type)}
Payload Type
${typeName}
@@ -836,7 +843,7 @@ id: pkt.id, hash: pkt.hash, _ts: new Date(pkt.timestamp).getTime(), decoded: { header: { payloadTypeName: typeName }, payload: decoded, path: { hops: pathHops } }, - snr: pkt.snr, rssi: pkt.rssi, observer: pkt.observer_name + snr: pkt.snr, rssi: pkt.rssi, observer: obsName(pkt.observer_id) }; sessionStorage.setItem('replay-packet', JSON.stringify(livePkt)); window.location.hash = '#/live'; @@ -848,7 +855,7 @@ if (routeBtn && pathHops.length) { routeBtn.addEventListener('click', async () => { try { - const obsId = pkt.observer_name || pkt.observer_id || ''; + const obsId = obsName(pkt.observer_id); const observerParam = obsId ? '&observer=' + encodeURIComponent(obsId) : ''; const resp = await fetch('/api/resolve-hops?hops=' + encodeURIComponent(pathHops.join(',')) + observerParam); const data = await resp.json();