Spaces:
Running
on
A100
Running
on
A100
| import React from "react"; | |
| import {useState, useRef, useCallback} from "react"; | |
| import {useTranscriptionStore} from "../stores/transcriptionStore"; | |
| import { | |
| SUPPORTED_AUDIO_FORMATS, | |
| SUPPORTED_VIDEO_FORMATS, | |
| CODEC_INFO, | |
| } from "../utils/mediaTypes"; | |
| import TranscriptionSideBar from "../components/TranscriptionSideBar"; | |
| import TranscriptionPlayer from "../components/TranscriptionPlayer"; | |
| import MediaRecorder from "../components/MediaRecorder"; | |
| import {useDragAndDrop} from "../hooks/useDragAndDrop"; | |
| import {CloudArrowUpIcon} from "@heroicons/react/24/outline"; | |
| import ErrorBoundary from "../components/ErrorBoundary"; | |
| export default function TranscriptionPage() { | |
| const {isRecording, setFile, stopRecording} = useTranscriptionStore(); | |
| // Sidebar resizing state | |
| const [sidebarWidth, setSidebarWidth] = useState(256); // Default 256px (w-64) | |
| const [isResizing, setIsResizing] = useState(false); | |
| const sidebarRef = useRef<HTMLDivElement>(null); | |
| // Drag and drop functionality | |
| const {isDragActive, dragProps} = useDragAndDrop({ | |
| onFileDropped: setFile, | |
| acceptedTypes: ["audio/*"], | |
| }); | |
| // Handle sidebar resizing | |
| const handleMouseDown = useCallback((e: React.MouseEvent) => { | |
| e.preventDefault(); | |
| setIsResizing(true); | |
| }, []); | |
| const handleMouseMove = useCallback( | |
| (e: MouseEvent) => { | |
| if (!isResizing) return; | |
| const newWidth = Math.max(200, Math.min(600, e.clientX)); // Min 200px, max 600px | |
| setSidebarWidth(newWidth); | |
| }, | |
| [isResizing] | |
| ); | |
| const handleMouseUp = useCallback(() => { | |
| setIsResizing(false); | |
| }, []); | |
| // Add global mouse event listeners | |
| React.useEffect(() => { | |
| if (isResizing) { | |
| document.addEventListener("mousemove", handleMouseMove); | |
| document.addEventListener("mouseup", handleMouseUp); | |
| document.body.style.userSelect = "none"; // Prevent text selection during drag | |
| document.body.style.cursor = "ew-resize"; | |
| } | |
| return () => { | |
| document.removeEventListener("mousemove", handleMouseMove); | |
| document.removeEventListener("mouseup", handleMouseUp); | |
| document.body.style.userSelect = ""; | |
| document.body.style.cursor = ""; | |
| }; | |
| }, [isResizing, handleMouseMove, handleMouseUp]); | |
| return ( | |
| <ErrorBoundary componentName="TranscriptionPage"> | |
| <div className="flex h-screen bg-gray-900 relative" {...dragProps}> | |
| {/* Drag Overlay */} | |
| {isDragActive && ( | |
| <div className="absolute inset-0 bg-blue-900/80 border-4 border-dashed border-blue-400 z-50 flex items-center justify-center"> | |
| <div className="text-center text-white"> | |
| <CloudArrowUpIcon className="w-16 h-16 mx-auto mb-4 text-blue-300" /> | |
| <div className="text-2xl font-semibold mb-2"> | |
| Drop your audio file here | |
| </div> | |
| <div className="text-lg text-blue-200 mb-4"> | |
| Supports audio files only | |
| </div> | |
| {/* Audio formats section */} | |
| <div className="text-center mb-3"> | |
| <div className="text-sm font-medium text-blue-300 mb-1"> | |
| Audio Formats | |
| </div> | |
| <div className="text-xs text-blue-100 opacity-90"> | |
| {SUPPORTED_AUDIO_FORMATS.join(" • ")} | |
| </div> | |
| </div> | |
| {/* Codec info */} | |
| <div className="text-center"> | |
| <div className="text-xs text-blue-200 opacity-75"> | |
| Best with standard codecs:{" "} | |
| {CODEC_INFO.audio.common.slice(0, 2).join(", ")} | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| )} | |
| {/* Sidebar with Resize Handle */} | |
| <div className="relative flex"> | |
| <div | |
| ref={sidebarRef} | |
| className="flex-shrink-0 bg-gray-800 text-white overflow-y-auto" | |
| style={{width: `${sidebarWidth}px`}} | |
| > | |
| <TranscriptionSideBar /> | |
| </div> | |
| {/* Drag Handle */} | |
| <div | |
| className="w-1 bg-gray-600 hover:bg-gray-500 cursor-ew-resize flex-shrink-0 transition-colors duration-150" | |
| onMouseDown={handleMouseDown} | |
| title="Drag to resize sidebar" | |
| /> | |
| </div> | |
| {/* Main Content */} | |
| <ErrorBoundary componentName="TranscriptionPlayer"> | |
| {isRecording ? ( | |
| <div className="flex-1 flex items-center justify-center bg-gray-900"> | |
| <MediaRecorder | |
| onComplete={() => stopRecording()} | |
| onCancel={() => stopRecording()} | |
| /> | |
| </div> | |
| ) : ( | |
| <TranscriptionPlayer /> | |
| )} | |
| </ErrorBoundary> | |
| </div> | |
| </ErrorBoundary> | |
| ); | |
| } | |