Commit Graph

274 Commits

Author SHA1 Message Date
sjg 17be874ee3 [style](trx-frontend): remove rds frame counter
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 23:10:03 +01:00
sjg 3d7ac6f6ed [feat](trx-frontend): bookmark markers, category colors, text filter
- Move bookmark frequency markers from drawSpectrum() to drawSignalOverlay()
  so dashed lines span both the waterfall and waveform canvases
- Assign distinct palette colors to named categories; uncategorised uses
  --accent-yellow resolved from the live theme at runtime
- Compute WCAG-compliant foreground color (dark/light) per category so label
  text is always legible against the solid background
- Add text search input to the Bookmarks toolbar; filters by name, category,
  and comment client-side without re-fetching from the server

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 23:00:05 +01:00
sjg 8b94c5e0bd [feat](trx-frontend-http): move bookmark axis between waterfall and waveform
Relocate #spectrum-bookmark-axis from inside .spectrum-wrap to the
flex gap between .overview-strip (waterfall) and #spectrum-panel
(waveform). Give it z-index:5 so labels sit above the signal-overlay-
canvas (BW/freq selector, z-index:4). Drop the now-unneeded
#spectrum-freq-axis.bm-axis-open border-radius hack and the
corresponding JS class toggle.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 20:03:57 +01:00
sjg 473bbb280a [style](trx-frontend): add golden rain theme
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 19:42:09 +01:00
sjg 587b06c6d8 [feat](trx-frontend-http): overlay bookmarks on spectrum; enforce one per freq
Draw bookmark frequency markers on the spectrum canvas: amber vertical
line + ribbon shape (rectangle with V-notch) at each bookmark in view.
Below the freq axis, show a #spectrum-bookmark-axis row of clickable
amber ribbon labels (clip-path bookmark shape); clicking tunes the rig.
Labels auto-appear / collapse as bookmarks scroll in and out of view.

Server: reject POST/PUT with 409 Conflict when another bookmark already
exists at the requested freq_hz (BookmarkStore::freq_taken helper).

Client: bmFetch() triggers a spectrum redraw so markers appear
immediately on load without requiring a tab visit first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 19:39:09 +01:00
sjg e80f71ced6 [style](trx-frontend-http): make bookmark decoders selectable; gate add on control role
Replace the free-text decoder input with FT8/WSPR checkboxes so users
cannot enter arbitrary decoder strings. Hide the "+ Add Bookmark" button
by default and show it only when the authenticated role is `control`
(or auth is disabled), matching the server-side write-endpoint guard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 19:30:59 +01:00
sjg 832fac1d64 [fix](trx-rs): refine wfm denoise and favicon handling
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 19:26:04 +01:00
sjg dc3c99b0ee [feat](trx-frontend-http): add Bookmarks tab to web UI
Add a "Bookmarks" tab between Main and Plugins in the tab bar.

HTML: tab panel with toolbar (category filter + Add Bookmark button),
an inline add/edit form (hidden by default, prefills freq/mode/BW from
the current rig state), and a sortable table showing all columns with
Tune / Edit / Del action buttons.

CSS: responsive bm-* classes following existing card/button theming,
works in both dark and light modes and all palette variants.

bookmarks.js: fetches bookmarks on tab activation, renders table with
event delegation, handles create/update/delete via REST, and applies a
bookmark by calling set_freq → set_mode → set_bandwidth, plus toggles
FT8/WSPR decoders when the stored mode is DIG.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 19:17:15 +01:00
sjg fbd881af7b [fix](trx-frontend): add peak hold off and scale waterfall floor
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 18:38:17 +01:00
sjg 63fd35802e [feat](trx-frontend): add Neon Disco colour scheme
Deep purple-black backgrounds, neon magenta (#ff10e0) as primary
accent and neon green (#39ff14) as secondary.  Waterfall sweeps
hue 300→120 (magenta→green).  Light variant uses muted (#cc00a8 /
#1f8800) counterparts on a lavender-tinted white background.

- style.css: dark + light CSS variable blocks for neon-disco
- app.js: CANVAS_PALETTE entry; "neon-disco" added to valid styles
- index.html: Neon Disco option in the style picker

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 18:06:17 +01:00
sjg dd051beee3 [style](trx-frontend-http): match APRS tab clear button to CW reference
Remove custom #aprs-clear-btn CSS overrides and SVG icon; reduce to a
plain <button>Clear</button> so it inherits the same global button
style as the CW clear button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 16:37:37 +01:00
sjg b6848c0c8e [style](trx-frontend): refine aprs web controls
Restyle the APRS clear button and tighten the APRS overlay bar to use
more compact, polished chrome while keeping the existing behavior.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:06:36 +01:00
sjg cbefdc15c4 [docs](trx-frontend): rename audio control labels
Update the web audio control labels in the markup and initialize the
same labels from JavaScript for consistency.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:41:13 +01:00
sjg 62c5889619 [feat](trx-frontend-http): add APRS bar overlay on overview strip
Show the last 5 received APRS frames as a compact overlay in the
bottom-left corner of the waterfall strip, styled similarly to the
RDS PS overlay (backdrop blur, pill border). Frames fade out by
recency via CSS sibling-selector opacity steps. Bar auto-hides when
empty and is cleared by the APRS clear button. Restored from
localStorage on page load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:37:17 +01:00
sjg fce024b090 [style](trx-frontend): improve mobile web layout
Refine the mobile layout for the web frontend, add a sticky bottom tab bar,
and style the GitHub footer link as a badge.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:32:36 +01:00
sjg 441cdd3adb [style](trx-frontend): use select element for WFM denoise control
Replace the checkbox with an On/Off select dropdown to match the
styling of the other WFM controls (Deemp, Audio) in the controls row.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 13:41:13 +01:00
sjg 64bb9a0d42 [feat](trx-rs): expose WFM stereo denoise toggle in UI
Wire the StereoDenoise processor through the full stack:
- Add SetWfmDenoise command variant and RigCat trait method (trx-core)
- Add wfm_denoise field to RigFilterState with default true
- Add protocol command and bidirectional mapping (trx-protocol)
- Add rig_task command handler (trx-server)
- Implement set_wfm_denoise in SoapySdrRig backend
- Add /set_wfm_denoise API endpoint (trx-frontend-http)
- Add denoise checkbox in WFM controls with SSE sync and
  localStorage persistence

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 13:29:02 +01:00
sjg f9492633d9 [fix](trx-frontend): add footer project link and safari favicon fix
Add the trx-rs GitHub link in the footer and make favicon handling more explicit for Safari.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:03:47 +01:00
sjg 99c6ff0e87 [fix](trx-frontend): unify signal markers and clamp axis labels
Render the BW and tuned-frequency markers on a shared overlay and keep spectrum axis labels bold and inside their box.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:54:15 +01:00
sjg e3c7231650 [fix](trx-frontend): group signal visuals in main tab
Wrap the waterfall and spectrum in a shared main-tab block so lower sections and other tabs keep consistent spacing.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:37:53 +01:00
sjg 816780aa6b [fix](trx-frontend): compact wfm controls layout
Align the WFM options into a concise control strip with consistent sizes and spacing in the main window.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:25:52 +01:00
sjg 3ea516d27c [fix](trx-frontend): clarify tune step labels
Rename the tune-step scale labels so the divisor toggle reads clearly in the frequency controls.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:22:56 +01:00
sjg a9aee190d3 [fix](trx-frontend): move logo bar content into top bar
Move the logo/header cluster into the top bar on the left side.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:56:39 +01:00
sjg 420e98de31 [feat](trx-client,trx-frontend-http): add default rig and hideable rf gain
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 23:45:17 +01:00
sjg 617255cd32 [feat](trx-rs): expose live sdr gain control
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 23:30:08 +01:00
sjg df1bbf8f5b [fix](trx-rs): remove wfm denoise and default stereo audio
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 22:01:17 +01:00
sjg b722787ada [feat](trx-rs): show live wfm stereo detect state
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 21:44:32 +01:00
sjg 95716a0fc3 [feat](trx-rs): expose WFM stereo denoise toggle
Add a server-side toggle for the multiband stereo denoiser so it can be
enabled or disabled at runtime without restarting the server.

Backend (trx-backend-soapysdr):
- Add `denoise_enabled: bool` to `WfmStereoDecoder`; gate multiband
  blend behind it (falls back to uniform single-band blend when off)
- Add `set_denoise_enabled()` method on `WfmStereoDecoder`
- Propagate `wfm_denoise: bool` through `ChannelDsp`, `SdrPipeline`,
  and `SoapySdrRig`; add `set_wfm_denoise()` at each layer
- Include `wfm_denoise` in `filter_state()` so it flows into snapshots

Protocol / core (trx-core, trx-protocol, trx-server):
- Add `SetWfmDenoise(bool)` to `RigCommand` and `ClientCommand`
- Add default `set_wfm_denoise()` trait method to `RigCat`
- Handle `SetWfmDenoise` in `rig_task.rs` and update `RigFilterState`
- Add `wfm_denoise: bool` (default `true`) to `RigFilterState`

Frontend (trx-frontend-http):
- Add `POST /toggle_wfm_denoise` endpoint
- Add "Denoise On/Off" button next to the stereo/mono audio picker
- Sync button state from SSE filter snapshot (`update.filter.wfm_denoise`)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 19:47:36 +01:00
sjg ec1518facc [fix](trx-frontend-http): serve safari-friendly favicon
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 17:14:20 +01:00
sjg e26b8dd6a1 [feat](trx-frontend-http): refresh favicon from logo
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 17:09:51 +01:00
sjg ce25751c5d [feat](trx-rds,trx-frontend-http): add af tuning and dynamic page title
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 16:41:25 +01:00
sjg ea6830e343 [feat](trx-frontend-http): add rds raw json copy action
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 15:51:08 +01:00
sjg cf8d0743ce [feat](trx-rds,trx-frontend-http): expand rds metadata display
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 15:27:26 +01:00
sjg 0329be6124 [fix](trx-frontend-http): clarify jog step controls
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 12:16:09 +01:00
sjg 8f7afed132 [fix](trx-backend-soapysdr,trx-frontend-http): keep rds state on bw changes
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 12:13:06 +01:00
sjg f48e2a6a81 [feat](trx-frontend-http): improve rds pty and ps display
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 12:03:46 +01:00
sjg ee9add1b53 [feat](trx-frontend-http): move map into dedicated tab
Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 11:22:14 +01:00
sjg 855d21fd8a [debug](trx-backend-soapysdr,trx-frontend-http): add RDS diagnostics
Add server-side debug log when RDS data is decoded (PI, PS, PTY).
Extend the RDS panel with active mode, frame counter, and a raw JSON
dump of the last spectrum frame (bins excluded) to help diagnose why
RDS remains absent from the SSE stream.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 09:31:24 +01:00
sjg f7367e6270 [feat](trx-frontend-http): add RDS debug panel in Plugins tab
Add an RDS sub-tab to the Plugins panel showing PI code, PS name, PTY
number and name, decoder status, and a raw JSON dump of the latest RDS
data received via SSE. Also list the RDS decoder in the Overview tab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 09:16:15 +01:00
sjg e1ab2ae9dc [feat](trx-frontend-http): add automatic bandwidth sizing
Add an Auto BW control that estimates a suitable\nreceive bandwidth from the live spectrum around the\ncurrently tuned peak and applies it to the server.\n\nCo-authored-by: Codex <codex@openai.com>

Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 09:09:39 +01:00
sjg b27c2f8d73 [feat](trx-frontend-http): adjust auth header and style ids
Keep the top bar visible while logged out, limit access to\nthe Main tab, and leave theme controls available while the\nrig selector stays disabled.\n\nRename the internal style ids from nord/arctic and\nmonokai/lime, including a compatibility remap for saved\nsettings.\n\nCo-authored-by: Codex <codex@openai.com>

Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 08:53:51 +01:00
sjg 4b93e8ff97 [feat](trx-frontend-http): rename theme labels
Rename the Nord and Monokai theme labels in the web UI\nto Arctic and Brownie, and update the matching CSS\nsection comments.\n\nCo-authored-by: Codex <codex@openai.com>

Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 08:46:10 +01:00
sjg 7fa4f5d133 [fix](trx-frontend-http): fix jog multiplier reset and rename unit label
Fix updateJogStepSupport to snap jogUnit (not jogStep) to nearest
supported unit, then recompute jogStep = jogUnit * jogMult so the
multiplier is preserved across rig connect/reconnect.

Rename "Mult" label to "Unit Multiplier" for clarity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 02:37:16 +01:00
sjg 4f8658b773 [fix](trx-frontend-http): fix waterfall freeze, RDS bandwidth, add jog multiplier
Fix waterfall overview freezing at steady state by tracking a monotonic
push counter instead of row array length — the array size stays constant
once the waterfall is full, so the previous row-count comparison never
triggered the incremental draw path.

Fix WFM RDS not decoding when switching to WFM from a narrowband mode:
set_mode now resets audio_bandwidth_hz to the mode-appropriate default
(180 kHz for WFM) before rebuilding the FIR, preventing the 57 kHz RDS
subcarrier from being filtered out.

Add 1×/10×/100× multiplier button group next to the jog unit selector.
jogUnit × jogMult gives the effective jog step; both are persisted to
localStorage independently.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 02:25:39 +01:00
sjg f65135cb5e [feat](trx-frontend-http): display RDS PS name overlay on overview strip
When a WFM/SDR spectrum stream carries RDS data, show the Program
Service name (8-char station name) centered on the visible waveform
area in DSEG14 monospace — the same font as the frequency display.

- Add #rds-ps-overlay div inside .overview-strip (pointer-events: none,
  z-index: 2, absolutely positioned at the center of the visible canvas)
- updateRdsPsOverlay(rds) shows/hides and updates text on every spectrum
  frame; trims trailing spaces common in RDS PS strings
- Overlay cleared on spectrum disconnect / null frame
- text-shadow uses CSS color-mix against --bg for legibility across all
  style/theme combinations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 02:04:51 +01:00
sjg 7520796869 [feat](trx-frontend-http): add style picker with Nord, Monokai, Contrast themes
Add a style picker dropdown to the tab bar (right of rig picker) with
four styles — Original, Nord, Monokai, Contrast — each with full
light/dark variants.

CSS: define data-style attribute overrides for all CSS custom properties
(bg, card-bg, borders, text, accents, jog, audio level, filter, spectrum
background) for each of the three new styles × two themes (6 new blocks).

JS: introduce CANVAS_PALETTE lookup table covering spectrum/waveform/
waterfall colors for all style×theme combinations. Add currentStyle(),
canvasPalette(), setStyle() helpers. Persist selection to localStorage.

Replace all isLight ternaries in drawing code with palette lookups:
- drawOverviewWaterfall, drawOverviewSignalHistory, waterfallColor
  signatures changed from isLight flag to pal object
- drawSpectrum uses canvasPalette() for grid lines, labels, fill, line
- spectrumBgColor() now delegates to canvasPalette().bg

Theme toggle also triggers a spectrum redraw so canvas colors update
immediately when switching light/dark.

Also fix light-theme spectrum rendering broken since canvas drawing used
hardcoded dark-only colors (white grid lines invisible on light bg).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 01:48:45 +01:00
sjg 4e9516871f [feat](trx-frontend-http): improve mobile UX and fix S0/S9 label offset
- Add viewport meta tag so mobile browsers use device width instead of
  the default 980px desktop viewport
- Add 520px breakpoint: remove controls-tray forced min-width (was
  52–58rem, causing horizontal scroll on phones), stack controls-row
  into a single column with jog wheel first (order: -1)
- Scale frequency DSEG14 display with clamp() on narrow screens
- Make volume sliders responsive width with larger 20px thumb
- Raise spectrum Set/Auto button and input heights to 2.2rem (overrides
  the min-height: 0 that blocked the existing 760px touch-size rule)
- Add overflow-x: auto + flex-shrink: 0 to sub-tab-bar so all six
  plugin tabs are reachable on small screens without clipping
- Swap spectrum hint text based on input device: mouse/keyboard hint
  hidden on touch devices, touch-specific hint shown instead
- Offset S0/S9/S9+ signal history labels 6px below their grid lines

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 01:37:04 +01:00
sjg 449663ddd7 [feat](trx-frontend-http): refine decoder and SDR displays
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 01:22:30 +01:00
sjg 01485f3cd4 [fix](trx-frontend-http): rename browser title
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 01:09:42 +01:00
sjg 7258ea57b2 [fix](trx-frontend-http): restore tabs and relocate peak hold
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-02-28 01:08:56 +01:00