SafeSight commited on
Commit
137ae4e
·
1 Parent(s): 7d8f3e9

file saving

Browse files
client/src/components/BlockEditor/BlockEditor.tsx CHANGED
@@ -738,6 +738,14 @@ export default function BlockEditor() {
738
  ws.addChangeListener(saveBlocks);
739
 
740
  return () => {
 
 
 
 
 
 
 
 
741
  ws.removeChangeListener(saveBlocks);
742
  ws.dispose();
743
  workspaceRef.current = null;
 
738
  ws.addChangeListener(saveBlocks);
739
 
740
  return () => {
741
+ // Save current blocks for the file before workspace is disposed
742
+ if (activeFileId) {
743
+ try {
744
+ const dom = Blockly.Xml.workspaceToDom(ws);
745
+ const xml = Blockly.Xml.domToText(dom);
746
+ setBlocksXml(activeFileId, xml);
747
+ } catch (e) {}
748
+ }
749
  ws.removeChangeListener(saveBlocks);
750
  ws.dispose();
751
  workspaceRef.current = null;
client/src/components/ProjectEditor/ProjectEditor.tsx CHANGED
@@ -60,8 +60,9 @@ export default function ProjectEditor() {
60
  editorMode, setEditorMode, viewMode, setViewMode,
61
  activeFileId, setActiveFile, fileTree, setFileTree,
62
  visualElements, setVisualElements, setElementRegistry,
63
- elementRegistry, snapToGrid, toggleSnapToGrid,
64
- showMiniMap, toggleMiniMap, setBlocksXml
 
65
  } = useEditorStore();
66
  const [showSidebar, setShowSidebar] = useState(true);
67
  const [saving, setSaving] = useState(false);
@@ -111,6 +112,12 @@ export default function ProjectEditor() {
111
  setBlockCode(fid, code);
112
  });
113
  }
 
 
 
 
 
 
114
  if (!activeFileId && currentProject.data.files?.length > 0) {
115
  const firstFile = currentProject.data.files[0];
116
  if (firstFile) {
@@ -122,7 +129,7 @@ export default function ProjectEditor() {
122
  }
123
  }
124
  }
125
- }, [currentProject, setFileTree, setVisualElements, setActiveFile, activeFileId, setEditorMode, setBlocksXml, setElementRegistry]);
126
 
127
  // When activeFileId changes, load visual elements from the registry
128
  useEffect(() => {
@@ -227,7 +234,7 @@ export default function ProjectEditor() {
227
  if (!currentProject || !id) return;
228
  setSaving(true);
229
  try {
230
- const { blocksXml: currentBlocksXml, blockCode: currentBlockCode, elementRegistry: currentRegistry } = useEditorStore.getState();
231
 
232
  // Sync current visual elements into registry before saving
233
  const fullRegistry = { ...currentRegistry };
@@ -241,6 +248,7 @@ export default function ProjectEditor() {
241
  visual: fullRegistry,
242
  blocksXml: currentBlocksXml,
243
  blockCode: currentBlockCode,
 
244
  };
245
 
246
  // Try WebSocket save first, fall back to REST
@@ -259,7 +267,7 @@ export default function ProjectEditor() {
259
  if (!currentProject || !id || !connected) return;
260
  const timer = setTimeout(() => handleSave(), 2000);
261
  return () => clearTimeout(timer);
262
- }, [currentProject, id, fileTree, visualElements, elementRegistry, activeFileId, connected, handleSave]);
263
 
264
  useEffect(() => {
265
  const handleKeyDown = (e: KeyboardEvent) => {
 
60
  editorMode, setEditorMode, viewMode, setViewMode,
61
  activeFileId, setActiveFile, fileTree, setFileTree,
62
  visualElements, setVisualElements, setElementRegistry,
63
+ elementRegistry, blocksXml, blockCode, cssRules,
64
+ snapToGrid, toggleSnapToGrid,
65
+ showMiniMap, toggleMiniMap, setBlocksXml, setCssRules
66
  } = useEditorStore();
67
  const [showSidebar, setShowSidebar] = useState(true);
68
  const [saving, setSaving] = useState(false);
 
112
  setBlockCode(fid, code);
113
  });
114
  }
115
+ // Restore per-file CSS rules
116
+ if (currentProject.data.cssRules) {
117
+ Object.entries(currentProject.data.cssRules).forEach(([fid, rules]) => {
118
+ setCssRules(fid, rules as any[]);
119
+ });
120
+ }
121
  if (!activeFileId && currentProject.data.files?.length > 0) {
122
  const firstFile = currentProject.data.files[0];
123
  if (firstFile) {
 
129
  }
130
  }
131
  }
132
+ }, [currentProject, setFileTree, setVisualElements, setActiveFile, activeFileId, setEditorMode, setBlocksXml, setElementRegistry, setCssRules]);
133
 
134
  // When activeFileId changes, load visual elements from the registry
135
  useEffect(() => {
 
234
  if (!currentProject || !id) return;
235
  setSaving(true);
236
  try {
237
+ const { blocksXml: currentBlocksXml, blockCode: currentBlockCode, elementRegistry: currentRegistry, cssRules: currentCssRules } = useEditorStore.getState();
238
 
239
  // Sync current visual elements into registry before saving
240
  const fullRegistry = { ...currentRegistry };
 
248
  visual: fullRegistry,
249
  blocksXml: currentBlocksXml,
250
  blockCode: currentBlockCode,
251
+ cssRules: currentCssRules,
252
  };
253
 
254
  // Try WebSocket save first, fall back to REST
 
267
  if (!currentProject || !id || !connected) return;
268
  const timer = setTimeout(() => handleSave(), 2000);
269
  return () => clearTimeout(timer);
270
+ }, [currentProject, id, fileTree, visualElements, elementRegistry, activeFileId, blocksXml, blockCode, cssRules, connected, handleSave]);
271
 
272
  useEffect(() => {
273
  const handleKeyDown = (e: KeyboardEvent) => {