feat(channel): live-refresh the channel page while full-history backfills
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.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
|
import { useLiveQuery } from "../lib/useLiveQuery";
|
||||||
import { qk } from "../lib/queryKeys";
|
import { qk } from "../lib/queryKeys";
|
||||||
import { useNavigationActions } from "./NavigationProvider";
|
import { useNavigationActions } from "./NavigationProvider";
|
||||||
import { PriorityStepper } from "./PriorityStepper";
|
import { PriorityStepper } from "./PriorityStepper";
|
||||||
@@ -79,9 +80,11 @@ export default function ChannelPage({
|
|||||||
const MAX_BANNER_RETRIES = 3;
|
const MAX_BANNER_RETRIES = 3;
|
||||||
const [bannerAttempt, setBannerAttempt] = useState(0);
|
const [bannerAttempt, setBannerAttempt] = useState(0);
|
||||||
|
|
||||||
const detail = useQuery({
|
// A LIVE query: while THIS user's full-history backfill is running, poll so the stored count (and
|
||||||
queryKey: qk.channel(channelId),
|
// the N/S/L breakdown) climb on their own — the scheduler adds videos in ~2-min ticks — then stop
|
||||||
queryFn: () => api.channelDetail(channelId),
|
// polling once the back-catalogue is in. Same queryKey as before, so mutation invalidations still hit.
|
||||||
|
const detail = useLiveQuery(qk.channel(channelId), () => api.channelDetail(channelId), {
|
||||||
|
intervalMs: (d) => (d?.deep_requested && !d.backfill_done ? 4000 : false),
|
||||||
});
|
});
|
||||||
const ch = detail.data;
|
const ch = detail.data;
|
||||||
useEffect(() => setBannerAttempt(0), [ch?.banner_url]); // fresh channel/banner → try again
|
useEffect(() => setBannerAttempt(0), [ch?.banner_url]); // fresh channel/banner → try again
|
||||||
|
|||||||
@@ -9,10 +9,13 @@ export function useLiveQuery<T>(
|
|||||||
key: QueryKey,
|
key: QueryKey,
|
||||||
queryFn: () => Promise<T>,
|
queryFn: () => Promise<T>,
|
||||||
// intervalMs may be a function of the latest data, so the poll cadence can adapt to it
|
// 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). react-query re-evaluates it after each fetch
|
// (e.g. poll faster while a job is running, and return `false` to STOP once it's done).
|
||||||
// against fresh data — the right place for this, vs. a React state toggle that can lag or
|
// react-query re-evaluates it after each fetch against fresh data — the right place for this,
|
||||||
// stall the live updates.
|
// vs. a React state toggle that can lag or stall the live updates.
|
||||||
opts: { intervalMs?: number | ((data: T | undefined) => number); enabled?: boolean } = {},
|
opts: {
|
||||||
|
intervalMs?: number | false | ((data: T | undefined) => number | false);
|
||||||
|
enabled?: boolean;
|
||||||
|
} = {},
|
||||||
) {
|
) {
|
||||||
const { intervalMs = 4000, enabled = true } = opts;
|
const { intervalMs = 4000, enabled = true } = opts;
|
||||||
return useQuery({
|
return useQuery({
|
||||||
|
|||||||
Reference in New Issue
Block a user