typescript
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { MutableRefObject, useEffect } from 'react';
|
||||
|
||||
interface DropOverlayState {
|
||||
active: boolean;
|
||||
folderName: string | null;
|
||||
}
|
||||
|
||||
interface UseFileDropOptions {
|
||||
shellRef: MutableRefObject<HTMLElement | null>;
|
||||
token?: string | null;
|
||||
currentFolderName: string | null;
|
||||
selectedFolder: string | null;
|
||||
handleFileDrop: (dataTransfer: DataTransfer, folderId: string | null) => Promise<void>;
|
||||
hasFiles: (event: DragEvent) => boolean;
|
||||
defaultFolderName: string;
|
||||
dragCounterRef: MutableRefObject<number>;
|
||||
setDropOverlayState: (updater: ((prev: DropOverlayState) => DropOverlayState) | DropOverlayState) => void;
|
||||
}
|
||||
|
||||
const useFileDrop = ({
|
||||
shellRef,
|
||||
token,
|
||||
currentFolderName,
|
||||
selectedFolder,
|
||||
handleFileDrop,
|
||||
hasFiles,
|
||||
defaultFolderName,
|
||||
dragCounterRef,
|
||||
setDropOverlayState,
|
||||
}: UseFileDropOptions) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (!token) {
|
||||
setDropOverlayState((prev) => ({ ...prev, active: false }));
|
||||
dragCounterRef.current = 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const handleDragEnter = (event: DragEvent) => {
|
||||
if (!hasFiles(event)) return;
|
||||
event.preventDefault();
|
||||
dragCounterRef.current += 1;
|
||||
setDropOverlayState({ active: true, folderName: currentFolderName });
|
||||
};
|
||||
|
||||
const handleDragOver = (event: DragEvent) => {
|
||||
if (!hasFiles(event)) return;
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
};
|
||||
|
||||
const handleDragLeave = (event: DragEvent) => {
|
||||
if (!hasFiles(event)) return;
|
||||
dragCounterRef.current = Math.max(0, dragCounterRef.current - 1);
|
||||
if (dragCounterRef.current === 0) {
|
||||
setDropOverlayState((prev) => ({ ...prev, active: false }));
|
||||
}
|
||||
};
|
||||
|
||||
const handleDrop = async (event: DragEvent) => {
|
||||
if (!hasFiles(event)) return;
|
||||
event.preventDefault();
|
||||
dragCounterRef.current = 0;
|
||||
setDropOverlayState((prev) => ({ ...prev, active: false }));
|
||||
await handleFileDrop(event.dataTransfer, selectedFolder);
|
||||
};
|
||||
|
||||
const dropTarget = shellRef.current;
|
||||
if (!dropTarget) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dropTarget.addEventListener('dragenter', handleDragEnter);
|
||||
dropTarget.addEventListener('dragover', handleDragOver);
|
||||
dropTarget.addEventListener('dragleave', handleDragLeave);
|
||||
dropTarget.addEventListener('drop', handleDrop);
|
||||
|
||||
return () => {
|
||||
dropTarget.removeEventListener('dragenter', handleDragEnter);
|
||||
dropTarget.removeEventListener('dragover', handleDragOver);
|
||||
dropTarget.removeEventListener('dragleave', handleDragLeave);
|
||||
dropTarget.removeEventListener('drop', handleDrop);
|
||||
dragCounterRef.current = 0;
|
||||
setDropOverlayState((prev) => ({ ...prev, active: false }));
|
||||
};
|
||||
}, [
|
||||
token,
|
||||
handleFileDrop,
|
||||
currentFolderName,
|
||||
defaultFolderName,
|
||||
selectedFolder,
|
||||
hasFiles,
|
||||
shellRef,
|
||||
dragCounterRef,
|
||||
setDropOverlayState,
|
||||
]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default useFileDrop;
|
||||
Reference in New Issue
Block a user