Commit Graph

1024 Commits

Author SHA1 Message Date
sjg 0b28900082 [refactor](trx-ftx): optimize ft2 decode hot paths
Reuse FT2 downsample and bitmetric work buffers, speed up\nsync2d_score with precomputed references, and cache peak-search\nFFT state on the pipeline.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-18 23:08:42 +01:00
sjg 7d20058c03 [chore](trx-rs): remove unused external ft8_lib
Delete the obsolete ft8_lib submodule and update documentation to point at the pure Rust trx-ftx decoder.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-18 22:44:35 +01:00
sjg ab30270a63 [chore](trx-rs): update SPDX copyright headers
Normalize tracked SPDX headers to the 2026 Stan Grams identity.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-18 22:39:06 +01:00
sjg 2609ce668a [fix](trx-ftx): clear decoder warnings
Quiet compiler and clippy warnings in the translated decoder modules.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-18 22:34:55 +01:00
sjg 7cc8490024 [fix](trx-wspr): clear decoder warnings
Keep protocol items before tests and rewrite warning-triggering loops.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-18 22:34:43 +01:00
sjg 5dabe32106 [refactor](trx-rs): remove trx-ft8 C FFI crate, use trx-ftx directly
Delete trx-ft8 (C wrapper around ft8_lib + ft2_ldpc) and update
trx-server to depend on trx-ftx (pure Rust) directly. Removes
~2,900 lines of C code and all unsafe FFI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-18 22:22:20 +01:00
sjg de79e8a1e6 [feat](trx-ftx): add pure Rust FTx decoder crate
Replace the C FFI-based trx-ft8 with a pure Rust implementation
supporting FT8, FT4, and FT2 protocols. Eliminates cc/libc build
dependencies and all unsafe FFI code while providing the same
Ft8Decoder/Ft8DecodeResult public API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-18 22:21:12 +01:00
sjg 974b9fa9ed [refactor](trx-rs): convert external/ft8_lib to git submodule
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-18 21:44:07 +01:00
sjg 71b9a3128b [feat](trx-frontend-http): refactor map source filter to toggle behavior
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-18 21:29:26 +01:00
sjg 353be875be [style](trx-wspr): apply cargo fmt formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-18 21:29:23 +01:00
sjg cc64c51fd0 [feat](trx-frontend-http): make map source filter select exclusively on click
Clicking a source chip now isolates that source instead of toggling it.
Clicking the already-isolated source restores default visibility.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-18 07:18:23 +01:00
sjg 723da3f7ed [fix](trx-frontend-http): make decode history lists fill remaining viewport
Replace the fixed max-height: 360px on FT8/FT4/FT2/WSPR message
containers with flex-based layout so they grow to fill the available
space. Make #content, .tab-panel, and .sub-tab-panel flex containers
that propagate height down the layout chain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 23:20:49 +01:00
sjg 7cf829ef52 [feat](trx-rs): display APRS-IS connection status on About page
Thread aprs_is_status through RigState, RigSnapshot, and the protocol
layer following the same pattern as pskreporter_status. Show the
connection target and callsign when enabled, or "Disabled" otherwise.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 23:20:43 +01:00
sjg 2517ed0b29 [fix](trx-frontend): fix spectrum screenshot hotkey
Preserve the WebGL drawing buffers used by the spectrum snapshot,
flush them before compositing, and move the shortcut listener to
capture phase so focused widgets do not swallow it.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 23:11:10 +01:00
sjg 9019acee0e [feat](trx-backend-soapysdr): enable hardware AGC by default if available
Query the device for AGC support via has_gain_mode and enable it
automatically at startup. Devices without hardware AGC fall back to
manual gain as before.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 22:57:20 +01:00
sjg cf4c262456 [fix](trx-wspr): reduce false positives with stricter validation
Restrict accepted power levels to the 19 valid WSPR values instead of
any 0-60. Require a digit at position 1 or 2 of the trimmed callsign
per the WSPR encoding rules. Skip candidates whose sync correlation
score falls below a minimum threshold before attempting Fano decode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 22:57:13 +01:00
sjg 7527770c0c [fix](trx-frontend): let decoder disable take scheduler control
When a scheduler-managed decoder is manually disabled from the frontend,
take scheduler control first so the manual change overrides the current
scheduler cycle like a direct frequency change does.

Track decoder enabled state on the toggle buttons and only take over
when the click is actually disabling FT8, FT4, FT2, WSPR, or HF APRS.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 22:39:00 +01:00
sjg b533d704a1 [style](trx-rs): reformat codebase
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 22:36:11 +01:00
sjg a823e66816 [fix](trx-server): drop in-flight decodes on main retune
Invalidate main-decoder windows whenever the rig's main frequency
changes, including direct SetFreq, scheduler-driven retunes, and
external CAT retunes observed during polling.

The decoder loops now resubscribe their PCM receivers on reset and drop
results that finish after the reset sequence advances, preventing false
decodes from stale pre-retune audio.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 22:28:31 +01:00
sjg 7044747ade [fix](trx-wspr): remove spurious power field offset that rejected all decodes
The WSPR 7-bit power field contains the raw dBm value (0-60) with no
offset. The decoder was subtracting 64, turning valid power values into
negative numbers that always failed the range check, causing
unpack_message to return None for every real signal. Also fix callsign
trimming to strip leading spaces from space-padded callsigns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 22:26:55 +01:00
sjg da799a1d1f [fix](trx-frontend): widen main panel on large screens
Allow the main frontend card to grow past the previous 1280px cap
on large screens while keeping side gutters for bookmark stacks.

Only widen the desktop layout at 1440px+ and cap it at 1600px so the
main content stays readable with room for side bookmarks.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 22:07:36 +01:00
sjg bcd3255ad7 [fix](trx-wspr): fix reversed deinterleaving that prevented all decodes
The deinterleave function had its indices swapped: it wrote
out[j] = symbols[p] instead of out[p] = symbols[j]. This fed
completely scrambled data to the Fano decoder, making convergence
impossible. Matched against the reference implementation in
raptor/lib/wsprd/wsprd_utils.c which does tmp[p] = sym[j].

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 21:48:06 +01:00
sjg 46415fa307 [fix](trx-ft8): add hard-error verification to FT2 OSD decoder
The OSD-lite decoder was the source of FT2 false positives. It tries
685 CRC-14 checks across 5 passes (1 + 16 + 120 per pass), giving a
~4% chance of accepting random noise as a valid decode.

The reference implementation (decode174_91) verifies OSD results
against the received signal; the trx-rs OSD-lite only checked CRC.

Add ft2_count_hard_errors_vs_llr() which counts how many of the 174
coded bits in an OSD candidate disagree with the received hard
decisions. A legitimate correction disagrees in very few positions;
a false CRC match on noise disagrees in ~40-50 parity positions.
Reject OSD results with more than 36 hard errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 21:44:21 +01:00
sjg 8aa1884d2d [fix](trx-ft8): align FT2 decoder thresholds and LLR scaling with reference
The FT2 decoder was failing to decode valid signals due to thresholds
and LLR parameters that were significantly stricter than the reference
implementation (Decodium/raptor ft2_triggered_decode).

Thresholds aligned with reference at depth>=3:
- Peak detection: 1.08 -> 1.03 (reference uses 0.50 on normalized spectrum)
- Scan sync: 0.60 -> 0.50 (reference at depth>=3)
- Decode sync: 0.80 -> 0.65 (reference at depth>=3)
- Sync quality min: 13 -> 10 (reference at depth>=3)

LLR parameters aligned:
- Scale factor: 2.83 -> 3.2 (matches reference scalefac)
- Normalization: sqrt(24/var) -> 1/sigma (matches reference normalizebmet)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 21:38:48 +01:00
sjg 7844cb65c8 [fix](trx-ft8): add missing encode.c to build
The ft8_wrapper.c references ft4_encode and ft8_encode from encode.c,
but encode.c was not included in build.rs, causing linker errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 21:29:42 +01:00
sjg c71fc58e3e [fix](trx-wspr): add sync vector correlation and multi-candidate decoding
The WSPR decoder was producing almost no valid decodes despite audible
signals. Three root causes:

- No sync vector: the 162-bit WSPR sync pattern was not used, so signal
  detection relied on raw peak power which is unreliable.
- Coarse frequency search: 4 Hz steps with 1.465 Hz tone spacing could
  miss signals entirely. Now uses 2 Hz coarse + 0.25 Hz fine refinement.
- Fixed timing: assumed signal starts exactly 1s into the slot. Now
  searches +/-2s in 0.5s steps to handle real-world timing jitter.

Also evaluates up to 8 frequency/timing candidates per slot and reports
the actual measured timing offset in dt_s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 21:24:50 +01:00
sjg 4464fa3735 [fix](trx-ft8): replace adjacent-bin SNR with post-decode estimation
The previous SNR formula (cand->score * 0.5 - 29.0) used the adjacent
tone bin as a noise reference. On a crowded FT8 band that bin is often
occupied by another station, inflating the apparent noise floor by
10-15 dB and capping reported SNR at around -10 dB even for strong
signals.

Replace with ftx_post_decode_snr(): re-encode the decoded message to
obtain the exact per-symbol tone sequence, compare each signal bin
against the minimum of the remaining (noise-only) bins, average over
all valid symbols, and apply the WSJT-X 2500 Hz bandwidth correction
dynamically per protocol. This produces accurate SNR estimates for both
FT8 and FT4 regardless of band occupancy.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 21:06:43 +01:00
sjg e1a9a8717f [style](trx-frontend-http): fix picker widths in scheduler entry form
Primary bookmark was cramped at one grid column; Extra channels was
unnecessarily spanning the full row. Swap their grid-column spans so
the bookmark select gets full width and Extra channels sits in a
normal column alongside Label and Interleave.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 01:43:21 +01:00
sjg 49659a5ce7 [style](trx-frontend-http): increase spacing in scheduler entry form
Row gap 0.5→0.75rem and label-to-input gap 0.2→0.35rem, scoped
to #sch-entry-form so the bookmark form is unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 01:42:42 +01:00
sjg d6d7c7d1f0 [style](trx-frontend-http): make scheduler entry Edit/Remove buttons smaller
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 01:41:57 +01:00
sjg 8da4c49d1d [feat](trx-frontend-http): align scheduler entry form with bookmark modal
Replace the inline always-visible add-row with a modal overlay
(same fixed + blurred-backdrop pattern as the bookmark add/edit
form). The "+ Add Entry" button opens the modal; each row now has
Edit and Remove buttons. Edit pre-fills the modal and updates the
entry in-place on save. CSS reuses the existing bookmark modal
selectors rather than duplicating rules.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 01:40:37 +01:00
sjg fc423d9958 [docs](trx-rs): drop FLAC support from recorder plan
Opus is the sole audio format. Removes all FLAC references, the
format config key, the claxon/flac dependency row, and the
FLAC-encoder open question.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 01:29:42 +01:00
sjg 659f18143d [docs](trx-rs): add recorder feature plan
Captures requirements REQ-REC-001–006, REQ-PLAY-001–002, and
REQ-SYNC-001 into a structured design document covering the new
trx-recorder crate, session layout (FLAC/Opus audio + JSONL data
track + seek index), command API, playback engine, and phased
implementation plan.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 01:27:42 +01:00
sjg bff3be38be [feat](trx-backend-soapysdr): implement ARM NEON optimizations
Add NEON (aarch64) vectorized paths mirroring the existing AVX2 paths:

- demod/math_arm.rs: replace the no-op placeholder with a full NEON FM
  discriminator that processes 4 samples per iteration using a 7th-order
  minimax atan polynomial and branchless atan2 with argument reduction,
  matching the accuracy of the AVX2 path (max error ~2.4e-7 rad).
  32-bit ARM retains the scalar fallback.

- dsp/filter.rs: add mul_freq_domain_neon() that deinterleaves 4 complex
  pairs via vuzpq/vzipq, performs complex multiply with vmulq/vaddq/vsubq,
  then reinterleaves. On aarch64 this path is always taken (NEON is
  mandatory); scalar fallback remains for other targets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 01:22:56 +01:00
sjg 088f05050c [feat](trx-frontend-http): add strongest decoded signal summary to map
Add a new "Strongest decoded signal" section below the existing
"Longest decode paths" section on the map tab, showing the top 5
stations with the highest SNR across the current map history window.
Reuses existing map-qso-card styling with SNR displayed in place of
distance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 01:12:15 +01:00
sjg 4c69273584 [feat](trx-wspr): implement WSPR protocol decoder
Replace the always-None stub with a full decode pipeline:
- Bit-reversal deinterleave of 4-FSK symbols (data_bit = symbol >> 1)
- Fano sequential decoder for K=32, rate-1/2 convolutional code
  (polynomials 0xF2D05351 / 0xE4613C47, 100k-cycle budget)
- Payload unpack: 28-bit callsign (mixed-radix N1), 15-bit Maidenhead
  grid (M1 formula), 7-bit power code (dBm + 64)
- Validity checks on callsign, grid, and power range
- Round-trip unit test for K1JT FN20 37

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 01:04:38 +01:00
sjg 7a144375f2 [fix](trx-backend-soapysdr): enforce 9 kHz minimum bandwidth for AMC mode
clamp_bandwidth_for_mode now floors AMC bandwidth at 9 kHz so that both
the sum (L+R) and difference (L−R) sidebands are always captured,
regardless of what the user or a set_filter call requests.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:19:35 +01:00
sjg e337870d53 [fix](trx-backend-soapysdr): add AMC to supported_modes capabilities list
RigMode::AMC was implemented but omitted from the supported_modes vec,
so the HTTP frontend never received it in capabilities and the mode
selector did not show AMC-QUAM.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:15:47 +01:00
sjg 016d4ddfd7 [fix](trx-rs): resolve all clippy warnings
- remote_client tests: add missing server_connected field and import
  AtomicBool in the test module
- pskreporter: replace map_or(true, …) with is_none_or and
  repeat(x).take(n) with repeat_n(x, n)
- dsp.rs, scheduler.rs: suppress intentional too_many_arguments with
  #[allow(clippy::too_many_arguments)]

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:15:03 +01:00
sjg 6eb2d5341f [fix](trx-backend-ft450d): mark AMC unsupported in FT-450D encoder
Add a RigMode::AMC arm to encode_mode returning an Err so that
attempting to set C-QUAM on the FT-450D returns a descriptive error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:10:48 +01:00
sjg bdc581637c [fix](trx-backend-ft817): mark AMC unsupported in FT-817 encoder
Add RigMode::AMC to the None return arm of encode_mode so that
attempting to set C-QUAM on the FT-817 returns a descriptive error
rather than a compile-time non-exhaustive match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:10:45 +01:00
sjg c818139175 [feat](trx-frontend-http): add AMC-QUAM to mode selector
Add "AMC-QUAM" to the MODE_BW_DEFAULTS table in app.js with the same
bandwidth settings as AM (9 kHz default, 500 Hz min, 20 kHz max, 500 Hz
step). Add an <option value="AMC-QUAM"> to the bookmark datalist in
index.html.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:10:40 +01:00
sjg 223726368d [feat](trx-server): handle AMC mode in rig_task and server config
Add RigMode::AMC arm to default_audio_bandwidth_for_mode, returning
9_000 Hz (same as AM).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:10:34 +01:00
sjg 3564a48ced [feat](trx-backend-soapysdr): implement C-QUAM stereo demodulator
Add CquamDemod (demod/amcquam.rs) with first-order IIR carrier phase
tracker (τ = 50 ms) that rotates baseband IQ to align I with the sum
audio and Q with the difference audio, then DC-blocks each channel to
yield L/R stereo PCM.

Wire AmCQuam into the Demodulator enum, add ChannelDsp::cquam_decoder
field initialized for RigMode::AMC, and insert the C-QUAM audio path
between the WFM and fallback branches in process_block. Update all
mode-dispatch tables (agc_for_mode, iq_agc_for_mode, dc_for_mode,
default_bandwidth_for_mode, lib.rs, vchan_impl.rs) with AMC arms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:10:31 +01:00
sjg 6be8644d45 [feat](trx-protocol): serialize AMC mode as "AMC-QUAM"
Add parse_mode and mode_to_string support for RigMode::AMC, accepting
"AMC-QUAM", "AMC_QUAM", and "AMC" as input strings and serializing to
"AMC-QUAM". Add test cases for round-trip correctness.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:10:20 +01:00
sjg 52452b609d [feat](trx-core): add AMC variant to RigMode for C-QUAM AM stereo
Add RigMode::AMC to represent Motorola C-QUAM Compatible Quadrature
Amplitude Modulation stereo, placing it after RigMode::AM.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-17 00:10:15 +01:00
sjg 844b0e60df [fix](trx-frontend-http): roll back optimistic freq update when set_freq fails
setRigFrequency applied applyLocalTunedFrequency before the network
round-trip, leaving the spectrum view shifted to the new frequency even
when the POST was rejected (e.g. 403 when the user loses control access).
Save the previous frequency and restore it in the catch block so the UI
stays aligned with the actual server-side state.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-16 23:46:04 +01:00
sjg 9fba303bd8 [feat](trx-frontend-http): add connection-lost overlay for trx-client and trx-server failures
Show a full-screen blurred overlay (reusing decode-history-overlay styles)
when the SSE connection to trx-client drops or when trx-server is reported
unreachable via server_connected=false.  The overlay distinguishes the two
failure modes with separate titles and sub-text.  It is dismissed on
es.onopen (trx-client back) or when a message with server_connected!=false
arrives (trx-server back), and cleared on explicit disconnect/logout.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-16 23:44:18 +01:00
sjg 84dc28cf77 [fix](trx-frontend-http): dismiss decode history overlay on connection error
decodeSource.onerror terminated the history worker but never called
flushLiveBuffer(), leaving historySettled=false and the "Loading decode
history…" overlay stuck on screen when trx-client breaks.  Call
flushLiveBuffer() in the error path so the overlay is dismissed and the
powerHint connection-lost message is visible to the user.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-16 23:41:18 +01:00
sjg 0f57fb8920 [fix](trx-frontend-http): fix axis bookmark chip positioning after name span addition
querySelectorAll("span") was picking up the inner .spectrum-bookmark-name
spans added in the previous commit, causing chips[i] to map to the wrong
element during left-position assignment.  Switch to :scope > span to
select only direct-child chip spans.

Also revert axis bar from height:auto (which breaks the CSS transition and
collapses the bar) to height:38px with overflow:visible to accommodate
two-line labels while keeping the open/close animation intact.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-03-16 23:37:11 +01:00