diff --git a/frontend/src/features/workspace/WorkspaceView.tsx b/frontend/src/features/workspace/WorkspaceView.tsx index 83e6ad2..dfb308b 100644 --- a/frontend/src/features/workspace/WorkspaceView.tsx +++ b/frontend/src/features/workspace/WorkspaceView.tsx @@ -43,6 +43,7 @@ import { Lock, Unlock, Eye, + Share, Share2, } from 'lucide-react'; import { BlockType, Document, DocumentBlock, DocLockInfo, DocShare, User } from '../../lib/types'; @@ -373,15 +374,28 @@ export const WorkspaceView: React.FC = ({ }; }, [selectedDoc?.id]); - // Flush pending save before tab closes or unmounts + // Flush pending save and release lock before tab closes or unmounts useEffect(() => { const handleBeforeUnload = () => { flushPendingSave(); + if (currentDocIdRef.current && holdsLockRef.current) { + try { + const token = localStorage.getItem('mindsift_token') || sessionStorage.getItem('mindsift_token'); + fetch(`/api/v1/documents/${currentDocIdRef.current}/lock`, { + method: 'DELETE', + headers: token ? { Authorization: `Bearer ${token}` } : {}, + keepalive: true, + }).catch(() => {}); + } catch {} + } }; window.addEventListener('beforeunload', handleBeforeUnload); return () => { window.removeEventListener('beforeunload', handleBeforeUnload); flushPendingSave(); + if (currentDocIdRef.current && holdsLockRef.current) { + releaseMyLock(currentDocIdRef.current); + } }; }, []); @@ -399,8 +413,9 @@ export const WorkspaceView: React.FC = ({ } } } else if (msg.event === 'DOC_UNLOCKED') { - const payload = msg.payload as { doc_id: string }; - if (payload && payload.doc_id === selectedDoc?.id) { + const payload = msg.payload as { docId?: string; doc_id?: string; id?: string }; + const unlockedDocId = payload?.docId || payload?.doc_id || payload?.id; + if (unlockedDocId && unlockedDocId === selectedDoc?.id) { setActiveLock(null); } } else if (msg.event === 'DOC_CREATED') { @@ -413,11 +428,11 @@ export const WorkspaceView: React.FC = ({ const updated = msg.payload as Document; if (updated && updated.id) { setDocs((prev) => - prev.map((d) => (d.id === updated.id ? { ...d, ...updated } : d)) + prev.map((d) => (d.id === updated.id ? { ...d, ...updated, isPinned: d.isPinned } : d)) ); if (selectedDoc?.id === updated.id) { if (!holdsLockRef.current) { - setSelectedDoc((prev) => (prev ? { ...prev, ...updated } : updated)); + setSelectedDoc((prev) => (prev ? { ...prev, ...updated, isPinned: prev.isPinned } : updated)); } } onStatsChange(); @@ -1915,16 +1930,10 @@ export const WorkspaceView: React.FC = ({