save/load workspace now works
parent
ef0f3e12d1
commit
3fdf4b1573
144
src/main.js
144
src/main.js
|
|
@ -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`);
|
||||
|
|
|
|||
Loading…
Reference in New Issue