"use client" import type { DriveFileInfo } from "@/lib/api/types" import { displayFileName } from "@/lib/drive/display-file-name" import { driveFolderIconMeta, driveMimeCategoryFor, driveMimeIconMeta, } from "@/lib/drive/drive-file-icon" const PREVIEW_WIDTH_PX = 200 const PREVIEW_HEIGHT_PX = 48 const ICON_COLOR_HEX: Record = { "text-amber-500": "#f59e0b", "text-amber-600": "#d97706", "text-blue-500": "#3b82f6", "text-blue-600": "#2563eb", "text-green-600": "#16a34a", "text-red-500": "#ef4444", "text-red-600": "#dc2626", "text-rose-500": "#f43f5e", "text-[#5f6368]": "#5f6368", } let activePreview: HTMLElement | null = null function iconMetaForFile(file: DriveFileInfo) { const category = driveMimeCategoryFor(file) if (category === "folder") return driveFolderIconMeta(file) return driveMimeIconMeta(category) } function iconifySvgUrl(iconId: string, colorHex: string) { const [prefix, name] = iconId.split(":") return `https://api.iconify.design/${prefix}/${name}.svg?width=24&height=24&color=${encodeURIComponent(colorHex)}` } function appendTypeIcon( root: HTMLElement, file: DriveFileInfo, dragSourceEl: HTMLElement | null ) { const iconSlot = document.createElement("span") iconSlot.setAttribute("data-drive-type-icon", "") iconSlot.style.cssText = "display:inline-flex;width:20px;height:20px;flex-shrink:0;align-items:center;justify-content:center;" const cardRoot = dragSourceEl?.closest("[data-drive-card]") ?? dragSourceEl ?? null const liveSvg = cardRoot?.querySelector("[data-drive-type-icon] svg") if (liveSvg) { const svg = liveSvg.cloneNode(true) as SVGElement svg.setAttribute("width", "20") svg.setAttribute("height", "20") svg.style.width = "20px" svg.style.height = "20px" iconSlot.appendChild(svg) } else { const { icon, color } = iconMetaForFile(file) const img = document.createElement("img") img.src = iconifySvgUrl(icon, ICON_COLOR_HEX[color] ?? "#5f6368") img.width = 20 img.height = 20 img.alt = "" img.draggable = false img.style.display = "block" iconSlot.appendChild(img) } root.appendChild(iconSlot) } function buildPreviewElement( files: DriveFileInfo[], dragSourceEl: HTMLElement | null ): HTMLElement { const primary = files[0] const label = files.length === 1 ? displayFileName(primary.name) : `${files.length} élément${files.length > 1 ? "s" : ""}` const root = document.createElement("div") root.style.cssText = [ `width:${PREVIEW_WIDTH_PX}px`, `height:${PREVIEW_HEIGHT_PX}px`, "box-sizing:border-box", "display:flex", "align-items:center", "gap:12px", "padding:0 12px", "border-radius:12px", "border:1px solid rgba(232,234,237,0.8)", "background:#f8f9fa", "box-shadow:0 2px 8px rgba(60,64,67,0.28)", "font-family:system-ui,sans-serif", "font-size:14px", "font-weight:500", "color:#3c4043", "pointer-events:none", ].join(";") appendTypeIcon(root, primary, dragSourceEl) const text = document.createElement("span") text.textContent = label text.style.cssText = "min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;" root.appendChild(text) return root } export function applyDriveDragPreview( dataTransfer: DataTransfer, files: DriveFileInfo[], dragSourceEl: HTMLElement | null ): void { removeDriveDragPreview() if (files.length === 0) return const root = buildPreviewElement(files, dragSourceEl) root.style.position = "fixed" root.style.left = "-9999px" root.style.top = "0" root.style.zIndex = "99999" document.body.appendChild(root) activePreview = root dataTransfer.setDragImage(root, PREVIEW_WIDTH_PX / 2, PREVIEW_HEIGHT_PX / 2) } export function removeDriveDragPreview(): void { activePreview?.remove() activePreview = null }