"use client"; import { AspectRatio } from "@/components/ui/aspect-ratio"; import { Button } from "@/components/ui/button"; import { ReactNode, useState, useRef, useEffect } from "react"; import { createPortal } from "react-dom"; import { Plus } from "lucide-react"; import { cn } from "@/lib/utils"; export interface DraggableMediaItemProps { name: string; preview: ReactNode; dragData: Record; onDragStart?: (e: React.DragEvent) => void; aspectRatio?: number; className?: string; showPlusOnDrag?: boolean; showLabel?: boolean; rounded?: boolean; } export function DraggableMediaItem({ name, preview, dragData, onDragStart, aspectRatio = 16 / 9, className = "", showPlusOnDrag = true, showLabel = true, rounded = true, }: DraggableMediaItemProps) { const [isDragging, setIsDragging] = useState(false); const [dragPosition, setDragPosition] = useState({ x: 0, y: 0 }); const dragRef = useRef(null); const emptyImg = new window.Image(); emptyImg.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="; useEffect(() => { if (!isDragging) return; const handleDragOver = (e: DragEvent) => { setDragPosition({ x: e.clientX, y: e.clientY }); }; document.addEventListener("dragover", handleDragOver); return () => { document.removeEventListener("dragover", handleDragOver); }; }, [isDragging]); const handleDragStart = (e: React.DragEvent) => { e.dataTransfer.setDragImage(emptyImg, 0, 0); // Set drag data e.dataTransfer.setData( "application/x-media-item", JSON.stringify(dragData) ); e.dataTransfer.effectAllowed = "copy"; // Set initial position and show custom drag preview setDragPosition({ x: e.clientX, y: e.clientY }); setIsDragging(true); onDragStart?.(e); }; const handleDragEnd = () => { setIsDragging(false); }; return ( <>
{preview} {!isDragging && ( )} {showLabel && ( {name.length > 8 ? `${name.slice(0, 16)}...${name.slice(-3)}` : name} )}
{/* Custom drag preview */} {isDragging && typeof document !== "undefined" && createPortal(
{preview}
{showPlusOnDrag && }
, document.body )} ); } function PlusButton({ className }: { className?: string }) { return ( ); }