mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
102 lines
2.2 KiB
TypeScript
102 lines
2.2 KiB
TypeScript
import { useState, useRef } from "react";
|
|
import { hasDragData } from "@/lib/drag-data";
|
|
|
|
interface UseFileUploadOptions {
|
|
accept?: string;
|
|
multiple?: boolean;
|
|
onFilesSelected?: (files: File[]) => void;
|
|
}
|
|
|
|
function containsFiles(dataTransfer: DataTransfer): boolean {
|
|
return !hasDragData({ dataTransfer }) && dataTransfer.types.includes("Files");
|
|
}
|
|
|
|
export function useFileUpload({
|
|
accept,
|
|
multiple,
|
|
onFilesSelected,
|
|
}: UseFileUploadOptions = {}) {
|
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
const dragCounterRef = useRef(0);
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
|
|
function openFilePicker() {
|
|
if (!inputRef.current) return;
|
|
|
|
inputRef.current.accept = accept || "*";
|
|
inputRef.current.multiple = multiple || false;
|
|
inputRef.current.click();
|
|
}
|
|
|
|
function handleFileChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
const files = Array.from(event.target.files ?? []);
|
|
if (files.length > 0 && onFilesSelected) {
|
|
onFilesSelected(files);
|
|
}
|
|
|
|
if (event.target) {
|
|
event.target.value = "";
|
|
}
|
|
}
|
|
|
|
function handleDragEnter(e: React.DragEvent) {
|
|
e.preventDefault();
|
|
|
|
if (!containsFiles(e.dataTransfer)) return;
|
|
|
|
dragCounterRef.current += 1;
|
|
setIsDragOver(true);
|
|
}
|
|
|
|
function handleDragOver(e: React.DragEvent) {
|
|
e.preventDefault();
|
|
|
|
if (!containsFiles(e.dataTransfer)) return;
|
|
}
|
|
|
|
function handleDragLeave(e: React.DragEvent) {
|
|
e.preventDefault();
|
|
|
|
if (!containsFiles(e.dataTransfer)) return;
|
|
|
|
dragCounterRef.current -= 1;
|
|
if (dragCounterRef.current === 0) {
|
|
setIsDragOver(false);
|
|
}
|
|
}
|
|
|
|
function handleDrop(e: React.DragEvent) {
|
|
e.preventDefault();
|
|
setIsDragOver(false);
|
|
dragCounterRef.current = 0;
|
|
|
|
if (onFilesSelected && containsFiles(e.dataTransfer)) {
|
|
const files = Array.from(e.dataTransfer.files);
|
|
const shouldUseMultiple = multiple ?? false;
|
|
|
|
if (shouldUseMultiple) {
|
|
onFilesSelected(files);
|
|
} else if (files.length > 0) {
|
|
onFilesSelected([files[0]]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
isDragOver,
|
|
openFilePicker,
|
|
fileInputProps: {
|
|
ref: inputRef,
|
|
type: "file",
|
|
style: { display: "none" },
|
|
onChange: handleFileChange,
|
|
},
|
|
dragProps: {
|
|
onDragEnter: handleDragEnter,
|
|
onDragOver: handleDragOver,
|
|
onDragLeave: handleDragLeave,
|
|
onDrop: handleDrop,
|
|
},
|
|
};
|
|
}
|