Files
investor-flow/app/src/lib/useVisibilityAwarePoll.ts
T

57 lines
1.2 KiB
TypeScript
Raw Normal View History

"use client";
import { useEffect, useRef } from "react";
/**
* Run `tick` on an interval, but pause while the document is hidden
* (background Safari tab / phone locked). Resumes with an immediate tick
* when the page becomes visible again.
*/
export function useVisibilityAwarePoll(
tick: () => void | Promise<void>,
intervalMs: number,
enabled = true,
): void {
const tickRef = useRef(tick);
tickRef.current = tick;
useEffect(() => {
if (!enabled || intervalMs <= 0) return;
let id: ReturnType<typeof setInterval> | null = null;
const run = () => {
void tickRef.current();
};
const start = () => {
if (id != null) return;
id = setInterval(run, intervalMs);
};
const stop = () => {
if (id != null) {
clearInterval(id);
id = null;
}
};
const onVisibility = () => {
if (document.hidden) {
stop();
} else {
run();
start();
}
};
if (!document.hidden) start();
document.addEventListener("visibilitychange", onVisibility);
return () => {
stop();
document.removeEventListener("visibilitychange", onVisibility);
};
}, [intervalMs, enabled]);
}