Follow-up to #53. That change kept the mini views over the waterfall to the selected rig; this one does the same for the decoder panels behind them.
What was wrong
A client connected to several rigs decodes all of them at once, and the decode stream carries every rig's traffic to every browser. The panels listed all of it:
a station a background rig copied on another band appeared in the APRS list next to the selected rig's
N total, the vessel and burst counts, and the "latest seen" lines counted both rigs
the status lines read "Receiving" because some rig was
the CW pane interleaved two rigs into one stream of text that read as neither
a WEFAX or SSTV picture from another rig painted straight over the one being watched on the live canvas
What it does now
The page is about the rig the operator selected — the one whose spectrum is on screen and whose audio is playing — so each panel shows what that rig heard: rows, counts, latest-seen, status, the live picture, and the CW pane.
Panel
Filtered
APRS, HF APRS
rows, N total, M shown, latest-seen, status
AIS
rows, vessel count, latest-seen, status
VDES
rows, burst count, latest-seen, status
FT8 / FT4 / FT2, WSPR
rows, status
CW
the copied-text pane, signal indicator, WPM/tone readouts
WEFAX, SSTV
live canvas, latest card, history table and counts
The map is untouched, on purpose
Nothing is dropped on the way in. The map is the whole station's view, it has its own rig selector (#map-rig-filter, defaulting to All), and it would empty out if the plugins stopped feeding it — so the histories still hold every rig and every plot call sits outside the filter. Statistics stay station-wide too, with their own receiver picker and the per-rig comparison.
That also makes switching lossless: the plugin runtime gained a rerender hook that the rig switch calls, and switching back brings the other rig's traffic up again. The one exception is the CW pane — a running stream of text cannot be unpicked after the fact — so it starts empty on the rig you switch to. Documented rather than hidden.
Verification
65 unit tests pass, including 6 new panel tests (AIS, VDES, FT8, WSPR, the CW pane, and a rig switch repainting through the runtime). mini-view-rig.test.mjs becomes active-rig.test.mjs now that it covers both pages.
decode-flow.mjs pins the whole split in one place: a vessel from rig-b arrives while rig-a is selected, and the panel does not list it, the mini view does not show it, and markers.ais === 2 on the map.
Typecheck, lint and the full browser suite pass. Generated bundles rebuilt.
The user manual gains a "Multiple Rigs in the Web UI" section with the per-page table and the CW caveat.
Note this inverts the rule #53 wrote into active-rig.ts — that panels aggregate the station. The comment there now states the real boundary: radio page and digital modes are one rig, map and statistics are the station.
Follow-up to #53. That change kept the mini views over the waterfall to the selected rig; this one does the same for the decoder panels behind them.
## What was wrong
A client connected to several rigs decodes all of them at once, and the decode stream carries every rig's traffic to every browser. The panels listed all of it:
- a station a background rig copied on another band appeared in the APRS list next to the selected rig's
- `N total`, the vessel and burst counts, and the "latest seen" lines counted both rigs
- the status lines read "Receiving" because *some* rig was
- the CW pane interleaved two rigs into one stream of text that read as neither
- a WEFAX or SSTV picture from another rig painted straight over the one being watched on the live canvas
## What it does now
The page is about the rig the operator selected — the one whose spectrum is on screen and whose audio is playing — so each panel shows what that rig heard: rows, counts, latest-seen, status, the live picture, and the CW pane.
| Panel | Filtered |
|---|---|
| APRS, HF APRS | rows, `N total`, `M shown`, latest-seen, status |
| AIS | rows, vessel count, latest-seen, status |
| VDES | rows, burst count, latest-seen, status |
| FT8 / FT4 / FT2, WSPR | rows, status |
| CW | the copied-text pane, signal indicator, WPM/tone readouts |
| WEFAX, SSTV | live canvas, latest card, history table and counts |
## The map is untouched, on purpose
Nothing is dropped on the way in. The map is the whole station's view, it has its own rig selector (`#map-rig-filter`, defaulting to All), and it would empty out if the plugins stopped feeding it — so the histories still hold every rig and every plot call sits outside the filter. Statistics stay station-wide too, with their own receiver picker and the per-rig comparison.
That also makes switching lossless: the plugin runtime gained a `rerender` hook that the rig switch calls, and switching back brings the other rig's traffic up again. The one exception is the CW pane — a running stream of text cannot be unpicked after the fact — so it starts empty on the rig you switch to. Documented rather than hidden.
## Verification
- 65 unit tests pass, including 6 new panel tests (AIS, VDES, FT8, WSPR, the CW pane, and a rig switch repainting through the runtime). `mini-view-rig.test.mjs` becomes `active-rig.test.mjs` now that it covers both pages.
- `decode-flow.mjs` pins the whole split in one place: a vessel from `rig-b` arrives while `rig-a` is selected, and the panel does not list it, the mini view does not show it, and `markers.ais === 2` on the map.
- Typecheck, lint and the full browser suite pass. Generated bundles rebuilt.
- The user manual gains a "Multiple Rigs in the Web UI" section with the per-page table and the CW caveat.
Note this inverts the rule #53 wrote into `active-rig.ts` — that panels aggregate the station. The comment there now states the real boundary: radio page and digital modes are one rig, map and statistics are the station.
A client connected to several rigs decodes all of them at once, and the
decode stream carries every rig's traffic to every browser. The decoder
panels listed all of it: a station a background rig copied on another band
appeared in the APRS list next to the selected rig's, the vessel counts and
the "latest seen" lines counted both, the status lines said "Receiving"
because some other rig was, and the CW pane interleaved two rigs into one
stream of text that read as neither.
The page is about the rig the operator selected — the one whose spectrum is
on screen and whose audio is playing — so each panel now shows what that rig
heard: rows, counts, latest-seen, status, the live picture a WEFAX or SSTV
frame is painting, and the CW pane.
Nothing is dropped on the way in. The map is the whole station's view, has
its own rig filter, and would empty out if the plugins stopped feeding it, so
the histories still hold every rig and the map still plots them. That also
means a switch loses nothing: the runtime gained a rerender hook, which the
rig switch calls, and switching back brings the other rig's traffic up again.
The CW pane is the exception — a running stream of text cannot be unpicked
after the fact — so it starts empty on the rig switched to.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SyX26FCpMQxiBoC7r5K1A7
Signed-off-by: Stan Grams <sjg@haxx.space>
sjg
merged commit bf3bcc8a84 into main2026-08-07 08:45:45 +02:00
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.
Follow-up to #53. That change kept the mini views over the waterfall to the selected rig; this one does the same for the decoder panels behind them.
What was wrong
A client connected to several rigs decodes all of them at once, and the decode stream carries every rig's traffic to every browser. The panels listed all of it:
N total, the vessel and burst counts, and the "latest seen" lines counted both rigsWhat it does now
The page is about the rig the operator selected — the one whose spectrum is on screen and whose audio is playing — so each panel shows what that rig heard: rows, counts, latest-seen, status, the live picture, and the CW pane.
N total,M shown, latest-seen, statusThe map is untouched, on purpose
Nothing is dropped on the way in. The map is the whole station's view, it has its own rig selector (
#map-rig-filter, defaulting to All), and it would empty out if the plugins stopped feeding it — so the histories still hold every rig and every plot call sits outside the filter. Statistics stay station-wide too, with their own receiver picker and the per-rig comparison.That also makes switching lossless: the plugin runtime gained a
rerenderhook that the rig switch calls, and switching back brings the other rig's traffic up again. The one exception is the CW pane — a running stream of text cannot be unpicked after the fact — so it starts empty on the rig you switch to. Documented rather than hidden.Verification
mini-view-rig.test.mjsbecomesactive-rig.test.mjsnow that it covers both pages.decode-flow.mjspins the whole split in one place: a vessel fromrig-barrives whilerig-ais selected, and the panel does not list it, the mini view does not show it, andmarkers.ais === 2on the map.Note this inverts the rule #53 wrote into
active-rig.ts— that panels aggregate the station. The comment there now states the real boundary: radio page and digital modes are one rig, map and statistics are the station.