diff --git a/frontend/src/features/workspace/WorkspaceView.tsx b/frontend/src/features/workspace/WorkspaceView.tsx index 28b55e5..7d24330 100644 --- a/frontend/src/features/workspace/WorkspaceView.tsx +++ b/frontend/src/features/workspace/WorkspaceView.tsx @@ -579,8 +579,25 @@ export const WorkspaceView: React.FC = ({ await persistDocument(updatedDoc); }; + // Global drag cleanup so drag states never get stuck if dragend is lost during re-render + useEffect(() => { + const handleGlobalDragEnd = () => { + setDraggingDocId(null); + setDragOverFolder(null); + setDraggingBlockId(null); + }; + window.addEventListener('dragend', handleGlobalDragEnd); + window.addEventListener('drop', handleGlobalDragEnd); + return () => { + window.removeEventListener('dragend', handleGlobalDragEnd); + window.removeEventListener('drop', handleGlobalDragEnd); + }; + }, []); + const handleDropDocToFolder = async (folderPath: string, e: React.DragEvent) => { const docId = e.dataTransfer.getData('application/mindsift-doc-id') || draggingDocId; + setDraggingDocId(null); + setDragOverFolder(null); if (!docId) return; const doc = docs.find((d) => d.id === docId); if (!doc) return; @@ -1244,6 +1261,7 @@ export const WorkspaceView: React.FC = ({ e.preventDefault(); e.stopPropagation(); setDragOverFolder(null); + setDraggingDocId(null); handleDropDocToFolder(node.path, e); }} > @@ -1532,6 +1550,7 @@ export const WorkspaceView: React.FC = ({ e.preventDefault(); e.stopPropagation(); setDragOverFolder(null); + setDraggingDocId(null); handleDropDocToFolder('', e); }} className={`mx-2 my-1.5 p-2 border-2 border-dashed rounded-btn text-center text-xs transition-colors ${