The channel detail page now polls (via useLiveQuery) while THIS user's full-history backfill is running (deep_requested && !backfill_done), so the stored count and the N/S/L breakdown climb on their own as the scheduler adds videos — no manual F5 — and it stops polling once the back-catalogue is in. Widen useLiveQuery's interval callback to allow returning `false` (stop) so "poll while active, stop when done" is a first-class, reusable cadence.
34 lines
1.4 KiB
TypeScript
34 lines
1.4 KiB
TypeScript
import { useQuery, type QueryKey } from "@tanstack/react-query";
|
|
|
|
// Reusable "live" polling query: a thin wrapper over react-query that refetches on an
|
|
// interval and — by leaving refetchIntervalInBackground at its default false — pauses while
|
|
// the tab is unfocused, so it doesn't poll a server nobody's watching. This is the shared
|
|
// live-progress mechanism: the Scheduler dashboard uses it now; the notification bell and the
|
|
// future yt-dlp job queue reuse it rather than each re-implementing polling.
|
|
export function useLiveQuery<T>(
|
|
key: QueryKey,
|
|
queryFn: () => Promise<T>,
|
|
// intervalMs may be a function of the latest data, so the poll cadence can adapt to it
|
|
// (e.g. poll faster while a job is running, and return `false` to STOP once it's done).
|
|
// react-query re-evaluates it after each fetch against fresh data — the right place for this,
|
|
// vs. a React state toggle that can lag or stall the live updates.
|
|
opts: {
|
|
intervalMs?: number | false | ((data: T | undefined) => number | false);
|
|
enabled?: boolean;
|
|
} = {},
|
|
) {
|
|
const { intervalMs = 4000, enabled = true } = opts;
|
|
return useQuery({
|
|
queryKey: key,
|
|
queryFn,
|
|
enabled,
|
|
refetchInterval: !enabled
|
|
? false
|
|
: typeof intervalMs === "function"
|
|
? (query) => intervalMs(query.state.data as T | undefined)
|
|
: intervalMs,
|
|
refetchIntervalInBackground: false,
|
|
staleTime: 0,
|
|
});
|
|
}
|