fix: 4 bugs - spark bars inline style, My Nodes filter field names, duplicate pin button, map dark mode

1. Spark bars: inline style override on td (max-width:none, min-width:80px)
2. My Nodes filter: pubkey→pubKey, to/from→srcPubKey/destPubKey/srcHash/destHash
3. Pin button: guard against duplicates in init, remove in destroy
4. Map page: CartoDB dark/light tiles with MutationObserver theme swap
This commit is contained in:
you
2026-03-20 09:21:17 +00:00
parent 116f0c8dfb
commit db884f12eb
6 changed files with 29 additions and 16 deletions

View File

@@ -36,8 +36,7 @@
"SJC": "San Jose, US",
"SFO": "San Francisco, US",
"OAK": "Oakland, US",
"MRY": "Monterey, US",
"LAR": "Los Angeles, US"
"MRY": "Monterey, US"
},
"cacheTTL": {
"stats": 10,

View File

@@ -22,7 +22,7 @@
<meta name="twitter:title" content="MeshCore Analyzer">
<meta name="twitter:description" content="Real-time MeshCore LoRa mesh network analyzer — live packet visualization, node tracking, channel decryption, and route analysis.">
<meta name="twitter:image" content="https://raw.githubusercontent.com/Kpa-clawbot/meshcore-analyzer/master/public/og-image.png">
<link rel="stylesheet" href="style.css?v=1773998059">
<link rel="stylesheet" href="style.css?v=1773998477">
<link rel="stylesheet" href="home.css">
<link rel="stylesheet" href="live.css?v=1773966856">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
@@ -81,14 +81,14 @@
<script src="vendor/qrcode.js"></script>
<script src="app.js?v=1773993532"></script>
<script src="home.js?v=1773977027"></script>
<script src="packets.js?v=1773993532"></script>
<script src="map.js?v=1773977027" onerror="console.error('Failed to load:', this.src)"></script>
<script src="packets.js?v=1773998477"></script>
<script src="map.js?v=1773998477" onerror="console.error('Failed to load:', this.src)"></script>
<script src="channels.js?v=1773977027" onerror="console.error('Failed to load:', this.src)"></script>
<script src="nodes.js?v=1773977027" onerror="console.error('Failed to load:', this.src)"></script>
<script src="traces.js?v=1773972187" onerror="console.error('Failed to load:', this.src)"></script>
<script src="analytics.js?v=1773996158" onerror="console.error('Failed to load:', this.src)"></script>
<script src="live.js?v=1773964458" onerror="console.error('Failed to load:', this.src)"></script>
<script src="observers.js?v=1773998059" onerror="console.error('Failed to load:', this.src)"></script>
<script src="live.js?v=1773998477" onerror="console.error('Failed to load:', this.src)"></script>
<script src="observers.js?v=1773998477" onerror="console.error('Failed to load:', this.src)"></script>
<script src="observer-detail.js?v=1773993532" onerror="console.error('Failed to load:', this.src)"></script>
<script src="node-analytics.js?v=1773996158" onerror="console.error('Failed to load:', this.src)"></script>
<script src="perf.js?v=1773985649" onerror="console.error('Failed to load:', this.src)"></script>

View File

@@ -908,8 +908,8 @@
const topNav = document.querySelector('.top-nav');
if (topNav) { topNav.style.position = 'fixed'; topNav.style.width = '100%'; topNav.style.zIndex = '1100'; }
_navCleanup = { timeout: null, fn: null, pinned: false };
// Add pin button to nav
if (topNav) {
// Add pin button to nav (guard against duplicate)
if (topNav && !document.getElementById('navPinBtn')) {
const pinBtn = document.createElement('button');
pinBtn.id = 'navPinBtn';
pinBtn.className = 'nav-pin-btn';
@@ -1466,6 +1466,8 @@
if (appEl) appEl.style.height = '';
const topNav = document.querySelector('.top-nav');
if (topNav) { topNav.classList.remove('nav-autohide'); topNav.style.position = ''; topNav.style.width = ''; topNav.style.zIndex = ''; }
const existingPin = document.getElementById('navPinBtn');
if (existingPin) existingPin.remove();
if (_navCleanup) {
clearTimeout(_navCleanup.timeout);
const livePage = document.querySelector('.live-page');

View File

@@ -105,10 +105,21 @@
try { const v = JSON.parse(savedView); initCenter = [v.lat, v.lng]; initZoom = v.zoom; } catch {}
}
map = L.map('leaflet-map', { zoomControl: true }).setView(initCenter, initZoom);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap',
const DARK_TILES = 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png';
const LIGHT_TILES = 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png';
const isDark = document.documentElement.getAttribute('data-theme') === 'dark' ||
(document.documentElement.getAttribute('data-theme') !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches);
const tileLayer = L.tileLayer(isDark ? DARK_TILES : LIGHT_TILES, {
attribution: '© OpenStreetMap © CartoDB',
maxZoom: 19,
}).addTo(map);
const _mapThemeObs = new MutationObserver(function () {
const dark = document.documentElement.getAttribute('data-theme') === 'dark' ||
(document.documentElement.getAttribute('data-theme') !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches);
tileLayer.setUrl(dark ? DARK_TILES : LIGHT_TILES);
});
_mapThemeObs.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
// Save position on move
map.on('moveend', () => {

View File

@@ -113,7 +113,7 @@
<td>${o.iata ? `<span class="badge-region">${o.iata}</span>` : '—'}</td>
<td>${timeAgo(o.last_seen)}</td>
<td>${(o.packet_count || 0).toLocaleString()}</td>
<td class="col-spark">${sparkBar(o.packetsLastHour || 0, maxPktsHr)}</td>
<td class="col-spark" style="max-width:none;overflow:visible;min-width:80px">${sparkBar(o.packetsLastHour || 0, maxPktsHr)}</td>
<td>${uptimeStr(o.first_seen)}</td>
</tr>`;
}).join('')}</tbody>

View File

@@ -598,10 +598,11 @@
try {
const d = JSON.parse(p.decoded_json || '{}');
const pathHops = JSON.parse(p.path_json || '[]');
// Check if any node key in decoded data or path matches
return (d.pubkey && allKeys.has(d.pubkey)) ||
(d.to && allKeys.has(d.to)) ||
(d.from && allKeys.has(d.from)) ||
return (d.pubKey && allKeys.has(d.pubKey)) ||
(d.srcPubKey && allKeys.has(d.srcPubKey)) ||
(d.destPubKey && allKeys.has(d.destPubKey)) ||
(d.srcHash && allKeys.has(d.srcHash)) ||
(d.destHash && allKeys.has(d.destHash)) ||
pathHops.some(h => allKeys.has(h));
} catch { return false; }
});