Spaces:
Running
on
A100
Running
on
A100
| import React, {useRef, useState} from "react"; | |
| import {useTranscriptionStore} from "../stores/transcriptionStore"; | |
| import ServerStatusIndicator from "./ServerStatusIndicator"; | |
| import FeedbackCard from "./FeedbackCard"; | |
| import TipsNotice from "./TipsNotice"; | |
| import QuickGuide from "./QuickGuide"; | |
| import { | |
| TOSModalComponent, | |
| AUPModalComponent, | |
| ModelReadmeModalComponent, | |
| } from "./TermsModal"; | |
| const TranscriptionSideBar: React.FC = () => { | |
| const fileInputRef = useRef<HTMLInputElement>(null); | |
| const [isTOSModalOpen, setIsTOSModalOpen] = useState(false); | |
| const [isAUPModalOpen, setIsAUPModalOpen] = useState(false); | |
| const [isModelReadmeModalOpen, setIsModelReadmeModalOpen] = useState(false); | |
| const { | |
| file, | |
| transcription, | |
| error, | |
| isRecording, | |
| handleFileSelect, | |
| startRecording, | |
| } = useTranscriptionStore(); | |
| const handleFileInputChange = ( | |
| event: React.ChangeEvent<HTMLInputElement> | |
| ) => { | |
| const selectedFile = event.target.files?.[0]; | |
| if (selectedFile) { | |
| handleFileSelect(selectedFile); | |
| } | |
| }; | |
| return ( | |
| <div className="h-full p-4 overflow-y-auto"> | |
| <h2 className="text-lg font-bold mb-4"> | |
| Omnilingual ASR Media Transcription | |
| </h2> | |
| {/* Server Status Indicator */} | |
| <div className="mb-4 p-3 bg-gray-900 rounded-lg border border-gray-600"> | |
| <ServerStatusIndicator /> | |
| </div> | |
| {/* File Upload */} | |
| <div className="mb-4"> | |
| <h3 className="text-sm font-semibold mb-2">Upload Media</h3> | |
| <input | |
| ref={fileInputRef} | |
| type="file" | |
| accept="audio/*" | |
| onChange={handleFileInputChange} | |
| className="hidden" | |
| /> | |
| {!isRecording && ( | |
| <> | |
| <button | |
| onClick={() => fileInputRef.current?.click()} | |
| className="w-full p-2 bg-blue-600 hover:bg-blue-700 rounded text-sm transition-colors mb-2 flex items-center justify-center gap-2" | |
| > | |
| <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"> | |
| <path | |
| fillRule="evenodd" | |
| d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" | |
| clipRule="evenodd" | |
| /> | |
| </svg> | |
| {file ? "Choose Different File" : "Choose File"} | |
| </button> | |
| {/* Recording Buttons */} | |
| <div className="space-y-2"> | |
| <button | |
| onClick={() => startRecording("audio")} | |
| className="w-full p-2 bg-red-700 hover:bg-red-800 rounded text-sm transition-colors flex items-center justify-center gap-2" | |
| > | |
| <svg | |
| className="w-4 h-4" | |
| fill="currentColor" | |
| viewBox="0 0 20 20" | |
| > | |
| <path | |
| fillRule="evenodd" | |
| d="M7 4a3 3 0 016 0v4a3 3 0 11-6 0V4zm4 10.93A7.001 7.001 0 0017 8a1 1 0 10-2 0A5 5 0 015 8a1 1 0 00-2 0 7.001 7.001 0 006 6.93V17H6a1 1 0 100 2h8a1 1 0 100-2h-3v-2.07z" | |
| clipRule="evenodd" | |
| /> | |
| </svg> | |
| Record Audio | |
| </button> | |
| {/* <button | |
| onClick={() => startRecording("video")} | |
| className="w-full p-2 bg-red-700 hover:bg-red-800 rounded text-sm transition-colors flex items-center justify-center gap-2" | |
| > | |
| <svg | |
| className="w-4 h-4" | |
| fill="currentColor" | |
| viewBox="0 0 20 20" | |
| > | |
| <path d="M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z" /> | |
| </svg> | |
| Record Video | |
| </button> */} | |
| </div> | |
| </> | |
| )} | |
| {file && !isRecording && ( | |
| <div className="mt-2 p-2 bg-gray-700 rounded"> | |
| <div className="text-xs font-medium truncate">{file.name}</div> | |
| <div className="text-xs text-gray-400"> | |
| {(file.size / 1024 / 1024).toFixed(1)} MB | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| {/* Error Display */} | |
| {error && transcription && ( | |
| <div className="mb-4 p-2 bg-red-600 rounded"> | |
| <div className="text-xs font-medium">Error</div> | |
| <div className="text-xs">{error}</div> | |
| </div> | |
| )} | |
| <QuickGuide /> | |
| <TipsNotice /> | |
| <FeedbackCard /> | |
| {/* Terms and Policy Buttons */} | |
| <div className="mt-4 space-y-2"> | |
| <button | |
| onClick={() => setIsTOSModalOpen(true)} | |
| className="w-full p-2 bg-green-200 hover:bg-green-300 text-gray-800 rounded text-sm transition-colors" | |
| > | |
| Terms of Service | |
| </button> | |
| <button | |
| onClick={() => setIsAUPModalOpen(true)} | |
| className="w-full p-2 bg-green-200 hover:bg-green-300 text-gray-800 rounded text-sm transition-colors" | |
| > | |
| Acceptable Use Policy | |
| </button> | |
| <button | |
| onClick={() => setIsModelReadmeModalOpen(true)} | |
| className="w-full p-2 bg-green-200 hover:bg-green-300 text-gray-800 rounded text-sm transition-colors" | |
| > | |
| Model Readme | |
| </button> | |
| </div> | |
| {/* Modals */} | |
| <TOSModalComponent | |
| isOpen={isTOSModalOpen} | |
| onClose={() => setIsTOSModalOpen(false)} | |
| /> | |
| <AUPModalComponent | |
| isOpen={isAUPModalOpen} | |
| onClose={() => setIsAUPModalOpen(false)} | |
| /> | |
| <ModelReadmeModalComponent | |
| isOpen={isModelReadmeModalOpen} | |
| onClose={() => setIsModelReadmeModalOpen(false)} | |
| /> | |
| </div> | |
| ); | |
| }; | |
| export default TranscriptionSideBar; | |