From fdbcff9868a6cb7d8e8cc6f8cc704595d24e2bca Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 27 Feb 2026 20:37:26 +0000 Subject: [PATCH 1/2] Add autosave to file after explicit project save Once a user saves their project via the file picker (File System Access API), the returned FileSystemFileHandle is stored. The 30-second autosave interval now also writes to that file handle automatically, keeping the saved file in sync without prompting the user again. https://claude.ai/code/session_01SD7tmTxQf83oQYKAjTHUuV --- main/files.js | 24 ++++++++++++++++++++++++ main/main.js | 8 ++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/main/files.js b/main/files.js index 7b502f91..d96772bb 100644 --- a/main/files.js +++ b/main/files.js @@ -448,6 +448,9 @@ export function stripFilename(inputString) { return removeEnd.substring(lastIndex + 1).trim(); } +// Holds the FileSystemFileHandle from the last explicit save (File System Access API) +let currentFileHandle = null; + // Function to export project code export async function exportCode(workspace) { try { @@ -497,6 +500,7 @@ export async function exportCode(workspace) { const writable = await fileHandle.createWritable(); await writable.write(jsonString); await writable.close(); + currentFileHandle = fileHandle; } else { const blob = new Blob([jsonString], { type: FLOCK_MIME }); const link = document.createElement("a"); @@ -511,6 +515,26 @@ export async function exportCode(workspace) { } } +// Autosave to the last explicitly-saved file handle (no picker shown) +export async function autoSaveToFile(workspace) { + if (!currentFileHandle) return; + try { + const ws = + workspace && workspace.getAllBlocks + ? workspace + : Blockly.getMainWorkspace(); + if (!ws || !ws.getAllBlocks) return; + + const json = Blockly.serialization.workspaces.save(ws); + const jsonString = JSON.stringify(json, null, 2); + const writable = await currentFileHandle.createWritable(); + await writable.write(jsonString); + await writable.close(); + } catch (e) { + console.error("Error during file autosave:", e); + } +} + // Function to import snippet from file export function importSnippet() { const fileInput = document.getElementById("importFile"); diff --git a/main/main.js b/main/main.js index 14658a42..035943d5 100644 --- a/main/main.js +++ b/main/main.js @@ -23,6 +23,7 @@ import { saveWorkspace, loadWorkspace, exportCode, + autoSaveToFile, setupFileInput, setupDragAndDrop, loadExampleWrapper, @@ -414,8 +415,11 @@ window.onload = async function () { console.log("Welcome to Flock 🐑🐑🐑"); - // Call this function to autosave periodically - setInterval(() => saveWorkspace(workspace), 30000); // Autosave every 30 seconds + // Autosave every 30 seconds: to localStorage and (if a file was saved) to that file + setInterval(() => { + saveWorkspace(workspace); + autoSaveToFile(workspace); + }, 30000); (async () => { await flock.initialize(); From 653fafb49592c020b8d3328f957dee9b43973120 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 27 Feb 2026 20:53:04 +0000 Subject: [PATCH 2/2] Fix autosave overwriting old file when a new project is loaded When a new file or example was opened, currentFileHandle was never cleared, so the 30-second autosave kept writing back to the previously saved file. Now clearFileHandle() is called in all four load paths (file input, drag-and-drop, load example, new project) to reset the handle whenever the active project changes. https://claude.ai/code/session_01SD7tmTxQf83oQYKAjTHUuV --- main/files.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main/files.js b/main/files.js index d96772bb..07db82b7 100644 --- a/main/files.js +++ b/main/files.js @@ -451,6 +451,11 @@ export function stripFilename(inputString) { // Holds the FileSystemFileHandle from the last explicit save (File System Access API) let currentFileHandle = null; +// Clears the stored file handle (call whenever a new project is loaded) +export function clearFileHandle() { + currentFileHandle = null; +} + // Function to export project code export async function exportCode(workspace) { try { @@ -703,6 +708,7 @@ function processProjectFileDrop(file, workspace, executeCallback) { const baseName = sanitizedName.replace(/\.(json|flock)$/i, ""); document.getElementById("projectName").value = stripFilename(baseName); + clearFileHandle(); loadWorkspaceAndExecute(json, workspace, executeCallback); } catch (e) { console.error("Error loading Blockly project:", e); @@ -857,6 +863,7 @@ export function setupFileInput(workspace, executeCallback) { document.getElementById("projectName").value = stripFilename(baseName); + clearFileHandle(); loadWorkspaceAndExecute(json, workspace, executeCallback); } catch (e) { console.error("Error loading Blockly project:", e); @@ -893,6 +900,7 @@ export function loadExample(workspace, executeCallback) { .then((response) => response.json()) .then((json) => { console.log("Loading:", selectedOption); + clearFileHandle(); loadWorkspaceAndExecute(json, workspace, executeCallback); }) .catch((error) => { @@ -919,6 +927,7 @@ export function newProject() { fetch("examples/new.flock") .then((response) => response.json()) .then((json) => { + clearFileHandle(); loadWorkspaceAndExecute(json, workspace, executeCode); }) .catch((error) => {