From 6356d60a66a0f12b704bb1151863e6cb8c79abb5 Mon Sep 17 00:00:00 2001 From: rouggy Date: Mon, 20 Jul 2026 19:02:57 +0200 Subject: [PATCH] fix: Stations-on-air widget lagged minutes (timer reset by dbConn object churn) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 15s poll effect depended on the dbConn OBJECT, which gets a fresh reference on several events — each reset the interval before it fired, so the widget could stay stale for over a minute. Depend on the is-mysql boolean instead, and also refresh ~2s after qso:logged so our own row appears promptly like the ON AIR badge. --- frontend/src/App.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 60c2be6..edbdb48 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -441,13 +441,21 @@ export default function App() { type LiveStation = { operator: string; station: string; freq_hz: number; band: string; mode: string; online: boolean; version: string; age_sec: number }; const [liveStations, setLiveStations] = useState([]); const [showLiveStations, setShowLiveStations] = useState(() => localStorage.getItem('opslog.showLiveStations') === '1'); + // Depend on the BOOLEAN (is-mysql), not the dbConn object: dbConn gets a fresh + // reference on several events, and depending on the object reset the 15s timer + // on every such refresh so it could ~never fire (the widget looked stuck for + // minutes). Also refresh right after we log a QSO so our own row shows without + // waiting for the next tick, like the ON AIR badge. + const liveStationsOn = dbConn?.backend === 'mysql'; useEffect(() => { - if (dbConn?.backend !== 'mysql') { setLiveStations([]); return; } + if (!liveStationsOn) { setLiveStations([]); return; } const load = () => GetLiveStations().then((s) => setLiveStations((s ?? []) as LiveStation[])).catch(() => {}); load(); const id = window.setInterval(load, 15 * 1000); - return () => window.clearInterval(id); - }, [dbConn]); + // Small delay lets the async publishLiveStatus MySQL write land before we read. + const offLogged = EventsOn('qso:logged', () => { window.setTimeout(load, 2000); }); + return () => { window.clearInterval(id); offLogged?.(); }; + }, [liveStationsOn]); // Mode OpsLog shows when the rig reports generic DIG_U/DIG_L. OmniRig // can't tell us if it's FT8 vs FT4 vs RTTY, so the user picks the default // in Preferences > Hardware > CAT interface.