File size: 5,396 Bytes
ae238b3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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;