"use client"; import { useState } from "react"; import { StreamActionLog } from "yt-dlp-transcript-common/components/StreamActionLog"; import { formatDuration } from "yt-dlp-transcript-common/lib/format"; import { QueueControl } from "../../../../../../components/QueueControl"; import { cancelJobAction } from "../../../../../../jobs/actions"; import { redownloadIncompleteTranscriptAction, } from "../../videoActions"; // `coverage` is null when the transcript is NOT flagged as truncated — the // banner is always rendered and draws nothing in that case, rather than the // parent branching on the condition. The run offered here is the one that // CLEARS the flag, so a parent branch would unmount this component (and the // run's log with it) on the router.refresh() StreamActionLog fires when the run // ends. `ranHere` is what keeps it: once a run has started from this surface // the banner stays on screen with its log, whatever the condition now says. // See plans/FACTS.md, "A run log lives in the panel's React state". export function IncompleteTranscriptBanner({ slug, videoId, coverage, defaultQueueKey, existingQueues, }: { slug: string; videoId: string; coverage: { lastCueEnd: number; duration: number; coverage: number | null; } | null; defaultQueueKey: string; existingQueues: string[]; }) { const [queueKey, setQueueKey] = useState(defaultQueueKey); const [ranHere, setRanHere] = useState(false); if (!coverage && !ranHere) return null; const pct = !coverage || coverage.coverage === null ? null : Math.round(coverage.coverage * 1000) / 10; const actionLabel = `Re-download & re-transcribe ${videoId}`; return (