"use client" import { useCallback, useMemo, useState } from "react" import { toast } from "sonner" import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { DriveMoveDialog, type DriveFolderPickerMode } from "@/components/drive/drive-move-dialog" import { useDriveMutations } from "@/lib/api/hooks/use-drive-queries" import type { DriveFileInfo } from "@/lib/api/types" import { displayFileName } from "@/lib/drive/display-file-name" import { resolveRenameName } from "@/lib/drive/drive-default-name" import { guardDriveMenuPointer, stopDriveMenuBubble } from "@/lib/drive/drive-menu-guard" import { useDriveUIStore } from "@/lib/stores/drive-ui-store" import { DriveNameDialog } from "@/components/drive/drive-name-dialog" import { DRIVE_MENU_SURFACE_CLASS } from "@/components/drive/drive-file-context-menu" import { DriveFileMenuActions } from "@/components/drive/drive-file-menu-actions" import { MoreVertical } from "lucide-react" import { DRIVE_MENU_BTN } from "@/lib/drive/drive-chrome-classes" import { cn } from "@/lib/utils" export function useDriveActionTargets(file: DriveFileInfo, allItems: DriveFileInfo[]) { const selectedPaths = useDriveUIStore((s) => s.selectedPaths) return useMemo(() => { if (selectedPaths.size > 1 && selectedPaths.has(file.path)) { const picked = allItems.filter((item) => selectedPaths.has(item.path)) if (picked.length > 0) return picked } return [file] }, [allItems, file, selectedPaths]) } export function DriveFileMenuButton({ file, allItems, isTrash, allowShare = true, writable = true, hideFavorite = false, mutations: mutationsProp, onDownloadRequest, onOpen, onActiveChange, className, }: { file: DriveFileInfo allItems: DriveFileInfo[] isTrash?: boolean allowShare?: boolean writable?: boolean hideFavorite?: boolean mutations?: ReturnType onDownloadRequest?: () => void onOpen: () => void /** Visual highlight only — does not update global selection or bulk bar. */ onActiveChange?: (active: boolean) => void className?: string }) { const [open, setOpen] = useState(false) const [renameOpen, setRenameOpen] = useState(false) const [folderPickerMode, setFolderPickerMode] = useState(null) const setSharePath = useDriveUIStore((s) => s.setSharePath) const mutationsDefault = useDriveMutations() const mutations = mutationsProp ?? mutationsDefault const targets = useDriveActionTargets(file, allItems) const renameTarget = targets.length === 1 ? targets[0] : null const handleRename = async (input: string) => { const target = targets[0] if (!target) return const newName = resolveRenameName(target, input) if (displayFileName(target.name) === newName) return try { await mutations.rename.mutateAsync({ path: target.path, new_name: newName }) toast.success("Renommé") } catch { toast.error("Impossible de renommer") throw new Error("rename failed") } } const closeDropdown = useCallback(() => { setOpen(false) onActiveChange?.(false) guardDriveMenuPointer() }, [onActiveChange]) const openFolderPicker = (mode: DriveFolderPickerMode) => { closeDropdown() window.setTimeout(() => setFolderPickerMode(mode), 0) } return ( <> { if (!next) setFolderPickerMode(null) }} mode={folderPickerMode ?? "move"} sources={targets} /> { if (next) { setOpen(true) onActiveChange?.(true) return } closeDropdown() }} > e.preventDefault()} onPointerDown={(e) => stopDriveMenuBubble(e)} onClick={(e) => e.stopPropagation()} > { closeDropdown() onOpen() }} onClose={closeDropdown} setSharePath={setSharePath} mutations={mutations} onRenameRequest={() => { closeDropdown() window.setTimeout(() => setRenameOpen(true), 0) }} onMoveRequest={isTrash ? undefined : () => openFolderPicker("move")} onCopyRequest={isTrash ? undefined : () => openFolderPicker("copy")} onDownloadRequest={onDownloadRequest} /> ) }