The mesh contacts/peer list in the UI updates on a 5-second poll (mesh.fetchPeers), even though the backend already emits real-time peer events. Wire the UI to those events so newly-discovered contacts appear instantly on push instead of waiting for the next poll tick.
Current behavior
Backend emits MeshEvent::PeerDiscovered (new) / MeshEvent::PeerUpdated (existing) the moment an advert frame is decoded — core/archipelago/src/mesh/listener/decode.rs:454-459.
refresh_contacts() also merges the firmware contact table on connect, on should_action frames, and every 60s — core/archipelago/src/mesh/listener/session.rs:428,466-468,494.
But neode-ui/src/views/Mesh.vue:328-334 ignores the event stream for the peer list and just polls mesh.peers every 5s via the store's fetchPeers() (neode-ui/src/stores/mesh.ts:168).
Net effect: data is fresh on the node within seconds, but the UI lags up to 5s and generates constant poll traffic.
Proposed change
Subscribe the mesh store / Mesh.vue to the existing mesh event stream and apply PeerDiscovered / PeerUpdated (and IdentityReceived) to peers.value incrementally.
Keep a slow reconcile poll (e.g. 30-60s) as a safety net, but drop the 5s peer poll once push is live.
Confirm an SSE/websocket bridge exists for MeshEvent; if not, add one (events are already broadcast on state.event_tx).
Acceptance
A node coming into range shows up in the contacts list within ~1s of its advert, with no manual refresh.
No 5s peer polling in normal operation.
Found while debugging a meshcore "stuck connecting" report (root cause there was unrelated: no radio attached / cable). Related: #42.
### Summary
The mesh contacts/peer list in the UI updates on a **5-second poll** (`mesh.fetchPeers`), even though the backend already emits real-time peer events. Wire the UI to those events so newly-discovered contacts appear **instantly on push** instead of waiting for the next poll tick.
### Current behavior
- Backend emits `MeshEvent::PeerDiscovered` (new) / `MeshEvent::PeerUpdated` (existing) the moment an advert frame is decoded — `core/archipelago/src/mesh/listener/decode.rs:454-459`.
- `refresh_contacts()` also merges the firmware contact table on connect, on `should_action` frames, and every 60s — `core/archipelago/src/mesh/listener/session.rs:428,466-468,494`.
- But `neode-ui/src/views/Mesh.vue:328-334` ignores the event stream for the peer list and just polls `mesh.peers` every 5s via the store's `fetchPeers()` (`neode-ui/src/stores/mesh.ts:168`).
Net effect: data is fresh on the node within seconds, but the UI lags up to 5s and generates constant poll traffic.
### Proposed change
- Subscribe the mesh store / `Mesh.vue` to the existing mesh event stream and apply `PeerDiscovered` / `PeerUpdated` (and `IdentityReceived`) to `peers.value` incrementally.
- Keep a slow reconcile poll (e.g. 30-60s) as a safety net, but drop the 5s peer poll once push is live.
- Confirm an SSE/websocket bridge exists for `MeshEvent`; if not, add one (events are already broadcast on `state.event_tx`).
### Acceptance
- A node coming into range shows up in the contacts list within ~1s of its advert, with no manual refresh.
- No 5s peer polling in normal operation.
_Found while debugging a meshcore "stuck connecting" report (root cause there was unrelated: no radio attached / cable). Related: #42._
Implemented: mesh peers now appear on push instead of the 5s poll. Backend (server.rs) subscribes to mesh event_tx and, on PeerDiscovered/PeerUpdated (debounced ~2Hz), nudges the data-model revision so /ws/db clients refresh. Frontend (Mesh.vue) subscribes to the WS and refetches peers on push; the 5s poll stays only as a backstop for offline detection (no PeerLost event). Both cargo check and vue-tsc green. Verify on a node with a radio (e.g. .116).
Implemented: mesh peers now appear on push instead of the 5s poll. Backend (`server.rs`) subscribes to mesh `event_tx` and, on `PeerDiscovered`/`PeerUpdated` (debounced ~2Hz), nudges the data-model revision so `/ws/db` clients refresh. Frontend (`Mesh.vue`) subscribes to the WS and refetches peers on push; the 5s poll stays only as a backstop for offline detection (no PeerLost event). Both `cargo check` and `vue-tsc` green. Verify on a node with a radio (e.g. .116).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
The mesh contacts/peer list in the UI updates on a 5-second poll (
mesh.fetchPeers), even though the backend already emits real-time peer events. Wire the UI to those events so newly-discovered contacts appear instantly on push instead of waiting for the next poll tick.Current behavior
MeshEvent::PeerDiscovered(new) /MeshEvent::PeerUpdated(existing) the moment an advert frame is decoded —core/archipelago/src/mesh/listener/decode.rs:454-459.refresh_contacts()also merges the firmware contact table on connect, onshould_actionframes, and every 60s —core/archipelago/src/mesh/listener/session.rs:428,466-468,494.neode-ui/src/views/Mesh.vue:328-334ignores the event stream for the peer list and just pollsmesh.peersevery 5s via the store'sfetchPeers()(neode-ui/src/stores/mesh.ts:168).Net effect: data is fresh on the node within seconds, but the UI lags up to 5s and generates constant poll traffic.
Proposed change
Mesh.vueto the existing mesh event stream and applyPeerDiscovered/PeerUpdated(andIdentityReceived) topeers.valueincrementally.MeshEvent; if not, add one (events are already broadcast onstate.event_tx).Acceptance
Found while debugging a meshcore "stuck connecting" report (root cause there was unrelated: no radio attached / cable). Related: #42.
Implemented: mesh peers now appear on push instead of the 5s poll. Backend (
server.rs) subscribes to meshevent_txand, onPeerDiscovered/PeerUpdated(debounced ~2Hz), nudges the data-model revision so/ws/dbclients refresh. Frontend (Mesh.vue) subscribes to the WS and refetches peers on push; the 5s poll stays only as a backstop for offline detection (no PeerLost event). Bothcargo checkandvue-tscgreen. Verify on a node with a radio (e.g. .116).