incname commited on
Commit
5cc6796
·
1 Parent(s): 54ee264

blocks to js

Browse files
client/src/components/BlockEditor/BlockEditor.tsx CHANGED
@@ -627,6 +627,27 @@ function generateCodeFromWorkspace(ws: any): string {
627
  return code.filter(Boolean).join('\n');
628
  }
629
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
630
  export default function BlockEditor() {
631
  const blocklyDiv = useRef<HTMLDivElement>(null);
632
  const workspaceRef = useRef<Blockly.WorkspaceSvg | null>(null);
@@ -635,8 +656,6 @@ export default function BlockEditor() {
635
  const activeFileId = useEditorStore((s) => s.activeFileId);
636
  const getBlocksXml = useEditorStore((s) => s.getBlocksXml);
637
  const setBlocksXml = useEditorStore((s) => s.setBlocksXml);
638
- const setBlockCode = useEditorStore((s) => s.setBlockCode);
639
- const saveGeneratedCodeToFile = useEditorStore((s) => s.saveGeneratedCodeToFile);
640
  const projectIdRef = useRef(currentProject?.id);
641
  projectIdRef.current = currentProject?.id;
642
  const lastPointerEmitRef = useRef(0);
@@ -979,6 +998,10 @@ export default function BlockEditor() {
979
  Blockly.Xml.domToWorkspace(dom, ws2);
980
  try { (ws2 as any).clearSelection(); } catch {}
981
  try { ws2.zoomToFit(); } catch {}
 
 
 
 
982
  } catch (e) {
983
  console.error('[WS Reload] FAILED to apply deferred XML:', e);
984
  }
@@ -1063,19 +1086,7 @@ export default function BlockEditor() {
1063
  console.log('[saveBlocks] SAVING blocks for file:', currentFileId, 'xml length:', xml.length, 'topBlocks:', ws.getTopBlocks(false).length, '(old:', savedXml?.length, ')');
1064
  setBlocksXml(currentFileId, xml);
1065
  emitBlockStateSync(currentFileId, xml);
1066
- let finalCode = '';
1067
- try {
1068
- // Try manual code generation first (uses our compile functions directly)
1069
- finalCode = generateCodeFromWorkspace(ws);
1070
- // Fall back to Blockly's generator if manual output is empty but blocks exist
1071
- if (!finalCode && ws.getTopBlocks(false).length > 0) {
1072
- finalCode = javascriptGenerator.workspaceToCode(ws) || '';
1073
- }
1074
- } catch (e) {
1075
- // code generation failed - file content stays empty so compileWeb defaults
1076
- }
1077
- setBlockCode(currentFileId, finalCode);
1078
- saveGeneratedCodeToFile(currentFileId, finalCode);
1079
  };
1080
  ws.addChangeListener(saveBlocks);
1081
 
@@ -1154,6 +1165,9 @@ export default function BlockEditor() {
1154
  Blockly.Xml.domToWorkspace(dom, ws);
1155
  try { (ws as any).clearSelection(); } catch {}
1156
  try { ws.zoomToFit(); } catch {}
 
 
 
1157
  } catch (e) {
1158
  console.error('[WS Reload] FAILED to load blocks from XML:', e);
1159
  }
@@ -1234,6 +1248,9 @@ export default function BlockEditor() {
1234
  useCollaborationStore.setState({ pendingBlockConnects: unprocessed });
1235
  }
1236
  ws.render();
 
 
 
1237
  }
1238
  remoteUpdateRef.current = false;
1239
  }, [pendingBlockConnects, blocksXmlForFile]);
@@ -1255,6 +1272,9 @@ export default function BlockEditor() {
1255
  }
1256
  }
1257
  remoteUpdateRef.current = false;
 
 
 
1258
  }, [pendingBlockChanges]);
1259
 
1260
  // Create blocks on receiver when remote user drags a new block from the toolbox
@@ -1294,6 +1314,9 @@ export default function BlockEditor() {
1294
  const xml = Blockly.Xml.domToText(dom);
1295
  console.log('[PendingCreate] updating blocksXml after creating blocks');
1296
  useEditorStore.getState().setBlocksXml(activeFileId, xml);
 
 
 
1297
  requestAnimationFrame(() => {
1298
  try { syncCustomFunctionBlocks(ws); } catch {}
1299
  try { rebuildToolbox(ws); } catch {}
 
627
  return code.filter(Boolean).join('\n');
628
  }
629
 
630
+ // Regenerate the compiled code for a workspace and persist it to the store and
631
+ // file tree. Called on local saves and after remote XML reloads, which skip
632
+ // saveBlocks because its change listener early-returns while remoteUpdateRef
633
+ // is set. Without this, the code panel would not reflect collaborator changes.
634
+ function refreshCodeForWorkspace(ws: any, fileId: string): void {
635
+ let finalCode = '';
636
+ try {
637
+ // Try manual code generation first (uses our compile functions directly)
638
+ finalCode = generateCodeFromWorkspace(ws);
639
+ // Fall back to Blockly's generator if manual output is empty but blocks exist
640
+ if (!finalCode && ws.getTopBlocks(false).length > 0) {
641
+ finalCode = javascriptGenerator.workspaceToCode(ws) || '';
642
+ }
643
+ } catch (e) {
644
+ finalCode = '';
645
+ }
646
+ const store = useEditorStore.getState();
647
+ store.setBlockCode(fileId, finalCode);
648
+ store.saveGeneratedCodeToFile(fileId, finalCode);
649
+ }
650
+
651
  export default function BlockEditor() {
652
  const blocklyDiv = useRef<HTMLDivElement>(null);
653
  const workspaceRef = useRef<Blockly.WorkspaceSvg | null>(null);
 
656
  const activeFileId = useEditorStore((s) => s.activeFileId);
657
  const getBlocksXml = useEditorStore((s) => s.getBlocksXml);
658
  const setBlocksXml = useEditorStore((s) => s.setBlocksXml);
 
 
659
  const projectIdRef = useRef(currentProject?.id);
660
  projectIdRef.current = currentProject?.id;
661
  const lastPointerEmitRef = useRef(0);
 
998
  Blockly.Xml.domToWorkspace(dom, ws2);
999
  try { (ws2 as any).clearSelection(); } catch {}
1000
  try { ws2.zoomToFit(); } catch {}
1001
+ // Regenerate the compiled code now that the workspace reflects
1002
+ // the collaborator's XML (saveBlocks skips during remote loads).
1003
+ const currentFileId = useEditorStore.getState().activeFileId;
1004
+ if (currentFileId) refreshCodeForWorkspace(ws2, currentFileId);
1005
  } catch (e) {
1006
  console.error('[WS Reload] FAILED to apply deferred XML:', e);
1007
  }
 
1086
  console.log('[saveBlocks] SAVING blocks for file:', currentFileId, 'xml length:', xml.length, 'topBlocks:', ws.getTopBlocks(false).length, '(old:', savedXml?.length, ')');
1087
  setBlocksXml(currentFileId, xml);
1088
  emitBlockStateSync(currentFileId, xml);
1089
+ refreshCodeForWorkspace(ws, currentFileId);
 
 
 
 
 
 
 
 
 
 
 
 
1090
  };
1091
  ws.addChangeListener(saveBlocks);
1092
 
 
1165
  Blockly.Xml.domToWorkspace(dom, ws);
1166
  try { (ws as any).clearSelection(); } catch {}
1167
  try { ws.zoomToFit(); } catch {}
1168
+ // Regenerate the compiled code now that the workspace reflects the synced
1169
+ // XML (saveBlocks skips while remoteUpdateRef is set).
1170
+ if (activeFileId) refreshCodeForWorkspace(ws, activeFileId);
1171
  } catch (e) {
1172
  console.error('[WS Reload] FAILED to load blocks from XML:', e);
1173
  }
 
1248
  useCollaborationStore.setState({ pendingBlockConnects: unprocessed });
1249
  }
1250
  ws.render();
1251
+ // saveBlocks skips while remoteUpdateRef is set, so refresh the compiled
1252
+ // code explicitly after applying remote connections.
1253
+ if (activeFileId) refreshCodeForWorkspace(ws, activeFileId);
1254
  }
1255
  remoteUpdateRef.current = false;
1256
  }, [pendingBlockConnects, blocksXmlForFile]);
 
1272
  }
1273
  }
1274
  remoteUpdateRef.current = false;
1275
+ // saveBlocks skips while remoteUpdateRef is set, so refresh the compiled
1276
+ // code explicitly after applying remote field value changes.
1277
+ if (ws && activeFileId) refreshCodeForWorkspace(ws, activeFileId);
1278
  }, [pendingBlockChanges]);
1279
 
1280
  // Create blocks on receiver when remote user drags a new block from the toolbox
 
1314
  const xml = Blockly.Xml.domToText(dom);
1315
  console.log('[PendingCreate] updating blocksXml after creating blocks');
1316
  useEditorStore.getState().setBlocksXml(activeFileId, xml);
1317
+ // saveBlocks skips while remoteUpdateRef is set, so refresh the
1318
+ // compiled code explicitly after creating collaborator blocks.
1319
+ refreshCodeForWorkspace(ws, activeFileId);
1320
  requestAnimationFrame(() => {
1321
  try { syncCustomFunctionBlocks(ws); } catch {}
1322
  try { rebuildToolbox(ws); } catch {}