"use client" import { useCallback, useRef, useState } from "react" import { pathsInMarqueeRect, shouldIgnoreDriveMarqueeStart, type DriveMarqueeRect, } from "@/lib/drive/drive-marquee" import { useDriveUIStore } from "@/lib/stores/drive-ui-store" export function useDriveMarqueeSelection(enabled: boolean) { const selectedPaths = useDriveUIStore((s) => s.selectedPaths) const setSelectedPaths = useDriveUIStore((s) => s.setSelectedPaths) const clearSelection = useDriveUIStore((s) => s.clearSelection) const cardRefs = useRef(new Map()) const dragRef = useRef<{ startX: number startY: number additive: boolean baseSelection: Set } | null>(null) const [marquee, setMarquee] = useState(null) const registerCardRef = useCallback((path: string, el: HTMLDivElement | null) => { if (el) cardRefs.current.set(path, el) else cardRefs.current.delete(path) }, []) const onSurfacePointerDown = useCallback( (e: React.PointerEvent) => { if (!enabled || e.button !== 0) return // Touch scroll on empty surface must not wipe mobile selection. if (e.pointerType === "touch") return const target = e.target as HTMLElement if (shouldIgnoreDriveMarqueeStart(target)) return const additive = e.ctrlKey || e.metaKey || e.shiftKey const baseSelection = additive ? new Set(selectedPaths) : new Set() if (!additive) clearSelection() dragRef.current = { startX: e.clientX, startY: e.clientY, additive, baseSelection, } const update = (clientX: number, clientY: number) => { const state = dragRef.current if (!state) return const left = Math.min(state.startX, clientX) const top = Math.min(state.startY, clientY) const width = Math.abs(clientX - state.startX) const height = Math.abs(clientY - state.startY) const rect = { left, top, width, height } setMarquee(rect) const hit = pathsInMarqueeRect(cardRefs.current, rect) if (state.additive) { setSelectedPaths([...state.baseSelection, ...hit]) } else { setSelectedPaths(hit) } } update(e.clientX, e.clientY) const onMove = (ev: PointerEvent) => update(ev.clientX, ev.clientY) const onUp = () => { dragRef.current = null setMarquee(null) window.removeEventListener("pointermove", onMove) window.removeEventListener("pointerup", onUp) } window.addEventListener("pointermove", onMove) window.addEventListener("pointerup", onUp) }, [clearSelection, enabled, selectedPaths, setSelectedPaths] ) return { registerCardRef, onSurfacePointerDown, marquee } }