diff --git a/artifacts/tx-os/src/pages/executive-meetings.tsx b/artifacts/tx-os/src/pages/executive-meetings.tsx index 8545432d..b62af10f 100644 --- a/artifacts/tx-os/src/pages/executive-meetings.tsx +++ b/artifacts/tx-os/src/pages/executive-meetings.tsx @@ -726,13 +726,18 @@ function ScheduleSection({ writeJsonToStorage(HIGHLIGHT_STORAGE_KEY, highlightPrefs); }, [highlightPrefs]); - // 60-second tick to recompute the "current" meeting highlight. Refreshing - // less frequently than the minute boundary risks the highlight visibly - // lagging when one meeting ends and another starts. const [nowTick, setNowTick] = useState(() => Date.now()); useEffect(() => { - const id = setInterval(() => setNowTick(Date.now()), 60_000); - return () => clearInterval(id); + let intervalId: ReturnType | null = null; + const msToNextMinute = 60_000 - (Date.now() % 60_000); + const timeoutId = setTimeout(() => { + setNowTick(Date.now()); + intervalId = setInterval(() => setNowTick(Date.now()), 60_000); + }, msToNextMinute); + return () => { + clearTimeout(timeoutId); + if (intervalId) clearInterval(intervalId); + }; }, []); const currentMeetingId = useMemo(