This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657import { useEffect, useRef } from 'react';
export const REFRESH_INTERVAL_MS = 120_000;export const MAX_REFRESH_BACKOFF_MS = 15 * 60_000;
export function useAutomaticRefresh(enabled: boolean, refresh: () => Promise<boolean>, busy: boolean) { const refreshRef = useRef(refresh); const busyRef = useRef(busy); refreshRef.current = refresh; busyRef.current = busy;
useEffect(() => { if (!enabled) return; let disposed = false; let inFlight = false; let delay = REFRESH_INTERVAL_MS; let nextDue = Date.now() + delay; let timer: ReturnType<typeof setTimeout>; const schedule = () => { clearTimeout(timer); if (!disposed) timer = setTimeout(tick, Math.max(1000, nextDue - Date.now())); }; const tick = async () => { if (disposed) return; if (document.visibilityState === 'hidden' || !navigator.onLine || busyRef.current || inFlight) { nextDue = Date.now() + REFRESH_INTERVAL_MS; schedule(); return; } if (Date.now() < nextDue) { schedule(); return; } inFlight = true; try { const success = await refreshRef.current(); delay = success ? REFRESH_INTERVAL_MS : Math.min(delay * 2, MAX_REFRESH_BACKOFF_MS); } catch { delay = Math.min(delay * 2, MAX_REFRESH_BACKOFF_MS); } finally { inFlight = false; nextDue = Date.now() + delay; schedule(); } }; const onVisible = () => { if (document.visibilityState === 'visible' && navigator.onLine && Date.now() >= nextDue) void tick(); }; schedule(); document.addEventListener('visibilitychange', onVisible); window.addEventListener('online', onVisible); return () => { disposed = true; clearTimeout(timer); document.removeEventListener('visibilitychange', onVisible); window.removeEventListener('online', onVisible); }; }, [enabled]);}