Files
fusion/packages/dashboard/app/hooks/useStashOrphanCount.ts
gsxdsm f157bf7460 fix(dashboard): harden visibility suspension, log caps, and mobile board UX
Suspend poll/SSE work when the tab is hidden, cap log buffers, restore board scroll more reliably, and improve list windowing/live tickers with related tests and a mobile-tab retention changeset.
2026-07-26 09:50:44 -07:00

48 lines
1.7 KiB
TypeScript

/*
FNXC:StashRecovery 2026-06-24-00:00:
App-level count of orphaned stash-recovery entries, polled every 30s and surfaced as a header/mobile-nav badge. Extracted verbatim from AppInner so the root component no longer owns the polling loop.
*/
import { useCallback, useEffect, useRef, useState } from "react";
import { api } from "../api";
import { useVisibilityAwarePoll } from "./visibilitySuspension";
export interface UseStashOrphanCountResult {
stashOrphanCount: number;
}
const POLL_INTERVAL_MS = 30000;
export function useStashOrphanCount(currentProjectId: string | undefined): UseStashOrphanCountResult {
const [stashOrphanCount, setStashOrphanCount] = useState(0);
const contextVersionRef = useRef(0);
const load = useCallback(async () => {
const versionAtStart = contextVersionRef.current;
try {
const data = await api<{ count: number }>("/stash-recovery/orphans");
if (contextVersionRef.current === versionAtStart) setStashOrphanCount(data.count ?? 0);
} catch {
if (contextVersionRef.current === versionAtStart) setStashOrphanCount(0);
}
}, [currentProjectId]);
useEffect(() => {
void load();
return () => {
contextVersionRef.current += 1;
};
}, [load]);
/*
FNXC:MobileTabRetention 2026-07-26-10:50:
The 30s stash-orphan badge poll is suspended while the document is hidden. A badge count nobody can see is
never worth keeping a backgrounded mobile tab awake — background network work is a primary OS discard
signal and produced the white-splash reload on return. The badge re-counts once when the tab is shown again.
*/
useVisibilityAwarePoll(load, POLL_INTERVAL_MS);
return { stashOrphanCount };
}