import { ref, type Ref, type ComputedRef } from 'vue'; import type { Sprite } from '@/types/sprites'; import { getMaxDimensions } from './useSprites'; export interface FileDropOptions { sprites: Ref | ComputedRef | Sprite[]; onAddSprite: (file: File) => void; onAddSpriteWithResize: (file: File) => void; } export function useFileDrop(options: FileDropOptions) { const { onAddSprite, onAddSpriteWithResize } = options; // Helper to get sprites array const getSprites = () => (Array.isArray(options.sprites) ? options.sprites : options.sprites.value); const isDragOver = ref(false); const handleDragOver = (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); if (event.dataTransfer) { event.dataTransfer.dropEffect = 'copy'; } isDragOver.value = true; }; const handleDragEnter = (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); isDragOver.value = true; }; const handleDragLeave = (event: DragEvent, canvasRef?: HTMLCanvasElement | null) => { event.preventDefault(); event.stopPropagation(); if (canvasRef) { const rect = canvasRef.getBoundingClientRect(); if (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom) { isDragOver.value = false; } } else { isDragOver.value = false; } }; const processDroppedImage = (file: File): Promise => { return new Promise((resolve, reject) => { const img = new Image(); const reader = new FileReader(); reader.onload = e => { if (e.target?.result) { img.src = e.target.result as string; } }; img.onload = () => { const sprites = getSprites(); const { maxWidth, maxHeight } = getMaxDimensions(sprites); // Check if the dropped image is larger than current cells if (img.naturalWidth > maxWidth || img.naturalHeight > maxHeight) { onAddSpriteWithResize(file); } else { onAddSprite(file); } resolve(); }; img.onerror = () => { console.error('Failed to load image:', file.name); reject(new Error('Failed to load image')); }; reader.readAsDataURL(file); }); }; const handleDrop = async (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); isDragOver.value = false; if (!event.dataTransfer?.files || event.dataTransfer.files.length === 0) { return; } const files = Array.from(event.dataTransfer.files).filter(file => file.type.startsWith('image/')); if (files.length === 0) { alert('Please drop image files only.'); return; } // Process each dropped file for (const file of files) { await processDroppedImage(file); } }; return { isDragOver, handleDragOver, handleDragEnter, handleDragLeave, handleDrop, }; }