From 03ca33143bb49e1c1e2376caade5f0bf8bef77d8 Mon Sep 17 00:00:00 2001 From: pablorevilla-meshtastic Date: Mon, 26 Oct 2026 09:45:28 -0700 Subject: [PATCH] move visual changes --- meshview/static/map-inspector.js | 11 +++++++++++ meshview/static/packet-arrival.js | 12 ++++++++++++ meshview/templates/base.html | 18 ++++++++++++++++++ meshview/templates/firehose.html | 5 +++++ meshview/templates/map-view.html | 1 - 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 meshview/static/packet-arrival.js diff --git a/meshview/static/map-inspector.js b/meshview/static/map-inspector.js index d27fbc8..899260d 100644 --- a/meshview/static/map-inspector.js +++ b/meshview/static/map-inspector.js @@ -3,6 +3,9 @@ const byId = id => document.getElementById(id); const packetHistory = new Map(); const expandedPackets = new Set(); + const displayedPackets = new Set(); + const packetArrivals = new Map(); + let trafficLoaded = false; let nodeRequest = null; let inspectedNodeId = null; let recentPackets = []; @@ -220,6 +223,11 @@ toggle.setAttribute('aria-expanded',String(!payloadRow.hidden)); toggle.textContent = payloadRow.hidden ? '▶' : '▼'; }); body.append(row,payloadRow); + if (!displayedPackets.has(id)) { + displayedPackets.add(id); + packetArrivals.set(id,Date.now()); + } + if (packetArrivals.has(id)) markNewPacketArrival(row,packetArrivals.get(id)); } list.scrollTop = scrollTop; if (focusedId && focusedControl) { @@ -243,6 +251,7 @@ for (const packet of event.detail) { if (!packetHistory.has(String(packetId(packet)))) added = true; packetHistory.set(String(packetId(packet)),packet); + if (!trafficLoaded) displayedPackets.add(String(packetId(packet))); if (packet.channel && ![...byId('map-traffic-channel').options].some(o => o.value === packet.channel)) { byId('map-traffic-channel').add(new Option(packet.channel,packet.channel)); } @@ -253,10 +262,12 @@ if (String(packet.from_node_id) === inspectedNodeId && Number(packet.portnum) === 67) renderTelemetry(packet); } } + trafficLoaded = true; if (packetHistory.size > 30) { const sorted = [...packetHistory.values()].sort((a,b) => packetTime(b)-packetTime(a)); for (const packet of sorted.slice(30)) { packetHistory.delete(String(packetId(packet))); expandedPackets.delete(String(packetId(packet))); + displayedPackets.delete(String(packetId(packet))); packetArrivals.delete(String(packetId(packet))); } } if (!paused && added) renderTraffic(); diff --git a/meshview/static/packet-arrival.js b/meshview/static/packet-arrival.js new file mode 100644 index 0000000..76d93b1 --- /dev/null +++ b/meshview/static/packet-arrival.js @@ -0,0 +1,12 @@ +/* A short, shared arrival cue for the two live packet tables. */ +window.markNewPacketArrival = function (row, startedAt = Date.now()) { + const elapsed = Math.max(0, Date.now() - startedAt); + const remaining = 1000 - elapsed; + if (remaining <= 0) return; + row.classList.add('packet-arrival-glow'); + row.style.setProperty('--packet-glow-delay', `${-elapsed}ms`); + setTimeout(() => { + row.classList.remove('packet-arrival-glow'); + row.style.removeProperty('--packet-glow-delay'); + }, remaining); +}; diff --git a/meshview/templates/base.html b/meshview/templates/base.html index 99c1570..23ce482 100644 --- a/meshview/templates/base.html +++ b/meshview/templates/base.html @@ -15,6 +15,7 @@ + {% block head %}{% endblock %} @@ -90,6 +91,23 @@ input[type="checkbox"],input[type="radio"] { accent-color:var(--mesh-primary); } .form-check-input:focus { border-color:#91bda1; box-shadow:0 0 0 .25rem rgba(var(--mesh-primary-rgb),.2); } .page-link { --bs-pagination-color:var(--mesh-primary); --bs-pagination-hover-color:var(--mesh-primary-dark); --bs-pagination-active-bg:var(--mesh-primary); --bs-pagination-active-border-color:var(--mesh-primary); } [data-bs-theme="light"] body { background:var(--mesh-page); color:#243247; font-family:Inter,system-ui,-apple-system,"Segoe UI",sans-serif; } +/* Tint whole cells: an edge-only shadow is too subtle on wide packet tables. */ +.packet-arrival-glow > td { + animation:packet-arrival-beat 1s ease-in-out 1; + animation-delay:var(--packet-glow-delay,0ms); + box-shadow:inset 0 0 14px rgba(24,115,70,.12); +} +.packet-arrival-glow > td:first-child { + box-shadow:inset 4px 0 0 var(--mesh-primary),inset 0 0 14px rgba(24,115,70,.12); +} +@keyframes packet-arrival-beat { + 0%,100% { background-color:transparent; } + 45% { background-color:#ccebd7; } + 75% { background-color:#e2f3e8; } +} +@media(prefers-reduced-motion:reduce) { + .packet-arrival-glow > td { animation:none; background:#d8efdf; } +} .mesh-header { background:var(--mesh-primary); color:white; box-shadow:0 2px 8px #174b2d18; } .mesh-header-inner { max-width:1600px; margin:auto; padding:0 28px; min-height:56px; display:flex; align-items:center; gap:32px; } .mesh-brand { display:flex; align-items:center; gap:10px; font-size:19px; font-weight:700; color:white; text-decoration:none; flex-shrink:0; } diff --git a/meshview/templates/firehose.html b/meshview/templates/firehose.html index 5384229..30aa2a7 100644 --- a/meshview/templates/firehose.html +++ b/meshview/templates/firehose.html @@ -174,6 +174,7 @@ function logPacketTimes(packet) { FIREHOSE FETCHING ====================================================== */ let lastImportTimeUs = null; +let firehoseLoaded = false; let updatesPaused = false; let updateInterval = 3000; let selectedChannel = ""; @@ -207,6 +208,7 @@ async function loadChannels() { } function resetFirehose() { + firehoseLoaded = false; lastImportTimeUs = null; document.getElementById("packet_list").innerHTML = ""; } @@ -231,6 +233,8 @@ async function fetchUpdates() { const data = await res.json(); const packets = data.packets || []; + const highlightNewPackets = firehoseLoaded; + firehoseLoaded = true; if (!packets.length) return; const list = document.getElementById("packet_list"); @@ -326,6 +330,7 @@ async function fetchUpdates() { `; list.insertAdjacentHTML("afterbegin", html); + if (highlightNewPackets) markNewPacketArrival(list.firstElementChild); } // Limit table size diff --git a/meshview/templates/map-view.html b/meshview/templates/map-view.html index 65607bd..3481512 100644 --- a/meshview/templates/map-view.html +++ b/meshview/templates/map-view.html @@ -157,7 +157,6 @@ .mesh-traffic-table th { position:sticky; top:0; z-index:1; padding:12px 14px; background:var(--mesh-primary); color:white; font-weight:500; font-size:12px; white-space:nowrap; text-align:left; } .mesh-traffic-table td { padding:11px 14px; border-bottom:1px solid #edf1f6; text-align:left; } .mesh-traffic-row { background:white; } -.mesh-traffic-row:nth-of-type(4n+3) { background:var(--mesh-stripe); } .mesh-traffic-row:hover { background:var(--mesh-soft); } .mesh-traffic-table a { color:var(--mesh-primary); text-decoration:none; } .mesh-traffic-table a:hover { text-decoration:underline; }