import type { QueryClient } from "@tanstack/react-query"; import { api, type TakeoutStatus } from "../../lib/api"; import { qk } from "../../lib/queryKeys"; // A Takeout import, watched to its end: its status is asked again until no run is queued or going, // then the lists it changed are read afresh. It lives outside the section on purpose: the user may // leave Settings while the import runs, and the feed they go to must not keep showing as new what // the import has just marked watched. const POLL_MS = 1500; export const importBusy = (s: TakeoutStatus | undefined): boolean => !!s && (s.queued || s.run?.status === "running"); let watching = false; const pause = () => new Promise((done) => setTimeout(done, POLL_MS)); async function read(qc: QueryClient): Promise { try { return await qc.fetchQuery({ queryKey: qk.takeout(), queryFn: api.takeoutStatus, staleTime: 0, }); } catch { // A read that failed is the section's to say (its query holds the error); the watch asks again. return qc.getQueryData(qk.takeout()); } } /** Mark stale everything an import may have changed: the feed and its counts, Watch later, and the * playlists that show its size. */ export function invalidateImported(qc: QueryClient): void { for (const queryKey of [ qk.feed(), qk.feedSummary(), qk.feedYears(), qk.playlist(), qk.playlists(), ]) void qc.invalidateQueries({ queryKey }); } /** Watch the user's import until it is done (once: a second call while it watches is that watch), * then mark stale what it changed. */ export async function watchTakeout(qc: QueryClient): Promise { if (watching) return; watching = true; let status = qc.getQueryData(qk.takeout()); while (importBusy(status)) { await pause(); status = await read(qc); } watching = false; invalidateImported(qc); }