fix(wb): latest lookup wins the worked-before panel

Two lookups race when a second callsign is typed before the first answered,
and the slow one landed last: the grid showed the previous call's QSOs under
the new call's name — LU5AVM's contact filed under LW8ETV, screenshot in
hand. A request token now discards any response that is not the newest.
This commit is contained in:
2026-08-30 11:26:47 +02:00
parent 8e7ecc3d51
commit 7b15b534cd
2 changed files with 13 additions and 3 deletions
+4 -2
View File
@@ -37,7 +37,8 @@
"Icom console: the meters use the same LED bars as the Flex and Elecraft consoles, and the mode badge says USB or LSB instead of an ambiguous SSB.", "Icom console: the meters use the same LED bars as the Flex and Elecraft consoles, and the mode badge says USB or LSB instead of an ambiguous SSB.",
"Cluster: spots on the standard FT8/FT4 frequencies of every band now read FT8/FT4 when the comment names no mode — 30 m, 60 m, 80 m FT4, 17 m FT4 and 12 m were falling into the generic DATA bucket.", "Cluster: spots on the standard FT8/FT4 frequencies of every band now read FT8/FT4 when the comment names no mode — 30 m, 60 m, 80 m FT4, 17 m FT4 and 12 m were falling into the generic DATA bucket.",
"OmniRig (Yaesu): with split engaged, tuning to a spot moves BOTH VFOs — on an FT-2000 the write landed on the TX VFO only, so the transmitter QSYed and the receiver stayed behind.", "OmniRig (Yaesu): with split engaged, tuning to a spot moves BOTH VFOs — on an FT-2000 the write landed on the TX VFO only, so the transmitter QSYed and the receiver stayed behind.",
"Icom network: Wake-on-LAN — a rig switched fully off (LAN server down) is woken with a magic packet to its remembered MAC whenever a session is wanted, so the console and its ON button come back without a walk to the shack." "Icom network: Wake-on-LAN — a rig switched fully off (LAN server down) is woken with a magic packet to its remembered MAC whenever a session is wanted, so the console and its ON button come back without a walk to the shack.",
"Worked before: a slow lookup can no longer overwrite a newer one — typing a second callsign quickly could leave the previous calls QSOs displayed under the new calls name."
], ],
"fr": [ "fr": [
"Console Elecraft : le S-mètre est calibré sur un vrai K3 — S9 et les +dB correspondent désormais à laffichage de la radio (il lisait environ deux points S trop bas).", "Console Elecraft : le S-mètre est calibré sur un vrai K3 — S9 et les +dB correspondent désormais à laffichage de la radio (il lisait environ deux points S trop bas).",
@@ -74,7 +75,8 @@
"Console Icom : les mètres utilisent les mêmes barres LED que les consoles Flex et Elecraft, et le badge de mode dit USB ou LSB au lieu dun SSB ambigu.", "Console Icom : les mètres utilisent les mêmes barres LED que les consoles Flex et Elecraft, et le badge de mode dit USB ou LSB au lieu dun SSB ambigu.",
"Cluster : les spots sur les fréquences standard FT8/FT4 de chaque bande lisent désormais FT8/FT4 quand le commentaire ne nomme pas de mode — 30 m, 60 m, FT4 80 m, FT4 17 m et 12 m tombaient dans le bloc DATA générique.", "Cluster : les spots sur les fréquences standard FT8/FT4 de chaque bande lisent désormais FT8/FT4 quand le commentaire ne nomme pas de mode — 30 m, 60 m, FT4 80 m, FT4 17 m et 12 m tombaient dans le bloc DATA générique.",
"OmniRig (Yaesu) : avec le split actif, se rendre sur un spot déplace LES DEUX VFO — sur un FT-2000 l’écriture natteignait que le VFO TX, donc l’émetteur QSYait et le récepteur restait derrière.", "OmniRig (Yaesu) : avec le split actif, se rendre sur un spot déplace LES DEUX VFO — sur un FT-2000 l’écriture natteignait que le VFO TX, donc l’émetteur QSYait et le récepteur restait derrière.",
"Réseau Icom : Wake-on-LAN — une radio complètement éteinte (serveur LAN coupé) est réveillée par un paquet magique vers sa MAC mémorisée dès quune session est voulue, et la console avec son bouton ON revient sans aller au shack." "Réseau Icom : Wake-on-LAN — une radio complètement éteinte (serveur LAN coupé) est réveillée par un paquet magique vers sa MAC mémorisée dès quune session est voulue, et la console avec son bouton ON revient sans aller au shack.",
"Déjà contacté : une recherche lente ne peut plus écraser une plus récente — taper un second indicatif rapidement pouvait laisser les QSO du call précédent affichés sous le nom du nouveau."
] ]
}, },
{ {
+9 -1
View File
@@ -4615,10 +4615,17 @@ export default function App() {
return () => { dead = true; }; return () => { dead = true; };
}, [selQso, callsign]); }, [selQso, callsign]);
const wbTokenRef = useRef(0);
async function runWorkedBefore(call: string, dxccHint: number = 0) { async function runWorkedBefore(call: string, dxccHint: number = 0) {
// Latest-wins: two lookups race when the operator types a second call
// before the first answered, and the SLOW one used to land last — the
// grid then showed the previous call's QSOs under the new call's name
// (LU5AVM's contact filed under LW8ETV, screenshot in hand).
const token = ++wbTokenRef.current;
setWbBusy(true); setWbBusy(true);
try { try {
const w = await WorkedBefore(call, dxccHint); const w = await WorkedBefore(call, dxccHint);
if (token !== wbTokenRef.current) return; // a newer lookup owns the panel
setWb(w); setWb(w);
// Mirrored synchronously rather than through the effect above: a backfill // Mirrored synchronously rather than through the effect above: a backfill
// parked by the lookup has to read this on the very next line, not a // parked by the lookup has to read this on the very next line, not a
@@ -4633,10 +4640,11 @@ export default function App() {
fillFromLastQso(p.r, call); fillFromLastQso(p.r, call);
} }
} catch { } catch {
if (token !== wbTokenRef.current) return;
setWb(null); setWb(null);
wbRef.current = null; wbRef.current = null;
wbCallRef.current = ''; wbCallRef.current = '';
} finally { setWbBusy(false); } } finally { if (token === wbTokenRef.current) setWbBusy(false); }
} }
// fillFromLastQso enriches the entry from the LAST QSO we logged with this call // fillFromLastQso enriches the entry from the LAST QSO we logged with this call
// when the live lookup came up short — the callsign isn't on QRZ/HamQTH, or no // when the live lookup came up short — the callsign isn't on QRZ/HamQTH, or no