1import { useEffect, useEffectEvent, useState } from "react";
2
3export function usePermissionStatus<Id extends string>(
4 check: () => Promise<Record<Id, boolean>>,
5 initialStatus: Record<Id, boolean>,
6 enabled = true,
7) {
8 const [status, setStatus] = useState(initialStatus);
9 const [error, setError] = useState<string | null>(null);
10 const checkLatest = useEffectEvent(check);
11 useEffect(() => {
12 if (!enabled) return;
13 let disposed = false;
14 let checking = false;
15 const refresh = async () => {
16 if (disposed || checking || document.visibilityState === "hidden") return;
17 checking = true;
18 try {
19 const next = await checkLatest();
20 if (!disposed) {
21 setStatus(next);
22 setError(null);
23 }
24 } catch {
25 if (!disposed) setError("Could not check permissions. We'll try again automatically.");
26 }
27 checking = false;
28 };
29 void refresh();
30 const timer = window.setInterval(() => void refresh(), 1500);
31 window.addEventListener("focus", refresh);
32 document.addEventListener("visibilitychange", refresh);
33 return () => {
34 disposed = true;
35 window.clearInterval(timer);
36 window.removeEventListener("focus", refresh);
37 document.removeEventListener("visibilitychange", refresh);
38 };
39 }, [enabled]);
40 return {
41 status,
42 error,
43 isReady: (required: readonly Id[]) => error === null && required.every((id) => status[id]),
44 };
45}