From 997bc81d5e465e0745d09e4db837bddc750c6dc8 Mon Sep 17 00:00:00 2001 From: rouggy Date: Sun, 30 Aug 2026 15:29:07 +0200 Subject: [PATCH] fix(udp): edge-detect the decoder's DX Call stream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WSJT-X restates the same DX Call in every Status packet, and a spot clicked in OpsLog put that call into the last-UDP memory (deliberately, for another case) — so the guard let the decoder's next restatement straight through and the entry snapped back to old news. The decoder's stream now only counts when its value CHANGES; a clear over there resets the edge so re-selecting the same station still lands. Explicit picks (N1MM, remote, spot relays) are untouched. --- changelog.json | 6 ++++-- frontend/src/App.tsx | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/changelog.json b/changelog.json index 52c957b..a3f2410 100644 --- a/changelog.json +++ b/changelog.json @@ -6,13 +6,15 @@ "Bulk operations work on any size of selection — setting a field, fixing frequencies, deleting, marking uploads and exporting the selection all failed with “too many SQL variables” past a few tens of thousands of QSOs. Statements are now issued in slices.", "Elecraft console: the power meter reads in real watts. The K3’s bargraph is relative to a range that flips at 12 W — calibrated against a real radio’s full table, the PC setting picks the range and the bar converts to watts.", "Watchlist: a visual pass toward DXHunter’s look — pink callsigns, counter pills, quieter cards with a hover, the ⚡ back on the DXpedition badge.", - "WSJT-X / JTDX: OpsLog can highlight decodes in the decoder’s own Band Activity window from your log — watchlist members pink, new DXCC green, new band orange (option in Settings → Connections). And a freshly-started decoder is asked to replay its on-screen decodes, so the FT decodes panel starts full." + "WSJT-X / JTDX: OpsLog can highlight decodes in the decoder’s own Band Activity window from your log — watchlist members pink, new DXCC green, new band orange (option in Settings → Connections). And a freshly-started decoder is asked to replay its on-screen decodes, so the FT decodes panel starts full.", + "WSJT-X / JTDX / MSHV: only a CHANGED DX Call updates the entry — the decoder re-broadcasts the same call endlessly, and it kept overwriting a spot clicked in OpsLog." ], "fr": [ "Les opérations groupées fonctionnent quelle que soit la taille de la sélection — définir un champ, corriger des fréquences, supprimer, marquer les uploads et exporter la sélection échouaient avec « too many SQL variables » au-delà de quelques dizaines de milliers de QSO. Les requêtes sont désormais émises par tranches.", "Console Elecraft : le wattmètre lit en vrais watts. Le bargraph du K3 est relatif à une gamme qui bascule à 12 W — calibré sur la table complète d’une vraie radio, le réglage PC choisit la gamme et la barre se convertit en watts.", "Watchlist : une passe visuelle vers le look DXHunter — indicatifs roses, compteurs en pastilles, cartes plus feutrées avec survol, le ⚡ de retour sur le badge DXpedition.", - "WSJT-X / JTDX : OpsLog peut surligner les décodages dans la fenêtre Band Activity du décodeur selon votre log — watchlist en rose, nouveau DXCC en vert, nouvelle bande en orange (option dans Réglages → Connections). Et un décodeur fraîchement détecté rejoue ses décodages à l’écran, donc le panneau FT decodes démarre plein." + "WSJT-X / JTDX : OpsLog peut surligner les décodages dans la fenêtre Band Activity du décodeur selon votre log — watchlist en rose, nouveau DXCC en vert, nouvelle bande en orange (option dans Réglages → Connections). Et un décodeur fraîchement détecté rejoue ses décodages à l’écran, donc le panneau FT decodes démarre plein.", + "WSJT-X / JTDX / MSHV : seul un DX Call qui CHANGE met à jour la saisie — le décodeur rediffuse le même call sans fin, et il écrasait un spot cliqué dans OpsLog." ] }, { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 2620ebb..2254029 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2667,6 +2667,11 @@ export default function App() { // "the field still shows the previous broadcast" (safe to update) from "the // user has typed a different call" (must not clobber). const lastUdpCallRef = useRef(''); + // Edge detection for the DECODER'S stream: WSJT-X/JTDX/MSHV re-broadcast the + // same DX Call in every Status packet, seconds apart, forever. Applying each + // one meant a spot clicked in OpsLog was overwritten moments later by the + // decoder restating old news. Only a CHANGE in this stream is an event. + const lastWsjtEdgeRef = useRef(''); // When the entered callsign turns out to be worked-before, jump to the // Worked-before tab so the history is front-and-centre. Only once per call, @@ -3796,6 +3801,13 @@ export default function App() { // Anything that isn't WSJT-X (N1MM, ADIF, a panadapter/cluster click relayed // over UDP…) is an explicit pick → force it over an existing call. const force = String(p?.service ?? '').toLowerCase() !== 'wsjt'; + if (!force) { + // The decoder's stream: same value as last time = no edge = no update. + // Only a changed DX Call is the operator doing something over there. + const upper = String(p?.call ?? '').trim().toUpperCase(); + if (upper && upper === lastWsjtEdgeRef.current) return; + lastWsjtEdgeRef.current = upper; + } // External app moved to a new station → fresh recording for the new target. if (applyUdpCall(p?.call, force)) restartRecordingForNewTarget(String(p?.call ?? '')); }); @@ -3806,6 +3818,9 @@ export default function App() { // Only when something is actually in the entry, so an idle digital app doesn't // wipe a call being typed by hand. const unsubClear = EventsOn('udp:clear_call', () => { + // The decoder cleared its DX Call: the next call it announces — even the + // same one re-selected — is a fresh edge. + lastWsjtEdgeRef.current = ''; if (callsignRef.current?.value?.trim() || callsign.trim()) resetEntry(); }); // Clicked one of OpsLog's spots on the FlexRadio panadapter → fill the call