Replace the BW slider + FIR taps filter panel with a visual bandwidth
bookmark drawn directly on the spectrum canvas:
- Semi-transparent amber gradient strip spanning dialFreq ± BW/2
- Rounded-top bookmark tab at the top of the strip showing the current BW
- Draggable left/right edge handles (cursor: ew-resize) that adjust bandwidth
live and send set_bandwidth on mouse-up; range clamped per-mode defaults
- Y-axis now labeled with dB values (floor to ceiling) drawn on canvas
- Configurable floor level via number input below spectrum (default -100 dB)
- Auto button fits floor/range to current noise floor and peak level
- Remove FIR taps selector (internal DSP implementation detail)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Add MODE_BW_DEFAULTS table mapping each mode to [default, min, max, step]
in Hz. When mode changes (via picker or SSE), applyBwDefaultForMode
updates the filter bandwidth slider range and sends set_bandwidth to the
server, so the DSP filter is rebuilt automatically for the new mode.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Spectrum panel is now placed above the freq/mode/jog row, spanning the
full card width. Key improvements:
- Scroll wheel zooms in/out at the cursor position (up to 64x); double-
click resets to full bandwidth view.
- Mouse drag pans the visible window; click-to-tune is suppressed when a
drag has occurred.
- Touch pinch-to-zoom and single-finger drag-to-pan supported.
- Hover tooltip shows the frequency under the cursor, formatted to the
currently selected unit (MHz/kHz/Hz, matching the jog-step selection).
- Frequency axis labels update to reflect the zoomed visible range.
- Canvas height increased to 160 px; axis bar styled with card bg.
- A small hint line below the panel explains the controls.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Poll GetSpectrum every 200 ms in remote_client via a dedicated timer that
bypasses the main state-watch channel (no SSE noise). The resulting
SpectrumData is stored in FrontendRuntimeContext::spectrum and served by
a new GET /spectrum endpoint (JSON or 204 when unavailable).
HTTP frontend shows a spectrum panel (canvas + frequency axis) only when
the rig reports filter_controls=true (i.e. SoapySDR). The canvas renders:
- dark background with dBFS grid lines
- green FFT spectrum line with semi-transparent fill
- red dashed vertical marker at the currently tuned frequency
- frequency axis labels (MHz/kHz) below the canvas
Clicking the canvas tunes the rig to the clicked frequency.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Hide the header rig picker when showing the authentication gate,
since no rigs are accessible until the user authenticates.
Show the picker again when auth gate is hidden (after login).
This improves UX by not showing an empty picker to unauthenticated users.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Use header rig selector as the single point for rig switching. Remove
redundant about page rig selector controls and associated JavaScript
event listeners.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add /set_bandwidth and /set_fir_taps HTTP endpoints to api.rs.
Add applyCapabilities(caps) function to app.js that shows/hides:
- PTT button and TX meters: capabilities.tx
- TX limit row: capabilities.tx_limit
- VFO row: capabilities.vfo_switch
- Signal meter row: capabilities.signal_meter
- Filters panel: capabilities.filter_controls
Called from render() whenever capabilities are present; runs on both
initial /status response and every SSE event.
Add a Filters panel to index.html with bandwidth slider (1..500 kHz)
and FIR taps select (16/32/64/128/256); hidden by default, revealed by
applyCapabilities when filter_controls is set. Each control dispatches
to the corresponding HTTP endpoint on change.
Sync filter state from update.filter in render() to keep slider/select
in sync with server-side DSP state.
Fix missing struct fields in test helpers across remote_client.rs,
trx-frontend-http-json/server.rs, trx-frontend-rigctl/server.rs, and
trx-core controller tests (handlers.rs, machine.rs).
Update aidocs/UI-CAPS.md: all tasks UC-01..UC-09 marked [x].
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Fix authenticated refresh by restoring tab visibility during startup, and retune dark mode toward deep blue with amber-red accents.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Add compile-time build dates for trx-server and trx-frontend-http, propagate server build metadata through rig state/snapshot, and render both versions + build dates in the HTTP footer.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Enable sig-clear-btn for RX users since clearing signal measurements
is a local UI operation that doesn't affect rig state.
Only disable decode history clear buttons:
- aprs-clear-btn
- ft8-clear-btn
- wspr-clear-btn
- cw-clear-btn
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
After logging in, automatically show the Main tab-panel and mark
the Main tab button as active. Previously, users had to click the
Main tab to see content after login.
hideAuthGate() now:
- Shows the Main tab-panel
- Hides all other tab-panels
- Marks the Main tab button as active
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
When logout is clicked from the About tab, hide all tab panels to
prevent tab content from showing behind the login window.
Also ensures auth gate is displayed cleanly without any stray content
visible behind it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Disable all decode history clear buttons for rx-authenticated users:
- APRS clear
- FT8 clear
- WSPR clear
- CW clear
- Signal clear
These are control operations that should be restricted to full access.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
After logout, check if guest mode is available and show the
"Continue as Guest" button if no rx_passphrase is configured.
Previously, authLogout() always passed false to showAuthGate(),
hiding the guest button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Remove duplicate logout button from About tab. Use only the header
Login/Logout button for unified authentication control.
The About tab now shows the authentication badge (when logged in)
without the redundant logout button.
Single login view:
- Auth gate with Login form + Continue as Guest button (when no rx pass)
- Header Login/Logout button for quick access
- Auth badge in About tab showing current role
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Only redirect to login on 401 (unauthenticated). For 403 errors
(authenticated but insufficient role), let the caller handle the error.
This prevents rx-authenticated users from being redirected to login
when they attempt to scroll the jog wheel or frequency input, which
tries to call /set_freq (a control-only endpoint).
RX users will now see "Insufficient permissions" hint instead of
being sent to login screen.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Fix logout flow to properly show auth gate and clear form. Also
disable additional controls for rx role:
- Jog wheel (faded out)
- Jog up/down buttons
- VFO selector buttons
For rx-authenticated users, all frequency/mode adjustment controls
are now properly disabled to prevent accidental changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Replace location.reload() with disconnect() + auth gate to prevent
browser hang when logging out. The full page reload was causing
issues with resource loading and event source reconnection timers.
Changes:
- Add disconnect() function to cleanly close EventSource connections
and clear all timers (esHeartbeat, reconnectTimer)
- authLogout() now disconnects locally and shows auth gate instead
of reloading the page
- Faster logout experience without full page reload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Add a Login/Logout button in the header next to the theme toggle,
styled consistently with the theme button. Button behavior:
- When logged in: Shows "Logout" with confirmation
- When not logged in: Shows "Login" to open auth gate
- Visible when on main app (not in auth gate)
- Same theme-toggle-btn styling
Provides quick access to authentication controls without needing to
navigate to the About tab.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Do not auto-connect with guest role. Always show the auth gate when
there's no valid session, allowing the user to choose between:
- Login: Enter passphrase for control access
- Continue as Guest: Proceed with read-only access (if available)
This allows users to enter their control passphrase instead of being
forced into guest mode.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
When RX access is unrestricted (no rx_passphrase required), show
a "Continue as Guest" button on the auth gate to allow immediate
access without requiring login. The button is only shown when guest
mode is available.
Guest mode:
- No authentication required
- Grants rx role immediately
- Can monitor radio but cannot transmit
Login path still available for full control access.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
When a user is authenticated as 'rx' role (read-only), disable all
TX/PTT control buttons and frequency/mode inputs to prevent accidental
attempts to transmit. This provides clear visual feedback that these
controls are not available.
Controls disabled for rx role:
- PTT button
- Power button
- Lock button
- TX Audio button
- Frequency input
- Mode select
- TX Limit input/button
- Jog up/down buttons
- Jog step buttons
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Hide the Main/Plugins/About tab bar initially, only showing it after
the user successfully authenticates. This prevents navigation options
from being visible when access has not been granted.
Changes:
- Add display:none and id to tab-bar div in index.html
- Update showAuthGate() to hide tab-bar
- Update hideAuthGate() to show tab-bar
Now the UI flow is:
1. Header only (auth gate visible)
2. After login: Header + tabs + content
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Phase 4: Frontend login gate and role-based UI
- Add auth-gate HTML overlay with passphrase form
- Implement checkAuthStatus, authLogin, authLogout functions
- Auth startup sequence checks /auth/session before connecting
- Apply role-based restrictions: hide PTT/TX controls for rx role
- Handle 401/403 errors in postPath, return to login screen
- Add logout button in About tab with auth role display
- Passphrase form shows generic error messages (no info leakage)
Phase 5: Documentation
- Update trx-client.toml.example with [frontends.http.auth] section
- All config fields with inline documentation and examples
- security notes about cookie settings
- Update README.md with HTTP Frontend Authentication section
- Role model explanation (rx vs control)
- Configuration example
- Security considerations for local, LAN, and remote deployments
- Architecture overview
UI Features:
- Login gate blocks main UI until authenticated
- Role badge shows authenticated status in About tab
- Error messages clear after 5 seconds
- Logout confirmation prevents accidental logouts
- Smooth transition from auth gate to main UI
All code compiles successfully. HTTP frontend build verified.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Refine map plotting and filter UX in HTTP frontend plugins.\n\n- support plotting multiple locator squares from FT8/WSPR messages\n- show locator lists in popup content as newline-separated entries\n- add WSPR map layer filter toggle and marker typing\n- style filter controls for strong dark/light mode contrast\n- keep themed behavior aligned with map and control updates\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Add dark/light mode selector below logo and wire theme-aware visuals.\n\n- add compact theme toggle control under header logo\n- support persistent dark/light theme switching\n- use emoji labels for theme toggle actions\n- make jog and audio level visuals theme-aware\n- add dark-mode map tile layer and live layer switching on theme changes\n- keep responsive behavior for header graph and controls\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Implement UI refinements for the HTTP frontend main and plugin views.\n\n- add dimmed header signal graph with live rendering and scale\n- make graph responsive, colorized by signal strength, and keep last 10s only\n- add APRS and WSPR text filtering, matching FT8 behavior\n- refine responsive layout for controls/map/header behavior\n- tune jog wheel/button sizing and mode selector height alignment\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>