diff --git a/frontend/src/components/PasteTranscriptDialog.tsx b/frontend/src/components/PasteTranscriptDialog.tsx new file mode 100644 index 0000000..6619836 --- /dev/null +++ b/frontend/src/components/PasteTranscriptDialog.tsx @@ -0,0 +1,132 @@ +import { useState, useEffect, useRef } from 'react'; +import { X } from 'lucide-react'; +import { useEditorStore } from '../store/editorStore'; +import { diffTranscript, groupContiguousIndices } from '../utils/diffTranscript'; +import { buildDeletedSet } from '../utils/buildDeletedSet'; + +interface Props { + onClose: () => void; +} + +interface Preview { + deletedCount: number; + rangeCount: number; + totalActive: number; +} + +export default function PasteTranscriptDialog({ onClose }: Props) { + const words = useEditorStore((s) => s.words); + const deletedRanges = useEditorStore((s) => s.deletedRanges); + const applyPastedTranscript = useEditorStore((s) => s.applyPastedTranscript); + + const [pastedText, setPastedText] = useState(''); + const [preview, setPreview] = useState(null); + const debounceRef = useRef | null>(null); + + useEffect(() => { + if (debounceRef.current) clearTimeout(debounceRef.current); + + if (pastedText.trim() === '') { + setPreview(null); + return; + } + + debounceRef.current = setTimeout(() => { + const alreadyDeletedSet = buildDeletedSet(deletedRanges); + const totalActive = words.length - alreadyDeletedSet.size; + const deletedIndices = diffTranscript(words, pastedText, alreadyDeletedSet); + const rangeCount = groupContiguousIndices(deletedIndices).length; + setPreview({ deletedCount: deletedIndices.length, rangeCount, totalActive }); + }, 300); + + return () => { + if (debounceRef.current) clearTimeout(debounceRef.current); + }; + }, [pastedText, words, deletedRanges]); + + const handleApply = () => { + applyPastedTranscript(pastedText); + onClose(); + }; + + const handleBackdropClick = (e: React.MouseEvent) => { + if (e.target === e.currentTarget) onClose(); + }; + + const allDeleted = preview !== null && preview.deletedCount === preview.totalActive; + const noChanges = preview !== null && preview.deletedCount === 0; + const percent = preview !== null && preview.totalActive > 0 + ? Math.round((preview.deletedCount / preview.totalActive) * 100) + : 0; + + return ( +
+
+
+

Paste Edited Transcript

+ +
+ +

+ Paste your edited transcript below. Deleted words will be cut automatically. + Modified words are ignored — only deletions are detected. +

+ +