diff --git a/public/analytics.js b/public/analytics.js index 2c0af5c3..64bfc19e 100644 --- a/public/analytics.js +++ b/public/analytics.js @@ -811,7 +811,7 @@ }).join(' '); const stripe = i % 2 === 1 ? 'background:var(--row-stripe)' : ''; return ` - ${esc(n.name || n.public_key.slice(0, 12))} + ${esc(n.name || n.public_key.slice(0, 12))} ${n.role} ${prefix} (${n.hash_size || '?'}B) ${sizeBadges} diff --git a/public/nodes.js b/public/nodes.js index 512d8629..39e83fb4 100644 --- a/public/nodes.js +++ b/public/nodes.js @@ -119,7 +119,7 @@ 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.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). This is a known bug where automatic adverts ignore the configured multibyte path setting. Fixed in repeater v1.14.1.
` : ''}
${n.public_key}
@@ -136,7 +136,7 @@
- +
@@ -147,7 +147,7 @@
Last Heard${lastHeard ? timeAgo(lastHeard) : (n.last_seen ? timeAgo(n.last_seen) : '—')}
First Seen${n.first_seen ? new Date(n.first_seen).toLocaleString() : '—'}
Total Packets${stats.totalTransmissions || stats.totalPackets || n.advert_count || 0}${stats.totalObservations && stats.totalObservations !== (stats.totalTransmissions || stats.totalPackets) ? ' (seen ' + stats.totalObservations + '×)' : ''}
Hash Prefix${n.hash_size ? '' + n.public_key.slice(0, n.hash_size * 2).toUpperCase() + ' (' + n.hash_size + '-byte)' : 'Unknown'}${n.hash_size_inconsistent ? ' ⚠️ varies' : ''}
- ${observers.length ? `
+ ${observers.length ? `
${(() => { const regions = [...new Set(observers.map(o => o.iata).filter(Boolean))]; return regions.length ? `
Regions: ${regions.map(r => '' + escapeHtml(r) + '').join(' ')}
` : ''; })()}

Heard By (${observers.length} observer${observers.length > 1 ? 's' : ''})

@@ -169,7 +169,7 @@
Loading paths…
-
+

Recent Packets (${adverts.length})

${adverts.length ? adverts.map(p => { @@ -219,10 +219,13 @@ }).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); + // Deep-link scroll: ?section=node-packets or ?section=node-packets + const hashParams = location.hash.split('?')[1] || ''; + const urlParams = new URLSearchParams(hashParams); + const scrollTarget = urlParams.get('section') || (urlParams.has('highlight') ? 'node-packets' : null); + if (scrollTarget) { + const targetEl = document.getElementById(scrollTarget); + if (targetEl) setTimeout(() => targetEl.scrollIntoView({ behavior: 'smooth', block: 'start' }), 300); } // QR code for full-screen view @@ -519,7 +522,7 @@ 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