omniasr-transcriptions / frontend /src /components /TranscriptionControls.tsx
jeanma's picture
Omnilingual ASR transcription demo
ae238b3 verified
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;