From 582fa561b2863a3b8b5006b6b2792223d22bc216 Mon Sep 17 00:00:00 2001 From: rouggy Date: Sat, 29 Aug 2026 16:31:38 +0200 Subject: [PATCH] fix(rec): a fresh take starts its clock at zero, not at the last take's total MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two effects, wrong order: the ticking effect ran before the reset effect on a new take, so its closure captured the PREVIOUS take's elapsed as its starting point — the counter showed 0 for one second and then jumped back to thirty minutes. Effects run in declaration order; the reset now comes first. --- changelog.json | 6 ++++-- frontend/src/App.tsx | 10 +++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/changelog.json b/changelog.json index e172041..c9a617a 100644 --- a/changelog.json +++ b/changelog.json @@ -13,7 +13,8 @@ "Icom network audio: the right codec is requested (16-bit mono LPCM), settled by experiment on a real IC-7760.", "CAT settings: reopening the panel now shows the radio that is actually selected — it always showed the first one, with the fields (MY_RIG included) silently editing the wrong entry.", "IC-7760: the power meter is calibrated against the radio (100 W reads 100 W on the 250 W face) and the RF power setting reads in watts, not a percentage.", - "Icom network audio: toggling Listening off and on no longer chops the sound — the monitor restarts as network-fed instead of also opening a USB capture." + "Icom network audio: toggling Listening off and on no longer chops the sound — the monitor restarts as network-fed instead of also opening a USB capture.", + "QSO recorder: starting a fresh manual take resets the counter for good — it used to flash 0 and jump back to the previous take’s elapsed time." ], "fr": [ "Console Elecraft : le S-mètre est calibré sur un vrai K3 — S9 et les +dB correspondent désormais à l’affichage de la radio (il lisait environ deux points S trop bas).", @@ -26,7 +27,8 @@ "Audio réseau Icom : le bon codec est demandé (LPCM mono 16 bits), déterminé par l’expérience sur un vrai IC-7760.", "Réglages CAT : rouvrir le panneau montre désormais la radio réellement sélectionnée — il montrait toujours la première, et les champs (MY_RIG compris) modifiaient silencieusement la mauvaise entrée.", "IC-7760 : le wattmètre est calibré sur la radio (100 W affiche 100 W sur l’échelle 250 W) et le réglage RF power se lit en watts, plus en pourcentage.", - "Audio réseau Icom : couper puis relancer Listening ne hache plus le son — le moniteur redémarre alimenté par le réseau au lieu d’ouvrir en plus une capture USB." + "Audio réseau Icom : couper puis relancer Listening ne hache plus le son — le moniteur redémarre alimenté par le réseau au lieu d’ouvrir en plus une capture USB.", + "Enregistreur de QSO : démarrer une nouvelle prise manuelle remet le compteur à zéro pour de bon — il affichait 0 puis resautait au temps de la prise précédente." ] }, { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 93a64ae..d6733b5 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1051,6 +1051,13 @@ export default function App() { if (!active) setError(t('rec.manualFailed')); }).catch((e: any) => setError(String(e?.message ?? e))); }; + // recTick means "a fresh take" — that is the only case where the clock returns + // to zero, as opposed to resuming after a stop. Declared BEFORE the ticking + // effect below and deliberately so: effects run in declaration order, and the + // other way round the ticker captured the PREVIOUS take's elapsed as its + // starting point — the counter showed 0 for one second, then jumped straight + // back to the old thirty minutes. + useEffect(() => { setRecSeconds(0); recSecondsRef.current = 0; setRecStopped(false); }, [recTick]); useEffect(() => { if (!recording) { setRecSeconds(0); return; } // A stopped take freezes the clock where it is: it must show the length of @@ -1061,9 +1068,6 @@ export default function App() { const id = window.setInterval(() => setRecSeconds(from + Math.floor((Date.now() - start) / 1000)), 1000); return () => window.clearInterval(id); }, [recording, recTick, recStopped]); - // recTick means "a fresh take" — that is the only case where the clock returns - // to zero, as opposed to resuming after a stop. - useEffect(() => { setRecSeconds(0); recSecondsRef.current = 0; setRecStopped(false); }, [recTick]); // The callsign the in-progress recording belongs to (uppercased; '' = none). // Lets us restart from zero when the operator edits the call to a different // station mid-recording, instead of continuing the old take.