"use client"; import Link from "next/link"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "yt-dlp-transcript-common/components/ui/collapsible"; import { HoverCard, HoverCardContent, HoverCardTrigger, } from "yt-dlp-transcript-common/components/ui/hover-card"; import type { Siding } from "yt-dlp-transcript-common/views/pipeline/channelFlow"; // How many sidings stay visible before the rest collapse. The tail of the // pipeline can legitimately carry six at once (digest blocked + deferred + // warnings, backfill missing-input + deferred + blocked), and six lines of // muted text under one gap stops being a footnote and starts being the page. const VISIBLE_SIDINGS = 2; // SIDINGS — everything that has LEFT the line. // // Deliberately recessive: muted-foreground, 11px, hanging BELOW the rule while // reachable work sits on it. That is not decoration. `missingInput`, `deferred`, // `blocked`, `excludedFromDownload` and `untranscribable` must never be added to // a gap's reachable count — on the measured corpus missingInput alone is 91× // larger, and four surfaces once summed them into one "remaining" figure that // put every channel permanently at the top of every list. Rendering them on a // different axis is what makes the layout itself unable to sum them. // // The hover card carries the sentence nobody remembers: what "deferred" is // waiting for, what a "blocked" video is blocked ON. Those come from the // registry (kind.deferredHint, dependsOn → operationLabel), resolved on the // server, because OPERATION_BY_ID reads the filesystem. export function SidingList({ slug, sidings, }: { slug: string; sidings: Siding[]; }) { if (sidings.length === 0) return null; const head = sidings.slice(0, VISIBLE_SIDINGS); const tail = sidings.slice(VISIBLE_SIDINGS); return (
{s.count.toLocaleString()} {s.label}
{s.hint}