Spaces:
Running
Running
import React, { useState, useCallback, useRef } from 'react'; | |
import { FileVideo } from './Icons'; | |
interface VideoUploaderProps { | |
onVideoSelect: (file: File) => void; | |
} | |
export const VideoUploader: React.FC<VideoUploaderProps> = ({ onVideoSelect }) => { | |
const [isDragging, setIsDragging] = useState(false); | |
const fileInputRef = useRef<HTMLInputElement>(null); | |
const handleDrag = useCallback((e: React.DragEvent<HTMLDivElement>) => { | |
e.preventDefault(); | |
e.stopPropagation(); | |
}, []); | |
const handleDragIn = useCallback((e: React.DragEvent<HTMLDivElement>) => { | |
e.preventDefault(); | |
e.stopPropagation(); | |
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) { | |
setIsDragging(true); | |
} | |
}, []); | |
const handleDragOut = useCallback((e: React.DragEvent<HTMLDivElement>) => { | |
e.preventDefault(); | |
e.stopPropagation(); | |
setIsDragging(false); | |
}, []); | |
const handleDrop = useCallback((e: React.DragEvent<HTMLDivElement>) => { | |
e.preventDefault(); | |
e.stopPropagation(); | |
setIsDragging(false); | |
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) { | |
onVideoSelect(e.dataTransfer.files[0]); | |
e.dataTransfer.clearData(); | |
} | |
}, [onVideoSelect]); | |
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { | |
if (e.target.files && e.target.files.length > 0) { | |
onVideoSelect(e.target.files[0]); | |
} | |
}; | |
const onButtonClick = () => { | |
fileInputRef.current?.click(); | |
}; | |
return ( | |
<div | |
onDragEnter={handleDragIn} | |
onDragLeave={handleDragOut} | |
onDragOver={handleDrag} | |
onDrop={handleDrop} | |
onClick={onButtonClick} | |
className={`w-full h-full p-4 flex flex-col items-center justify-center border-4 border-dashed rounded-xl transition-all duration-300 cursor-pointer | |
${isDragging ? 'border-indigo-500 bg-slate-700/50' : 'border-slate-600 hover:border-indigo-600 hover:bg-slate-700/30'}`} | |
> | |
<input | |
ref={fileInputRef} | |
type="file" | |
accept="video/*" | |
onChange={handleFileChange} | |
className="hidden" | |
/> | |
<div className="text-center pointer-events-none"> | |
<FileVideo className="w-16 h-16 mx-auto text-slate-500 mb-4" /> | |
<p className="text-lg font-semibold text-slate-300">Drag & Drop Video File</p> | |
<p className="text-slate-400">or click to select a file</p> | |
</div> | |
</div> | |
); | |
}; | |