"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 (
{coverage ? (
Transcript looks truncated The transcript covers only {formatDuration(coverage.lastCueEnd)} of{" "} {formatDuration(coverage.duration)} {pct !== null ? ` (${pct}%)` : ""}. The audio download likely stopped early. Re-download the audio and re-transcribe to fix it — this deletes the truncated audio first so the full file is fetched.
) : null} { setRanHere(true); return redownloadIncompleteTranscriptAction(slug, videoId, queueKey); }} cancelAction={cancelJobAction} buttonLabel="Re-download & re-transcribe" runningLabel="Re-downloading…" label={actionLabel} extraControls={ } />
); }