import {useDragMonitor} from '@common/ui/interactions/dnd/use-drag-monitor'; import React, {memo, useRef, useState} from 'react'; import {FileTypeIcon} from '@common/uploads/file-type-icon/file-type-icon'; import {FileEntry} from '@common/uploads/file-entry'; import { DragSessionStatus, droppables, } from '@common/ui/interactions/dnd/drag-state'; import {AnimatePresence, m} from 'framer-motion'; import clsx from 'clsx'; import { isFolderTreeDragId, makeFolderTreeDragId, } from '../layout/sidebar/folder-tree-drag-id'; import {InteractableEvent} from '@common/ui/interactions/interactable-event'; import {useDriveStore} from '../drive-store'; import {ConnectedDraggable} from '@common/ui/interactions/dnd/use-draggable'; interface Point { x: number; y: number; } interface DragPreviewState { entries?: FileEntry[]; e?: InteractableEvent; status?: DragSessionStatus; draggingTreeItem?: boolean; } export function EntryDragPreview() { const ref = useRef(null); const [points, setPoints] = useState<{start?: Point; end?: Point}>(); const [state, setState] = useState({}); useDragMonitor({ type: 'fileEntry', onDragStart: (e, dragTarget) => { const target = dragTarget as ConnectedDraggable; if (target) { setState({ entries: target.getData(), e, draggingTreeItem: isFolderTreeDragId(target.id as number), }); setPoints({start: e}); } }, onDragMove: e => { setState(prev => { return {...prev, e: e}; }); setPoints(prev => { return {...prev, end: e}; }); }, onDragEnd: (e, dragTarget, status) => { setState({status}); }, }); let preview = null; if (state.entries && state.e) { preview = (
{state.entries.map((item, index) => ( ))}
); } return {preview}; } interface EntryPreviewProps { entry: FileEntry; index: number; points?: {start?: Point; end?: Point}; state: DragPreviewState; } const EntryPreview = memo( ({entry, points, index, state}: EntryPreviewProps) => { const viewMode = useDriveStore(s => s.viewMode); const droppableId = state.draggingTreeItem ? makeFolderTreeDragId(entry) : entry.id; const target = droppables.get(droppableId); if (!target?.rect || !points?.start) return null; const rect = target.rect; const itemCount = state.entries?.length || 0; const exitVariant = (status: DragSessionStatus) => { if (status === 'dropSuccess') { return { x: 0, y: 0, opacity: 0, transition: {duration: 0.1, delay: 0}, }; } return { x: rect.left - (points.end?.x || 0), y: rect.top - (points.end?.y || 0), width: `${state.e?.rect.width}px`, }; }; return ( 0 && 'top-6 left-6' )} > {itemCount > 1 && index === 0 && }
{entry.name}
); } ); interface EntryCountProps { count: number; } const EntryCount = memo(({count}: EntryCountProps) => { return ( {count} ); });