From 09dcae274f96dab2406f2b5e2016d802ffd05c1b Mon Sep 17 00:00:00 2001 From: you Date: Mon, 23 Mar 2026 16:46:24 +0000 Subject: [PATCH] feat: variable hash size badge links to detail page, shows per-advert hash sizes - Badge is now a link to the detail page with ?highlight=hashsize - Detail page auto-scrolls to Recent Packets section - Each advert shows its hash size badge (yellow if different from current) - Detail page shows always-visible explanation banner (not hidden) - Side pane badge links to detail page too --- public/nodes.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/public/nodes.js b/public/nodes.js index 07dfb54..e325dfc 100644 --- a/public/nodes.js +++ b/public/nodes.js @@ -119,8 +119,8 @@ body.innerHTML = `
${escapeHtml(n.name || '(unnamed)')}
-
${n.role} ${n.hash_size ? `${n.public_key.slice(0, n.hash_size * 2).toUpperCase()}` : ''} ${n.hash_size_inconsistent ? `⚠️ variable hash size` : ''} ${statusLabel}
- ${n.hash_size_inconsistent ? `` : ''} +
${n.role} ${n.hash_size ? `${n.public_key.slice(0, n.hash_size * 2).toUpperCase()}` : ''} ${n.hash_size_inconsistent ? `⚠️ variable hash size` : ''} ${statusLabel}
+ ${n.hash_size_inconsistent ? `
Adverts show varying hash sizes (${(n.hash_sizes_seen||[]).join('-byte, ')}-byte). Likely a firmware bug — update to MeshCore 1.14.1+. See advert details below.
` : ''}
${n.public_key}
@@ -180,9 +180,17 @@ const snr = p.snr != null ? ` · SNR ${p.snr}dB` : ''; const rssi = p.rssi != null ? ` · RSSI ${p.rssi}dBm` : ''; const obsBadge = p.observation_count > 1 ? ` 👁 ${p.observation_count}` : ''; + // Show hash size per advert if inconsistent + let hashSizeBadge = ''; + if (n.hash_size_inconsistent && p.payload_type === 4 && p.raw_hex) { + const pb = parseInt(p.raw_hex.slice(2, 4), 16); + const hs = ((pb >> 6) & 0x3) + 1; + const isDefault = hs === n.hash_size; + hashSizeBadge = ` ${hs}B`; + } return `
${timeAgo(p.timestamp)} - ${typeLabel}${detail}${obsBadge}${obs ? ' via ' + escapeHtml(obs) : ''}${snr}${rssi} + ${typeLabel}${detail}${hashSizeBadge}${obsBadge}${obs ? ' via ' + escapeHtml(obs) : ''}${snr}${rssi} Analyze →
`; }).join('') : '
No recent packets
'} @@ -210,6 +218,12 @@ }).catch(() => {}); }); + // Auto-scroll to adverts if highlight=hashsize + if (location.hash.includes('highlight=hashsize')) { + const recentSection = body.querySelector('.node-activity-list'); + if (recentSection) setTimeout(() => recentSection.scrollIntoView({ behavior: 'smooth', block: 'start' }), 300); + } + // QR code for full-screen view const qrFullEl = document.getElementById('nodeFullQrCode'); if (qrFullEl && typeof qrcode === 'function') { @@ -504,11 +518,10 @@ panel.innerHTML = `
${escapeHtml(n.name || '(unnamed)')}
-
${n.role} ${n.hash_size ? `${n.public_key.slice(0, n.hash_size * 2).toUpperCase()}` : ''} ${n.hash_size_inconsistent ? `⚠️ variable hash size` : ''} ${statusLabel} +
${n.role} ${n.hash_size ? `${n.public_key.slice(0, n.hash_size * 2).toUpperCase()}` : ''} ${n.hash_size_inconsistent ? `⚠️ variable hash size` : ''} ${statusLabel} 🔍 Details 📊 Analytics
- ${n.hash_size_inconsistent ? `` : ''} ${hasLoc ? `