diff --git a/changelog.json b/changelog.json index cbb91e4..466ff0b 100644 --- a/changelog.json +++ b/changelog.json @@ -3,10 +3,12 @@ "version": "0.25.6", "date": "", "en": [ - "Right-click: update the US county of the selected contacts from the ULS database, replacing a county since renamed or abolished." + "Right-click: update the US county of the selected contacts from the ULS database, replacing a county since renamed or abolished.", + "A QSO logged from WSJT-X, MSHV or a net now appears in Recent QSOs at once, instead of waiting for a delayed auto-upload to send it." ], "fr": [ - "Clic droit : mettre à jour le comté US des contacts sélectionnés depuis la base ULS, pour remplacer un comté renommé ou supprimé." + "Clic droit : mettre à jour le comté US des contacts sélectionnés depuis la base ULS, pour remplacer un comté renommé ou supprimé.", + "Un QSO logué depuis WSJT-X, MSHV ou un net apparaît aussitôt dans les QSO récents, sans attendre l’envoi d’un upload automatique différé." ] }, { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 9c1e865..a6d3e38 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2227,16 +2227,34 @@ export default function App() { } }, [buildActiveFilter]); - // Refresh the Recent QSOs grid after external-service uploads stamp the - // sent status (auto-upload via extsvc:uploaded, or manual QSL Manager via - // qslmgr:done). Debounced so a batch of per-QSO events triggers one reload. + // Reload the Recent QSOs grid when the log changes. + // + // qso:logged is the important one, and it was missing. The entry form calls + // refresh() itself after AddQSO, so a QSO TYPED here always appeared — but a + // QSO logged from anywhere else (WSJT-X / MSHV over UDP, JTAlert, NET + // Control, an offline replay) only reached the grid when something else + // happened to reload it, and the something else was the upload: with + // auto-upload set to immediate, extsvc:uploaded arrived a second later and + // hid the gap entirely. + // + // Which is why this surfaced as "delayed upload breaks the recent list". It + // does not — the grid was waiting on the upload for its news. On a delayed + // service the QSO appeared one to two minutes late, and on close-of-session + // upload not until the next launch: the corrections that deferring the upload + // exists to allow could not be made, because there was nothing to correct on + // screen. The list follows the LOG now, and the upload only stamps a status. + // + // Debounced: qso:logged fires twice per contact (once on insert, once when + // the award refs are materialised), and a contest run fires it every few + // seconds. useEffect(() => { let t: number | undefined; const ping = () => { if (t) window.clearTimeout(t); t = window.setTimeout(() => { refresh(); }, 400); }; + const offLogged = EventsOn('qso:logged', ping); const offUploaded = EventsOn('extsvc:uploaded', ping); const offDone = EventsOn('qslmgr:done', ping); const offEqsl = EventsOn('qsl:sent', ping); - return () => { offUploaded(); offDone(); offEqsl(); if (t) window.clearTimeout(t); }; + return () => { offLogged(); offUploaded(); offDone(); offEqsl(); if (t) window.clearTimeout(t); }; }, [refresh]); // The backend bulk-recomputed the materialised award_refs (an award definition