Spaces:
Running
on
A100
Running
on
A100
| import React, { useState, useEffect } from 'react'; | |
| import { useTranscriptionStore } from '../stores/transcriptionStore'; | |
| import LanguageSelector from './LanguageSelector'; | |
| import TranscriptionWarningModal from './TranscriptionWarningModal'; | |
| import { checkTranscriptionWarnings, getMediaDuration, WARNING_MESSAGES } from '../utils/transcriptionWarnings'; | |
| type WarningType = keyof typeof WARNING_MESSAGES; | |
| const TranscriptionControls: React.FC = () => { | |
| const { | |
| file, | |
| transcription, | |
| isLoading, | |
| isProcessingVideo, | |
| error, | |
| serverStatus, | |
| selectedLanguage, | |
| selectedScript, | |
| handleTranscribe, | |
| setSelectedLanguageAndScript, | |
| } = useTranscriptionStore(); | |
| const [showWarningModal, setShowWarningModal] = useState(false); | |
| const [warnings, setWarnings] = useState<WarningType[]>([]); | |
| const [mediaDuration, setMediaDuration] = useState<number | undefined>(undefined); | |
| // Get media duration when file changes | |
| useEffect(() => { | |
| if (file) { | |
| getMediaDuration(file) | |
| .then(duration => { | |
| setMediaDuration(duration); | |
| }) | |
| .catch(error => { | |
| console.warn('Could not get media duration:', error); | |
| setMediaDuration(undefined); | |
| }); | |
| } else { | |
| setMediaDuration(undefined); | |
| } | |
| }, [file]); | |
| // Handle transcribe button click with warning check | |
| const handleTranscribeClick = async () => { | |
| if (!file) return; | |
| // Check for warnings | |
| const detectedWarnings = checkTranscriptionWarnings({ | |
| file, | |
| duration: mediaDuration, | |
| }); | |
| if (detectedWarnings.length > 0) { | |
| setWarnings(detectedWarnings); | |
| setShowWarningModal(true); | |
| } else { | |
| // No warnings, proceed directly | |
| await handleTranscribe(); | |
| } | |
| }; | |
| // Handle warning modal acceptance | |
| const handleWarningAccept = async () => { | |
| setShowWarningModal(false); | |
| await handleTranscribe(); | |
| }; | |
| // Handle warning modal cancellation | |
| const handleWarningCancel = () => { | |
| setShowWarningModal(false); | |
| setWarnings([]); | |
| }; | |
| // Only show controls if file exists but no transcription yet | |
| if (!file || transcription) { | |
| return null; | |
| } | |
| return ( | |
| <> | |
| <div className="bg-gray-800 border-t border-gray-700 p-4"> | |
| <div className="max-w-4xl mx-auto"> | |
| {/* Error Display */} | |
| {error && ( | |
| <div className="mb-4 p-3 bg-red-600 rounded-lg"> | |
| <div className="text-sm font-medium text-white">Error</div> | |
| <div className="text-sm text-red-100">{error}</div> | |
| </div> | |
| )} | |
| {/* Controls Container */} | |
| <div className="flex flex-col sm:flex-row items-center justify-center gap-4"> | |
| {/* Language Selection */} | |
| <div className="flex flex-col items-center"> | |
| <div className="tooltip tooltip-bottom" data-tip="Select the primary language spoken in your audio/video file. This helps the AI model optimize its transcription accuracy by using language-specific acoustic models and vocabulary. Choosing the correct language significantly improves transcription quality and word recognition."> | |
| <label className="text-sm font-medium text-gray-300 mb-2 cursor-help"> | |
| Transcription Language <span className="text-red-400">*</span> | |
| </label> | |
| </div> | |
| <div className="w-80"> | |
| <LanguageSelector | |
| selectedLanguage={selectedLanguage} | |
| selectedScript={selectedScript} | |
| onLanguageAndScriptSelect={setSelectedLanguageAndScript} | |
| disabled={isLoading || serverStatus?.is_busy} | |
| /> | |
| </div> | |
| </div> | |
| {/* Transcribe Button */} | |
| <div className="flex flex-col items-center"> | |
| <label className="text-sm font-medium text-gray-300 mb-2"> | |
| {serverStatus?.is_busy ? ( | |
| <span className="text-orange-400">Server is processing a request</span> | |
| ) : ( | |
| <span className="opacity-0">Action</span> | |
| )} | |
| </label> | |
| <div className={!selectedLanguage ? "tooltip tooltip-bottom" : ""} data-tip={!selectedLanguage ? "Please select a transcription language to continue" : ""}> | |
| <button | |
| onClick={handleTranscribeClick} | |
| disabled={isLoading || serverStatus?.is_busy || !selectedLanguage} | |
| className="px-8 py-3 bg-green-600 hover:bg-green-700 disabled:bg-gray-600 rounded-lg text-sm font-medium transition-colors text-white min-w-32" | |
| > | |
| {isLoading | |
| ? isProcessingVideo | |
| ? "Processing..." | |
| : "Transcribing..." | |
| : serverStatus?.is_busy | |
| ? "Server Busy" | |
| : !selectedLanguage | |
| ? "Select Language" | |
| : "Transcribe"} | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Warning Modal */} | |
| <TranscriptionWarningModal | |
| isOpen={showWarningModal} | |
| warnings={warnings} | |
| onAccept={handleWarningAccept} | |
| onCancel={handleWarningCancel} | |
| /> | |
| </> | |
| ); | |
| }; | |
| export default TranscriptionControls; | |