fix(frontend): layers/blocks local-first merge + push effects (quality review fixes)
This commit is contained in:
+34
-26
@@ -334,42 +334,36 @@ const CADEditor: React.FC<CADEditorProps> = ({ projectId, token, onNavigateBack
|
||||
setElements(merged);
|
||||
}
|
||||
|
||||
// Never overwrite local layers with empty remote layers (prevents losing initialLayers)
|
||||
// Merge layers: local-first, update changed from remote, append remote-only
|
||||
if (collab.layers.length > 0) {
|
||||
// Compare by ID set, not by index ordering. Update if any layer properties differ.
|
||||
const localLayerMap = new Map(layers.map(l => [l.id, l]));
|
||||
let layersChanged = false;
|
||||
const mergedLayers = collab.layers.map(rl => {
|
||||
const local = localLayerMap.get(rl.id);
|
||||
if (!local || JSON.stringify(local) !== JSON.stringify(rl)) {
|
||||
layersChanged = true;
|
||||
}
|
||||
return rl;
|
||||
const remoteLayerMap = new Map(collab.layers.map(l => [l.id, l]));
|
||||
const mergedLayers = layers.map(ll => {
|
||||
const remote = remoteLayerMap.get(ll.id);
|
||||
return remote ? (JSON.stringify(remote) !== JSON.stringify(ll) ? remote : ll) : ll;
|
||||
});
|
||||
// Also check if local has layers not in remote
|
||||
if (!layersChanged && layers.length !== collab.layers.length) {
|
||||
layersChanged = true;
|
||||
collab.layers.forEach(rl => {
|
||||
if (!localLayerMap.has(rl.id)) mergedLayers.push(rl);
|
||||
});
|
||||
if (mergedLayers.length !== layers.length || mergedLayers.some((ml, i) => ml !== layers[i])) {
|
||||
setLayers(mergedLayers);
|
||||
}
|
||||
if (layersChanged) setLayers(mergedLayers);
|
||||
}
|
||||
|
||||
// Never overwrite local blocks with empty remote blocks (prevents losing defaultBlocks)
|
||||
// Merge blocks: local-first, update changed from remote, append remote-only
|
||||
if (collab.blocks.length > 0) {
|
||||
// Compare by ID set, not by index ordering. Update if any block properties differ.
|
||||
const localBlockMap = new Map(blocks.map(b => [b.id, b]));
|
||||
let blocksChanged = false;
|
||||
const mergedBlocks = collab.blocks.map(rb => {
|
||||
const local = localBlockMap.get(rb.id);
|
||||
if (!local || JSON.stringify(local) !== JSON.stringify(rb)) {
|
||||
blocksChanged = true;
|
||||
}
|
||||
return rb;
|
||||
const remoteBlockMap = new Map(collab.blocks.map(b => [b.id, b]));
|
||||
const mergedBlocks = blocks.map(lb => {
|
||||
const remote = remoteBlockMap.get(lb.id);
|
||||
return remote ? (JSON.stringify(remote) !== JSON.stringify(lb) ? remote : lb) : lb;
|
||||
});
|
||||
// Also check if local has blocks not in remote
|
||||
if (!blocksChanged && blocks.length !== collab.blocks.length) {
|
||||
blocksChanged = true;
|
||||
collab.blocks.forEach(rb => {
|
||||
if (!localBlockMap.has(rb.id)) mergedBlocks.push(rb);
|
||||
});
|
||||
if (mergedBlocks.length !== blocks.length || mergedBlocks.some((mb, i) => mb !== blocks[i])) {
|
||||
setBlocks(mergedBlocks);
|
||||
}
|
||||
if (blocksChanged) setBlocks(mergedBlocks);
|
||||
}
|
||||
|
||||
// Sync groups from remote → local
|
||||
@@ -409,6 +403,20 @@ const CADEditor: React.FC<CADEditorProps> = ({ projectId, token, onNavigateBack
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [bgConfig, collab.status]);
|
||||
|
||||
// Sync local → remote: push local layers to Yjs when layers change
|
||||
React.useEffect(() => {
|
||||
if (collab.status !== 'connected') return;
|
||||
for (const layer of layers) collab.setLayer(layer);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [layers, collab.status]);
|
||||
|
||||
// Sync local → remote: push local blocks to Yjs when blocks change
|
||||
React.useEffect(() => {
|
||||
if (collab.status !== 'connected') return;
|
||||
for (const block of blocks) collab.setBlock(block);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [blocks, collab.status]);
|
||||
|
||||
const handleElementCreated = useCallback((el: CADElement) => {
|
||||
const elWithLayer = el.layerId ? el : { ...el, layerId: activeLayerId };
|
||||
setElements((prev) => {
|
||||
|
||||
Reference in New Issue
Block a user