import { useMemo } from "react"; import type { Transcript } from "@/api/types"; type Sentence = Transcript["paragraphs"][number]["sentences"][number]; interface TranscriptPlaybackState { /** The sentence currently being spoken, or null if between sentences */ activeSentence: Sentence | null; /** Index of the active word within the transcript's flat words array */ activeWordIndex: number | null; } export function useTranscriptPlayback( transcript: Transcript | undefined, currentTime: number, ): TranscriptPlaybackState { return useMemo(() => { if (!transcript) return { activeSentence: null, activeWordIndex: null }; // Find the active sentence across all paragraphs let activeSentence: Sentence | null = null; for (const paragraph of transcript.paragraphs) { const sentence = paragraph.sentences.find( (s) => currentTime >= s.start && currentTime <= s.end, ); if (sentence) { activeSentence = sentence; break; } } // Binary search for active word const words = transcript.words; let activeWordIndex: number | null = null; let lo = 0; let hi = words.length - 1; while (lo <= hi) { const mid = (lo + hi) >>> 1; if (currentTime < words[mid].start) hi = mid - 1; else if (currentTime > words[mid].end) lo = mid + 1; else { activeWordIndex = mid; break; } } return { activeSentence, activeWordIndex }; }, [transcript, currentTime]); }