import { useCallback, useRef, useState } from 'react' import { DriveInfo } from '@solarpunkltd/file-manager-lib' interface UseDragAndDropProps { onFilesDropped: (files: FileList) => void currentDrive: DriveInfo | null } interface UseDragAndDropReturn { isDragging: boolean handleDragEnter: (e: React.DragEvent) => void handleDragOver: (e: React.DragEvent) => void handleDragLeave: (e: React.DragEvent) => void handleDrop: (e: React.DragEvent) => void handleOverlayDrop: (e: React.DragEvent) => void } export function useDragAndDrop({ onFilesDropped, currentDrive }: UseDragAndDropProps): UseDragAndDropReturn { const [isDragging, setIsDragging] = useState(false) const dragCounter = useRef(0) const hasFilesDT = (dt: DataTransfer | null): boolean => { if (!dt) return false if (dt.types && Array.from(dt.types).includes('Files')) return true if (dt.items && Array.from(dt.items).some(i => i.kind === 'file')) return true return false } const handleDragEnter = useCallback((e: React.DragEvent) => { if (!hasFilesDT(e.dataTransfer)) return e.preventDefault() if (dragCounter.current++ === 0) setIsDragging(true) }, []) const handleDragOver = useCallback((e: React.DragEvent) => { if (!hasFilesDT(e.dataTransfer)) return e.preventDefault() e.dataTransfer.dropEffect = 'copy' }, []) const handleDragLeave = useCallback((e: React.DragEvent) => { if (!hasFilesDT(e.dataTransfer)) return e.preventDefault() dragCounter.current = Math.max(0, dragCounter.current - 1) if (dragCounter.current === 0) setIsDragging(false) }, []) const handleDrop = useCallback( (e: React.DragEvent) => { if (!hasFilesDT(e.dataTransfer)) return e.preventDefault() const droppedFiles = e.dataTransfer?.files ?? null dragCounter.current = 0 setIsDragging(false) if (droppedFiles && droppedFiles.length) { onFilesDropped(droppedFiles) } }, [onFilesDropped], ) const handleOverlayDrop = useCallback( (e: React.DragEvent) => { e.preventDefault() e.stopPropagation() setIsDragging(false) dragCounter.current = 0 const dropped = e.dataTransfer?.files if (dropped && dropped.length) { onFilesDropped(dropped) } }, [onFilesDropped], ) return { isDragging, handleDragEnter, handleDragOver, handleDragLeave, handleDrop, handleOverlayDrop, } }