* 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
* build(deps): bump undici from 7.27.2 to 7.28.0 (#9)
Bumps [undici](https://github.com/nodejs/undici) from 7.27.2 to 7.28.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v7.27.2...v7.28.0)
---
updated-dependencies:
- dependency-name: undici
dependency-version: 7.28.0
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* feat: discover renderers, neighbor map lines, live packet flow
- 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).
* map: live mode dims nodes, flashes each packet's route
* map: shoot a comet along each packet's route in live mode
* map: rework live mode — packet dot, dashed trail, per-hop flash
* map: fade live-mode clusters more so dense ones stay see-through
* map: persist clustering + node-type, default neighbor lines to selected
* map: fade live-mode node markers more so overlaps stay see-through
* map: fade the live-mode node flash in sync with its packet trail
* nodes: let the mobile detail panel minimize without deselecting
* map: dim other nodes to spotlight a selected node and its neighbours
* map: colour a selected node's neighbour lines by obs count and freshness
* Add a neighbour graph under the renamed Analytics tab
* Focus the neighbour graph into an ego view on click
* Wrap the analytics sub-header so the range stays on-screen on mobile
* Use a dropdown for the analytics sections on mobile
* Gate the neighbour graph to a region and size labels by busyness
* Add a name search that spotlights matches and dims the rest of the mesh
* Add a copy button beside node and observer public keys
* Add a copy link to node and observer detail panels
Deep-linked ?node/?observer selections now survive load: the region
reset watches the raw selection instead of the async-resolved regionKey,
so slug expansion no longer wipes a restored panel.
* Add .env options for hiding tabs, MeshMapper themes, app name and a GitHub link
* Make VITE_ENABLED_THEMES an exclusive theme allowlist
* Add a .env option to skip the load splash
* Keep the packets list static while scrolled down instead of jumping on new packets
* Add Map deep-links for camera and settings with a copy-link button
* Filter packet history on the server when a single type, route or scope is selected
* Show loading feedback while packet history loads
* build(deps): bump echarts from 5.5.1 to 6.1.0 (#14)
* Fix: github workflow + stats tab + add traces vs pings (#10)
* 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
* build(deps): bump echarts from 5.5.1 to 6.1.0
Bumps [echarts](https://github.com/apache/echarts) from 5.5.1 to 6.1.0.
- [Release notes](https://github.com/apache/echarts/releases)
- [Commits](https://github.com/apache/echarts/compare/5.5.1...6.1.0)
---
updated-dependencies:
- dependency-name: echarts
dependency-version: 6.1.0
dependency-type: direct:production
...
Signed-off-by: dependabot[bot] <support@github.com>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: MrAlders0n <55921894+MrAlders0n@users.noreply.github.com>
Co-authored-by: MrAlders0n <55921894+MrAlders0n@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Bump version to 1.2.0
---------
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: MrAlders0n <55921894+MrAlders0n@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Fix: github workflow + stats tab + add traces vs pings (#10)
* 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
* build(deps): bump echarts from 5.5.1 to 6.1.0
Bumps [echarts](https://github.com/apache/echarts) from 5.5.1 to 6.1.0.
- [Release notes](https://github.com/apache/echarts/releases)
- [Commits](https://github.com/apache/echarts/compare/5.5.1...6.1.0)
---
updated-dependencies:
- dependency-name: echarts
dependency-version: 6.1.0
dependency-type: direct:production
...
Signed-off-by: dependabot[bot] <support@github.com>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: MrAlders0n <55921894+MrAlders0n@users.noreply.github.com>
Co-authored-by: MrAlders0n <55921894+MrAlders0n@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Deep-linked ?node/?observer selections now survive load: the region
reset watches the raw selection instead of the async-resolved regionKey,
so slug expansion no longer wipes a restored panel.
- 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
The donut counted types among the top-10 nodes only, so the center
read '10 NODES' as if the region had ten nodes, and its center text
never sat quite right (ECharts titles anchor the main text, the
subtext hangs below). There's no /stats/node-types endpoint to feed it
properly yet (ticket filed), so the card shows 'Coming soon' and the
donut builder goes away rather than lingering as dead code.
textAlign/textVerticalAlign make left/top the anchor point, so the
value+label block centers on (35%, 50%) geometrically instead of the
hand-tuned top offset that drifted with card size.
- a failed lazy chunk now offers 'reload' (React.lazy caches the
rejection, so remounting could never recover Map/Stats)
- an open spiderfy fan closes on region/type-filter change instead of
showing leaves from the previous dataset
- map settings persistence moved out of the setState updater
- observer search debounces 250ms and shows 'Search failed' instead of
'No matches' on errors
- packet-detail staleTime drops to 30s so a reopened analyzer picks up
new observations
- leaving Stats clears its statsTab/observerId/range URL params
- ws types now match the wire (batteryMv omitted not null, scopes can
be null, lastObservationId isn't sent today); drop the unused
microToDeg shim now that nothing imports it
- fresh-row highlights leaked under a steady stream (each new batch
cancelled the previous batch's clear timer); per-batch timers in a
small useFreshHashes hook now
- closing the analyzer drops ?hash and the row selection, so the same
row reopens on the next click and a closed analyzer stays closed
after reload/share
- sf=path / sf=payload from the URL fall back to hash search (only
field matchesFilters implements; the UI options were already disabled)
- remove the summary preview line no backend path ever populates
- channel message rows key on packetHash (live WS messages carry no id)
- footer read 'v0.1' forever; it's injected from package.json at build
time now
- region picker shows 'Failed to load' instead of an eternal Loading
when /iatas errors
- selecting text in a modal and releasing over the backdrop no longer
closes it (close requires the press to start on the backdrop)
- Escape in a dropdown inside the mobile filter sheet closes just the
dropdown, not the whole sheet
- Shift+Tab right after a modal opens wraps to the last control instead
of escaping the focus trap
- formatCount rolls 999,999 over to 1M instead of printing 1000k
- TABS list moved to lib/constants so AppShell only exports components
/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 WS observerStatus event never says offline (the backend only
derives it at REST read time, 5-minute window) and the list never
refetches, so badges stayed green all session once an observer went
quiet. Status is now re-derived on a tick from lastStatusAt — the WS
patch keeps the timestamp fresh — using the same 5-minute rule as the
server.
A multi-IATA region filters globally-paged rows client-side, and scroll
was the only trigger for the next page — an empty or too-short filtered
list could never fire it, so routes deeper in the cursor stream were
unreachable ('No routes' with routes that exist). Pull pages until the
region has a screenful or the cap calls it sparse.
The donut suits node types after all — few slices, and the total reads
better in the ring than on three bars. The center text is a title block
with textAlign center now, which ECharts actually centers (the old
graphic text anchored its left edge at the ring's x and clipped);
TitleComponent registered in the tree-shaken setup. Payload types stays
a bar chart.
Leaderboard names (top nodes/observers, radio presets) are left-aligned
at the card edge and ellipsized instead of running off the grid's left
side.
The WS patch only updated nodes already in the paged cache, and with
staleTime Infinity nothing ever refetched — a node that came up after
page load could never appear on the map. The event carries a full
summary, so unknown nodes are appended to the cache directly. The
Nodes table keeps patch-only behavior since its cache is filter-scoped.
microToDeg guessed microdegrees from integer values, but api/nodes.go
has always sent *float64 degrees — so a node sitting at an exact whole
degree got divided by 1e6 and rendered at the equator. Drop the shim
from the geojson builder, the nodes table and the detail panel, and fix
the ws.ts comment that repeated the wrong premise.
Also key neighbor rows by id+iata: the neighbors endpoint returns one
row per (neighbor, iata), so id alone collides for nodes heard in
several regions (live React duplicate-key error).