Commit Graph

804 Commits

Author SHA1 Message Date
sjg 2035e0cd6f [feat](trx-wefax): show decoder state transitions in frontend
Emit WefaxProgress events with a state label on each decoder state
transition (APT Start, Phasing, Receiving) so the frontend can display
the current decoder phase instead of just "listening for packets".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-03 22:48:10 +02:00
sjg 96dcbbe8f1 [fix](trx-frontend-http): fix bookmark decoder wiring
Two issues prevented bookmark decoder toggles from working:

1. bmPrefillFromStatus() did not prefill decoder checkboxes from the
   current toggle button state, so bookmarks were saved with an empty
   decoders array even when decoders were active.

2. The bookmark apply code fetched /status without the remote parameter,
   comparing against the wrong rig's decoder state in multi-rig setups.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-03 22:30:48 +02:00
sjg ce5b55386c [fix](trx-frontend-http): fix misaligned text in recorder Download/Remove buttons
Normalize button styling between <a> and <button> elements by using
inline-flex with centered alignment instead of inline-block. Add
align-items to the container and box-sizing to the buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-03 22:13:50 +02:00
sjg feb249cc0f [fix](trx-frontend-http): resolve per-rig state in decoder toggle endpoints
All decoder toggle endpoints (APRS, HF-APRS, CW, FT8, FT4, FT2, WSPR,
LRPT, WEFAX) read the enabled flag from the global default state watch
instead of the target rig's state. When controlling a non-active rig the
toggle reads the wrong rig's flag and sends the wrong enable/disable
value, causing the button to have no effect or invert the state.

Add resolve_rig_state() helper that looks up the per-rig watch via
context.rig_state_rx() and falls back to the global default, matching
the pattern already used by the /status endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-03 22:13:44 +02:00
sjg 919b6c5885 [fix](trx-frontend-http): route vchan commands to correct rig in background decode
BackgroundDecodeManager.send_audio_cmd used the global active_rig_id()
to route virtual channel commands. During a rig switch, Remove commands
for the old rig's channels were sent to the new rig's audio pipeline,
leaving orphaned virtual channels on the previous rig's server.

Replace send_audio_cmd with send_audio_cmd_to_rig that takes an explicit
rig_id, derived from the channel's own rig_id field. Both Remove and
SubscribeBackground commands now reach the correct rig.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-03 22:04:11 +02:00
sjg ced77464f9 [fix](trx-rs): use cache_dir for recordings and decode logs
Move default output directories from $XDG_DATA_HOME to $XDG_CACHE_HOME
so all runtime data lives under ~/.cache/trx-rs/ consistently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-03 19:33:11 +02:00
sjg c8a5e15b3b [feat](trx-frontend-http): add Live/History views to WEFAX tab
Restructure the WEFAX tab to match the SAT/LRPT pattern with a
view switcher bar. Live view shows decoder description, live canvas,
and latest image card. History view adds a filterable, sortable table
of all decoded images with Clear All button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-03 19:26:18 +02:00
sjg 462d7494fb [fix](trx-frontend-http): remove duplicate id on WEFAX tab button
The WEFAX button had id="subtab-wefax" which duplicated the panel's id,
causing querySelector to match the button instead of the panel on click.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-03 18:52:27 +02:00
Claude f607feaec4 [fix](trx-wefax): populate WEFAX tab with working live canvas and gallery
- Fix WefaxProgress.line_data serialization: change from Vec<u8> (JSON
  array) to base64-encoded String so the browser's atob() call works
- Set output_dir in server WefaxConfig to $XDG_CACHE_HOME/trx-rs/wefax
  so decoded PNG images are persisted to disk
- Add /images/{filename} GET route in trx-frontend-http to serve saved
  WEFAX PNGs with path traversal protection
- Capture live canvas as data URI on image completion for immediate
  gallery thumbnail display without requiring the file serving route

https://claude.ai/code/session_01V1kLpgLPb8Q5wSv4UrcLbr
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-03 18:47:37 +02:00
Claude 716d901d75 [fix](trx-frontend-http): add missing WEFAX toggle button click handler
The wefax.js plugin defined wefaxToggleBtn but never attached a click
event listener, so clicking "Enable WEFAX" did nothing. Also switched
the clear button from raw fetch() to postPath() so it includes the
remote parameter in multi-rig setups.

https://claude.ai/code/session_01UJQpbecEBbphMZkSDKCiY6
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-03 07:45:39 +02:00
Claude daa31fb6e5 [feat](trx-wefax): implement WEFAX decoder with full server and frontend integration
Pure Rust WEFAX (Weather Facsimile) decoder supporting 60/90/120/240 LPM,
IOC 288 and 576, with automatic APT tone detection and phase alignment.

Core DSP pipeline:
- Polyphase rational resampler (48k→11025 Hz)
- FM discriminator (Hilbert FIR + instantaneous frequency)
- Goertzel tone detector (300/450/675 Hz APT tones)
- Phase alignment via cross-correlation on phasing signal
- Line slicer with linear interpolation pixel clock recovery
- Image assembler with PNG encoding

State machine: Idle→StartDetected→Phasing→Receiving→Stopping

Server integration:
- WefaxMessage/WefaxProgress in trx-core DecodedMessage
- DecoderConfig, DecoderResetSeqs, RigCommand wefax variants
- DECODER_REGISTRY entry in trx-protocol
- DecoderHistories/DecoderLoggers wefax support
- run_wefax_decoder() async task in trx-server audio.rs
- History persistence in pickledb store

Frontend integration:
- wefax.js plugin with live canvas rendering and gallery
- HTML sub-tab with canvas, gallery, toggle/clear controls
- SSE dispatch for wefax/wefax_progress events
- Decode history worker and restore support
- Toggle/clear API endpoints

19 unit tests covering resampler, FM discriminator, tone detection,
phasing, line slicing, image encoding, and decoder state machine.

https://claude.ai/code/session_019eyxgx3LuhcFZ7T5tr2Trm
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-03 06:50:42 +02:00
sjg ce3cdfe448 [fix](trx-frontend-http): add missing closing tag on recorder tab button
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-02 19:41:33 +02:00
sjg dd8b86b38f [feat](trx-frontend-http): hide decoder tabs not present in server registry
After fetching /decoders, hide sub-tab buttons, panels, overview
descriptions, about-status rows, and settings clear-history buttons
for decoders the server doesn't advertise. This makes feature-gated
decoders like FT2 fully invisible in the UI when disabled.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 22:20:36 +02:00
sjg 2c388f8dc0 [fix](trx-frontend-http): make extra channels editable in scheduler inline edit
The inline row editor rendered extra channels as read-only text and
never saved changes to bookmark_ids. Add a dropdown + chip UI matching
the form modal pattern so users can add/remove extra channels inline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 22:02:48 +02:00
sjg 5221e3cbcc [fix](trx-frontend-http): load sat.js with digital-modes plugins
sat.js was only in the 'map' plugin group but the SAT subtab lives
under digital-modes. History/Predictions buttons had no click handlers
until the map tab was visited. The loaded Set prevents double-loading.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 19:42:38 +02:00
sjg 6502d59e54 [feat](trx-frontend-http): use monospace font for signal strength units
Wrap unit labels (dBm, dBf, dBFS, S, dB) in a .sig-unit span styled
with the system monospace stack, keeping numeric values in DSEG14.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 19:42:32 +02:00
sjg 2e7f3e0126 [fix](trx-frontend-http): fix Download/Remove button styling in recorder table
The Download button is an <a> tag which inherits default link styles
(underline, mismatched font/sizing). Added text-decoration, display,
font-family, and line-height to normalize both <a> and <button> elements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 19:34:24 +02:00
sjg c0e250111f [fix](trx-frontend-http): expand DSEG14 unicode-range to cover letters for RDS PS
The @font-face unicode-range only included digits and punctuation, so
letter characters in RDS station names fell back to generic monospace.
Expanded to U+0020-007E (full printable ASCII) matching all glyphs in
the font.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 19:27:19 +02:00
sjg 387015773a [fix](trx-frontend-http): expose reverseGeocodeLocation on window.trx.map namespace
Function was defined in map-core.js but not exported, causing a TypeError
when app.js called window.trx.map.reverseGeocodeLocation().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 19:09:04 +02:00
sjg 5c3b11d4c2 [fix](trx-frontend-http): vendor DSEG14 font locally to avoid CDN content blockers
Same issue as Leaflet — content blockers block the jsdelivr CDN request,
causing the seven-segment font to fail loading and fall back to monospace.

Also replace preload-to-stylesheet swap with media="print" onload swap
for themes.css and leaflet.css to eliminate Safari preload warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 19:08:04 +02:00
sjg 7859b82b16 [fix](trx-frontend-http): restore DSEG14 font on RDS PS field in debug panel
The .rds-ps class was missing font-family after JS refactoring, causing it
to inherit the generic monospace stack from .rds-value instead of using the
seven-segment DSEG14 Classic font.

Fixes #141

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 19:01:10 +02:00
sjg 9ab3db287a [fix](trx-frontend-http): expose missing functions on window.trx namespace
Add markDecodeMapSyncPending, decodeHistoryMapRenderingDeferred,
decodeHistoryReplayActive, decodeMapSyncPending, updateDocumentTitle,
activeChannelRds, _activeTab, and locationSubtitle to window.trx so
map-core.js can access them via the T alias.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 18:52:31 +02:00
sjg cb78070c59 [fix](trx-frontend-http): fix map not loading on direct /map navigation
navigateToTab now calls loadPluginsForTab to ensure map-core.js is
injected on initial page load from /map URL. map-core.js auto-inits the
map if the map tab is already visible when the module loads.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 18:47:09 +02:00
sjg 4fe6d1fcf7 [fix](trx-frontend-http): strip sourceMappingURL from vendored leaflet.js
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 18:43:45 +02:00
sjg 627ae63806 [fix](trx-frontend-http): vendor Leaflet 1.9.4 locally to avoid CDN content blockers
Bundle Leaflet JS, CSS, and marker/layer images as embedded assets served
under /vendor/ instead of loading from unpkg.com, which content blockers
(e.g. Safari) prevent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-04-01 18:40:48 +02:00
Claude 661f013a92 [fix](trx-frontend-http): load scheduler eagerly and auto-init on late load
The lazy plugin loader (25c5940) deferred scheduler.js to the 'settings'
tab, but initSettingsUI() runs at app boot before the user clicks any tab.
This meant initScheduler was undefined at boot, so the scheduler-control-row
on the main tab never showed and status polling never started.

Two fixes:
1. Add 'settings' to the eagerly-loaded plugin list so scheduler.js and
   vchan.js load at startup alongside digital-modes and bookmarks.
2. Add auto-init at the end of scheduler.js: if authRole is already set
   when the script executes (late/lazy load), it self-initializes without
   waiting for initSettingsUI(). This makes it resilient to any load order.

https://claude.ai/code/session_01YNwgQGjCdLjVMcatVy3uQi
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-01 13:45:20 +02:00
Claude 525224010c [fix](trx-frontend-http): load scheduler plugin on settings tab instead of recorder
The lazy plugin loader introduced in 25c5940 incorrectly mapped
scheduler.js to the 'recorder' tab. The scheduler UI lives under
Settings → Scheduler, so the plugin must load with the 'settings' tab.
This caused the scheduler controls to be invisible and non-functional.

https://claude.ai/code/session_01NuatkhpFU7JCRnAbNUavPk
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-01 13:12:58 +02:00
Claude de3b9f0bbb [fix](trx-frontend-http): move escapeMapHtml to global scope in app.js
escapeMapHtml was defined inside the map-core.js IIFE, making it
inaccessible to app.js and plugin files (aprs, ais, vdes, cw, hf-aprs)
that call it from global scope, causing ReferenceError at runtime.

Move the function definition to app.js (global scope), export it via
window.trx, and destructure it in map-core.js like other shared utils.

https://claude.ai/code/session_01RhL8cCcszaguKqoWn5XUxL
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-01 12:59:09 +02:00
Claude c12cdb4c57 [fix](trx-frontend-http): use theme-aware CSS variables for spectrum overlay styling
Replace hardcoded rgba(15, 23, 42, ...) backgrounds and #b31217/#ff7b7b
colors with color-mix() using CSS custom properties (--card-bg, --bg,
--text, --accent-red). This ensures RDS overlays, decoder bar overlays
(APRS, AIS, VDES, FT8, CW), header-main, and tab containers all
respect the selected color scheme and light/dark theme.

https://claude.ai/code/session_01L8XeLh7iHnX3LGLbqswLPu
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-01 12:59:00 +02:00
Claude 25c59405b5 [feat](trx-frontend-http): split app.js into ES modules with lazy loading
Extract map-core.js (3,483 lines) and screenshot.js (261 lines) from
the monolithic app.js, reducing it by ~30% (11,967 → 8,427 lines).

Modules communicate via a window.trx shared namespace with getter/setter-
backed state proxying. Map and statistics code lazy-loads on first tab
activation; screenshot code lazy-loads on first "S" keypress. All cross-
module calls use optional chaining for safe access before modules load.

Adds Rust infrastructure (include_str, gz_cache, Actix routes) for
serving the new JS assets.

https://claude.ai/code/session_01HgW8UpscRRA3CgSLqQDzdp
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-01 12:43:07 +02:00
Claude c9167177e0 [fix](trx-frontend-http): fix rig initialization freeze caused by auth-badge inside template
The auth-badge element was wrapped inside <template id="tmpl-about">,
making it invisible to document.getElementById() at page load.
updateAuthUI() accessed badge.style without a null check, throwing a
TypeError that halted app initialization before connect() was called.

Move auth-badge outside the template so it is always in the live DOM,
and add defensive null guards on badge/badgeRole access.

https://claude.ai/code/session_01Km7uxYUzehpYBdYqncnt4n
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-01 11:02:54 +02:00
Claude 941a37494b [feat](trx-frontend-http): implement frontend styling & performance improvements
CSS: reduce backdrop-filter to modals only, add contain/content-visibility
for inactive tabs, optimize transitions to background-color, pre-compute
color-mix results, add container queries, split themes to lazy-loaded file.

JS: cache DOM refs in render path, add field-level diffing for SSE updates,
replace innerHTML with replaceChildren() in hot paths, add WebGL colour
cache invalidation on theme switch.

HTML: add defer to scripts, lazy-load plugin scripts on tab activation,
SVG sprite sheet for tab icons, template elements for deferred tab content,
improve aria-live/keyboard nav/colour contrast accessibility.

Server: upgrade Cache-Control to immutable, add Brotli compression alongside
gzip with Accept-Encoding negotiation.

Implements all items from docs/frontend_improvements.md except app.js ES
module split (P1, requires major refactor) and Web Worker migration (P3).

https://claude.ai/code/session_015rQNMGvusj5jY66MPUgYqt
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-01 10:36:12 +02:00
Claude 07a10c0c3b [fix](trx-frontend-http): remove decommissioned NOAA 15/18/19 satellite presets
NOAA 15, 18, and 19 APT satellites are decommissioned. Remove them
from the satellite preset list and update the placeholder text.

https://claude.ai/code/session_01VFLAHs1UMzPso3GWSQP9wJ
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-01 09:51:58 +02:00
Claude 06f7c43799 [feat](trx-frontend-http): implement scheduler UI improvements (P0–P3)
Implement all 15 scheduler improvement tasks from docs/scheduler_improvements.md:

P0 — Usability Fixes:
- Highlight active entry in time-span table with sch-active class
- Bookmark existence validation on save with toast error
- Dirty-state indicator for satellite section via markDirty bridge

P1 — Information Density & Clarity:
- Show local time alongside UTC in entry table and timeline
- Expand entry details by default with localStorage persistence
- Richer "Now Playing" status card with freq, mode, active decoders

P2 — Interaction Improvements:
- Inline entry editing directly in table rows
- Drag-to-reorder entries with HTML5 drag-and-drop
- Timeline click-to-add with pre-filled hour range
- Improved extra-channels management with chip list and dropdown

P3 — Feature Enhancements:
- Grayline location lookup by Maidenhead grid square
- Expanded satellite preset library (NOAA 15/18/19, ISS, SO-50)
- Scheduler activity log with ring buffer backend and UI
- Timeline interleave visualization with alternating color stripes
- Keyboard shortcuts (Shift+R/N/P) for scheduler control

https://claude.ai/code/session_01VFLAHs1UMzPso3GWSQP9wJ
Signed-off-by: Claude <noreply@anthropic.com>
2026-04-01 09:51:58 +02:00
Claude 1fe0b75e20 [fix](trx-rs): fix LRPT pass detection status never updating during active decoding
The #sat-status element was stuck on "Waiting for satellite pass" because:

1. The client audio handler (audio_client.rs) did not include AUDIO_MSG_LRPT_IMAGE
   in its message type match, so LRPT image messages from the server were silently
   dropped and never reached the frontend.

2. No progress was reported during active LRPT decoding — the only status update
   happened when a complete image was finalized, which could take the entire pass.

3. The sat-status text was never updated when the decoder was enabled/disabled,
   leaving it permanently at the HTML default text.

Changes:
- Add DecodedMessage::LrptProgress variant for live MCU progress reporting
- Send LRPT progress updates from the decoder task when new MCUs are decoded
- Add AUDIO_MSG_LRPT_IMAGE and AUDIO_MSG_LRPT_PROGRESS to client audio handler
- Update sat-status text when decoder state changes (enabled/disabled)
- Handle lrpt_progress messages in the frontend to show "Receiving — N MCU rows"

https://claude.ai/code/session_017knbD7dr6hJGAWR6pModL7
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-31 16:21:12 +02:00
sjg bf2d70bf93 [style](trx-frontend-http): add tooltip and placeholder to recorder filter
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-31 03:07:17 +02:00
sjg 5f99f87f81 [fix](trx-frontend-http): add /recorder SPA route and fix header wrap
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-31 03:02:12 +02:00
sjg 10f25349e2 [feat](trx-frontend-http): add recorder file management and pagination
Add download/remove buttons per file, filename filter, sort dropdown, and paginated file list. Restore header REC toggle button. Add GET /api/recorder/download/{filename} and DELETE /api/recorder/files/{filename} endpoints with path traversal protection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-31 02:52:34 +02:00
sjg bccb66f250 [feat](trx-frontend-http): replace header REC button with Recorder tab page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-31 02:32:16 +02:00
sjg f2048c583c [feat](trx-rs): add client-side Opus audio recorder
Record Opus audio streams to OGG files on the client. Includes manual start/stop via HTTP API, scheduler-driven auto-recording per schedule entry, and a header REC button in the web UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-30 23:37:09 +02:00
sjg 2296a53916 [feat](trx-frontend-http): add S-meter unit to signal strength selector
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-30 22:13:40 +02:00
sjg 691f0727b2 [feat](trx-frontend-http): display S-meter in standard S-unit steps
Show S0–S9 as whole units and S9+xdB in 10dB steps instead of fractional S-unit values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-30 21:35:08 +02:00
sjg 80887ce859 [style](trx-rs): cargo fmt
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-30 21:25:14 +02:00
sjg bb1fdbb43d [refactor](trx-frontend-http): wire JS frontend to decoder registry
Fetch /decoders on page load and use the registry to drive all
decoder-related UI instead of hardcoded lists:

- bookmarks.js: bmReadDecoders/bmWriteDecoders and bookmark form
  checkboxes generated from registry; bmApply() decoder toggle gate
  uses registry active_modes instead of hardcoded DIG/FM check
- background-decode.js: delete SUPPORTED_DECODERS constant, derive
  bookmarkDecoderKinds() from registry
- app.js: _decoderToggles and SSE status sync built from registry;
  updateDecodeStatus() and setModeBoundDecodeStatus() driven by
  registry mode_bound/toggle entries
- index.html: replace 8 hardcoded decoder checkboxes with dynamic
  container populated from registry

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-30 20:57:13 +02:00
sjg e6dbfd1edb [feat](trx-protocol): add centralised decoder registry
Add DECODER_REGISTRY in trx-protocol::decoders as the single source of
truth for all decoder metadata (activation mode, supported rig modes,
background-decode capability). Replace duplicated resolver functions in
background_decode.rs and sse.rs with shared resolve_bookmark_decoders().
Add GET /decoders endpoint to expose the registry to the frontend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-30 20:47:12 +02:00
Claude 5c43bac42b [feat](trx-rs): remap decoder modes — remove DIG/PKT from SDR, wire decoders to standard modes
For SDR backends, DIG and PKT are removed from supported_modes and
replaced by USB and FM respectively. CAT backends (FT-817, FT-450D)
retain DIG/PKT as before.

Decoder mode allowances updated:
- APRS: FM | PKT (was PKT only)
- HF-APRS: USB | DIG (was DIG only)
- AIS: AIS | FM | PKT (was AIS only)
- VDES: VDES | FM (was VDES only)
- FT8/FT4/FT2/WSPR: USB | DIG (unchanged)
- CW: CW | CWR (unchanged)
- LRPT: FM (unchanged, mode-independent)

Frontend status text, bookmark decoder toggles, background-decode
fallbacks, and scheduler wiring updated to match.

https://claude.ai/code/session_01DCAaMH8RF5FNB2gRtVu4pY
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-30 18:55:04 +02:00
Claude f944cc0790 [fix](trx-frontend-http): remove max-width constraint from settings panel
The scheduler/settings panel had a max-width: 900px that made it narrower
than the statistics panel which has no such constraint.

https://claude.ai/code/session_0151QL4vHke3z31jJKAtP1b1
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-30 18:10:03 +02:00
Claude 5e51990275 [feat](trx-frontend-http): add FM broadcast band (87.5-108 MHz) to bandplan
Add the FM broadcasting band to all three IARU regions so the
87.5-108 MHz range is visible in the bandplan overlay.

https://claude.ai/code/session_01XCmCtBud7riY5anZRvvK2p
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-30 11:10:44 +02:00
Claude 582f674b7a [feat](trx-frontend-http): add missing amateur bands for full 0-1 GHz coverage
Add 2200m (135.7-137.8 kHz), 630m (472-479 kHz), 4m (70-70.5 MHz,
R1 only), 1.25m (222-225 MHz, R2 only), and 33cm (902-928 MHz, R2
only) bands to bandplan.json across all applicable IARU regions.

https://claude.ai/code/session_01XCmCtBud7riY5anZRvvK2p
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-30 11:10:44 +02:00
Claude 7dfac0c38c [fix](trx-frontend-http): remove duplicate bandplan overlay from spectrum canvas
The bandplan strip was rendered twice: once as a DOM element above the
spectrum and again via WebGL directly on the spectrum canvas. Remove the
WebGL duplicate and keep only the DOM-based strip.

https://claude.ai/code/session_01TA1pCDuAr7V6oSnQs7JYvU
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-30 11:08:41 +02:00