g1t/apps/web/app/lib/refresh.ts

23 lines964 bytesCodeBlame
1import { useEffect } from "react";
2import { useNavigation, useRevalidator } from "react-router";
3
4/** How often a page with something moving asks again. */
5export const REFRESH_MS = 4000;
6
7/**
8 * Revalidates the page every `everyMs` while `on` and the tab is visible.
9 * Never while a navigation is pending: a revalidation then restarts the
10 * navigation, aborting its loaders, so a click to a page slower than the
11 * interval would never arrive. Never on top of a revalidation still going.
12 */
13export function useRefreshWhile(on: boolean, everyMs = REFRESH_MS) {
14 const revalidator = useRevalidator();
15 const navigating = useNavigation().state !== "idle";
16 useEffect(() => {
17 if (!on || navigating) return;
18 const timer = setInterval(() => {
19 if (document.visibilityState === "visible" && revalidator.state === "idle") revalidator.revalidate();
20 }, everyMs);
21 return () => clearInterval(timer);
22 }, [on, navigating, everyMs, revalidator]);
23}