import type { ChannelFlow } from "yt-dlp-transcript-common/views/pipeline/channelFlow"; import { InlineActionButton } from "../../../../components/actions/InlineActionButton"; import type { StageId } from "yt-dlp-transcript-common/views/pipeline/stageStatus"; // THE ONE PRIMARY ACTION, and the only brand-coloured thing on the page. // // It renders NOTHING when the channel is idle and clean. A control that is // always there and usually does nothing teaches you to stop reading it; the // absence is the signal that there is nothing to do. // // The variants are the ones InlineActionButton already binds to real server // actions, so this is a router, not a new dispatch path. // Deliberately no `refreshReport` entry: NoReportYet already carries that // button at the top of an unreported channel, and two controls with the same // accessible name is one affordance too many (and one locator match too many). const VARIANT_FOR: Partial< Record< StageId, "downloadMissing" | "transcribeMissing" | "digestChannel" | "backfillChannel" > > = { download: "downloadMissing", transcribe: "transcribeMissing", digest: "digestChannel", speakers: "backfillChannel", }; export function NextAction({ flow, slug, }: { flow: ChannelFlow; slug: string; }) { const next = flow.next; if (!next) return null; const kind = VARIANT_FOR[next.stage]; if (!kind) return null; return (
{next.count > 0 && (

{next.count.toLocaleString()} {" "} {/* Furthest upstream, not biggest — see pickNext. */} waiting at the front of the line.

)}
); }