Atlas cards now use the Signal tab StatCard tiles, shared Card, badges,
action buttons, IATA chips and search bar. Polling moves to TanStack Query
with the app retry policy, pauses while rate-limited, and recovers a pin
whose server ID changed by its full public key. Search results show a key
prefix and explain short or non-hex input; heard-by states which packet it
counts. Sparkline component removed in favour of the stats one.
Lands the stacked web PRs #75, #79, #80, #81, #83, #85, #87, #89, #92, #95 and #99 in one squash. Server counterparts #166-#176 are merged. Remaining review items follow in a fix PR.
Airtime telemetry is on-air seconds, so chart it as a percent of elapsed time.
Add channel busy, packets heard, SNR heard and payload type charts from the
new per-observer activity endpoint; hidden until the server has it.
Draw each active IATA's GeoJSON region border as an outline over a faint
fill beneath the node markers, behind a Map Settings toggle that's off by
default and shareable via a URL param. IATAs with no border answer 204
and are skipped.
List repeaters and room servers whose advert-derived clock has drifted
past the server threshold, worst first, in a sortable table. It's each
node's latest reading, so there's no time range to pick.
- Discover packets decoded: DISCOVER_REQ/DISCOVER_RESP render real fields
(type-filter roles, tag, node-to-node request SNR) instead of a raw dump.
- Neighbor lines on the map: On/Selected/Off control draws links between nodes
and their known neighbors.
- Live packet flow: a play button animates packets hop-to-hop between repeaters
in real time (off by default).
* stats: node-types donut, multi-IATA filtering, preset split
- node-types: new /stats/node-types endpoint + useNodeTypes; donutOption
replaces the "Coming soon" card with a live donut
- stats endpoints take iatas[] instead of a single iata, so multi-IATA
regions filter instead of falling back to all (drops useStatsIata)
- radio presets keep the node/observer split via stacked presetBarsOption
- drop client-side telemetry ms-normalization (backend now emits epoch ms
on both paths); charts pick delta-vs-raw counters off the response interval
- MeshTab: range-driven charts lead, all-time charts follow; KPI window
from overview.windowHours instead of a hardcoded 24h
- ci: docker-publish builds a :dev image on dev-branch pushes
* feat: traces vs pings
feat: SNR for trace path in list
feat: known niehgbour count
* fix: github workflow, post images publically
- node-types: new /stats/node-types endpoint + useNodeTypes; donutOption
replaces the "Coming soon" card with a live donut
- stats endpoints take iatas[] instead of a single iata, so multi-IATA
regions filter instead of falling back to all (drops useStatsIata)
- radio presets keep the node/observer split via stacked presetBarsOption
- drop client-side telemetry ms-normalization (backend now emits epoch ms
on both paths); charts pick delta-vs-raw counters off the response interval
- MeshTab: range-driven charts lead, all-time charts follow; KPI window
from overview.windowHours instead of a hardcoded 24h
- ci: docker-publish builds a :dev image on dev-branch pushes
/channels ignores the plural iatas param, so the sidebar was always
global no matter the region — and opening another region's channel
showed an empty panel because the messages endpoint IS region-filtered.
Single-IATA regions filter properly now; multi-IATA stays global until
the backend grows parseIATAs there (ticket).
The big one: updateSubscription before the previous subscribe was acked
never unsubscribed it (the server keeps scopes additively), so a region
change right after connect left the old all-regions sub alive and the
live feed stayed a firehose. Subscribes now carry a tracked id and an
ack for a superseded subscribe is unsubscribed on arrival.
Also:
- doConnect/disconnect tear down the old socket and detach handlers, so
a late close from a dead socket can't spawn a parallel reconnect loop
(the StrictMode dev warning came from this)
- subscription ids are cleared per-connection instead of leaking a
stale id onto the next socket
- pings now double as a liveness check: no pong for two intervals
forces a reconnect instead of showing LIVE on a half-open link
- a server-sent close 1000 reconnects instead of going permanently dark
- after a reconnect the manager synthesizes a lag notice so live views
refetch what they missed during the outage
* feat: replace getScopeStats with getScopes and update related tests
bug: lastSeen/sentAt was set to string instead of number by mistake
* feat: update timestamp handling and formatting across components
- WS messages carry epoch ms now instead of ISO strings
- new Timestamp component (relative/absolute), used in RouteTable and RouteDetailPanel
- IataChip and ScopeTag chips
- TraceDetailPanel and TraceList for trace drill-down
- tests updated for the timestamp change
- LoadingPill shows loading/error state in MapView, NodeTable and ObserverTable
- new useInfinitePages hook shares the pagination logic between them
- patchNodeSummary/patchObserverSummary now keep references stable
- tests for loading states, observer updates and infinite paging