save/load workspace now works

main
Jake 2026-02-20 15:49:47 +08:00
parent ef0f3e12d1
commit 3fdf4b1573
1 changed files with 61 additions and 87 deletions

View File

@ -131,82 +131,58 @@ function setConnectedUI(connected) {
let workspaceCaptureState = null;
onData((text) => {
// Check if we're capturing workspace XML
if (workspaceCaptureState) {
const { startMarker, endMarker } = workspaceCaptureState;
const startIdx = text.indexOf(startMarker);
const endIdx = text.indexOf(endMarker);
// PRIORITY 1: If already capturing, check for end marker first
if (workspaceCaptureState.capturing) {
if (endIdx !== -1) {
// Found end marker - extract content
workspaceCaptureState.buffer += text.substring(0, endIdx);
const xmlContent = workspaceCaptureState.buffer.trim();
// Parse and load XML
try {
const xmlDom = Blockly.Xml.textToDom(xmlContent);
Blockly.Xml.domToWorkspace(xmlDom, workspace);
appendToTerminal('Workspace loaded successfully!\n');
} catch (parseErr) {
appendToTerminal(`\nParse error: ${parseErr.message}\n`);
}
workspaceCaptureState = null;
// Don't display the end marker, but show text after it
const afterEnd = text.substring(endIdx + endMarker.length);
if (afterEnd.trim()) {
appendToTerminal(afterEnd);
}
return;
} else {
// Still capturing, accumulate buffer
workspaceCaptureState.buffer += text;
// Don't display captured content
return;
}
}
// PRIORITY 2: Both markers in the same chunk (not yet capturing)
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
const xmlContent = text.substring(startIdx + startMarker.length, endIdx);
// Parse and load XML
try {
const xmlDom = Blockly.Xml.textToDom(xmlContent.trim());
Blockly.Xml.domToWorkspace(xmlDom, workspace);
appendToTerminal('Workspace loaded successfully!\n');
} catch (parseErr) {
appendToTerminal(`\nParse error: ${parseErr.message}\n`);
}
workspaceCaptureState = null;
// Don't display the markers, but show text before/after
const beforeStart = text.substring(0, startIdx);
const afterEnd = text.substring(endIdx + endMarker.length);
if (beforeStart.trim() || afterEnd.trim()) {
appendToTerminal(beforeStart + afterEnd);
}
return;
}
// PRIORITY 3: Start marker found, start capturing
if (startIdx !== -1) {
workspaceCaptureState.capturing = true;
workspaceCaptureState.buffer = text.substring(startIdx + startMarker.length);
// Don't display the start marker or content after it
const beforeStart = text.substring(0, startIdx);
if (beforeStart.trim()) {
appendToTerminal(beforeStart);
}
return;
}
if (!workspaceCaptureState) {
appendToTerminal(text);
return;
}
appendToTerminal(text);
const { startMarker, endMarker } = workspaceCaptureState;
workspaceCaptureState.raw += text;
const raw = workspaceCaptureState.raw;
const startIdx = raw.indexOf(startMarker);
if (startIdx === -1) {
// No start marker yet — flush text that can't be part of the marker
const keep = startMarker.length - 1;
if (raw.length > keep) {
appendToTerminal(raw.substring(0, raw.length - keep));
workspaceCaptureState.raw = raw.substring(raw.length - keep);
}
return;
}
const contentStart = startIdx + startMarker.length;
const endIdx = raw.indexOf(endMarker, contentStart);
if (endIdx === -1) {
// Have start but no end yet — show text before start marker once
if (!workspaceCaptureState.flushedPre && startIdx > 0) {
appendToTerminal(raw.substring(0, startIdx));
workspaceCaptureState.flushedPre = true;
}
return;
}
// Both markers found — extract content and load
const jsonContent = raw.substring(contentStart, endIdx).trim();
const beforeStart = startIdx > 0 && !workspaceCaptureState.flushedPre
? raw.substring(0, startIdx) : '';
const afterEnd = raw.substring(endIdx + endMarker.length);
workspaceCaptureState = null;
if (beforeStart) appendToTerminal(beforeStart);
try {
const state = JSON.parse(jsonContent);
Blockly.serialization.workspaces.load(state, workspace);
appendToTerminal('Workspace loaded successfully!\n');
} catch (parseErr) {
appendToTerminal(`\nParse error: ${parseErr.message}\n`);
}
if (afterEnd.trim()) appendToTerminal(afterEnd);
});
// ─── Toolbar Buttons ─────────────────────────────────────
@ -331,13 +307,12 @@ btnSave.addEventListener('click', async () => {
async function saveWorkspaceToDevice() {
try {
// Convert workspace to XML
const xml = Blockly.Xml.workspaceToDom(workspace);
const xmlText = Blockly.Xml.domToText(xml);
const state = Blockly.serialization.workspaces.save(workspace);
const json = JSON.stringify(state);
appendToTerminal('\nSaving workspace to device...\n');
await writeFileToDevice(xmlText, 'workspace.xml');
appendToTerminal('Workspace saved to workspace.xml\n');
await writeFileToDevice(json, 'workspace.json');
appendToTerminal('Workspace saved to workspace.json\n');
} catch (err) {
appendToTerminal(`\nSave workspace error: ${err.message}\n`);
}
@ -352,24 +327,23 @@ async function loadWorkspaceFromDevice() {
const startMarker = `__WS_START_${timestamp}__`;
const endMarker = `__WS_END_${timestamp}__`;
// Set up capture state
workspaceCaptureState = {
startMarker,
endMarker,
buffer: '',
capturing: false,
raw: '',
flushedPre: false,
};
const script = [
`try:`,
` f = open('workspace.xml', 'r')`,
` f = open('workspace.json', 'r')`,
` data = f.read()`,
` f.close()`,
` print('${startMarker}')`,
` print(data, end='')`,
` print('${endMarker}')`,
`except Exception as e:`,
` print('Error reading workspace.xml: ' + str(e))`,
` print('Error reading workspace.json: ' + str(e))`,
].join('\n');
await executeCode(script);
@ -380,7 +354,7 @@ async function loadWorkspaceFromDevice() {
appendToTerminal('\nTimeout waiting for workspace data\n');
workspaceCaptureState = null;
}
}, 5000);
}, 10000);
} catch (err) {
appendToTerminal(`\nLoad workspace error: ${err.message}\n`);