diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 29d3fa4..0cc4ccc 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -238,18 +238,30 @@ const CADEditor: React.FC = ({ projectId, token, onNavigateBack if (snap) { restoreSnapshot(snap); syncHistory(); + // Sync restored state to Yjs CRDT to prevent collab overwrite + if (collab.status === 'connected') { + for (const el of snap.elements) collab.setElement(el); + for (const layer of snap.layers) collab.setLayer(layer); + for (const block of snap.blocks) collab.setBlock(block); + } setCommandHistory((prev) => [...prev, { prefix: '·', text: 'Rückgängig: letzte Aktion', type: 'info' }]); } - }, [restoreSnapshot, syncHistory]); + }, [restoreSnapshot, syncHistory, collab]); const handleRedo = useCallback(() => { const snap = historyManagerRef.current.redo(); if (snap) { restoreSnapshot(snap); syncHistory(); + // Sync restored state to Yjs CRDT to prevent collab overwrite + if (collab.status === 'connected') { + for (const el of snap.elements) collab.setElement(el); + for (const layer of snap.layers) collab.setLayer(layer); + for (const block of snap.blocks) collab.setBlock(block); + } setCommandHistory((prev) => [...prev, { prefix: '·', text: 'Wiederherstellen: letzte Aktion', type: 'info' }]); } - }, [restoreSnapshot, syncHistory]); + }, [restoreSnapshot, syncHistory, collab]); const pushHistorySnapshot = useCallback((label: string) => { historyManagerRef.current.pushSnapshot({ @@ -318,6 +330,15 @@ const CADEditor: React.FC = ({ projectId, token, onNavigateBack } setSavedStatus('gespeichert'); setDataLoaded(true); + // Re-initialize HistoryManager with loaded project state so undo does not jump back to empty initial state + historyManagerRef.current.initialize({ + elements: data.elements, + layers: data.layers.length > 0 ? data.layers : initialLayers, + blocks: data.blocks, + groups: [], + bgConfig: null, + }); + syncHistory(); // Push initial data to Yjs CRDT after load // Issue #7: Only push to CRDT if backend data actually has content. // Pushing empty arrays would wipe existing CRDT data from other connected clients.