Files
healer-man/src/ui/useDungeonReports.ts
T
2026-09-12 23:55:24 -04:00

41 lines
1.5 KiB
TypeScript

import { useCallback, useEffect, useRef, useState } from "react";
import { fetchDungeonReports, type DungeonReportSnapshot } from "../app/dungeonReports";
export function useDungeonReports() {
const [snapshot, setSnapshot] = useState<DungeonReportSnapshot | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
const sequence = useRef(0);
const refresh = useCallback(async () => {
const request = ++sequence.current;
setLoading(true);
try {
const next = await fetchDungeonReports();
if (request !== sequence.current) return;
setSnapshot(next);
setError("");
} catch (failure) {
if (request === sequence.current) setError(failure instanceof Error ? failure.message : "Reports could not be loaded.");
} finally {
if (request === sequence.current) setLoading(false);
}
}, []);
useEffect(() => {
const refreshVisible = () => { if (document.visibilityState === "visible") void refresh(); };
void refresh();
const timer = window.setInterval(refreshVisible, 30_000);
window.addEventListener("focus", refreshVisible);
document.addEventListener("visibilitychange", refreshVisible);
return () => {
sequence.current += 1;
window.clearInterval(timer);
window.removeEventListener("focus", refreshVisible);
document.removeEventListener("visibilitychange", refreshVisible);
};
}, [refresh]);
return { snapshot, loading, error, refresh };
}