Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions main/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,14 @@ 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;

// 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 {
Expand Down Expand Up @@ -497,6 +505,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");
Expand All @@ -511,6 +520,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");
Expand Down Expand Up @@ -679,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);
Expand Down Expand Up @@ -833,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);
Expand Down Expand Up @@ -869,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) => {
Expand All @@ -895,6 +927,7 @@ export function newProject() {
fetch("examples/new.flock")
.then((response) => response.json())
.then((json) => {
clearFileHandle();
loadWorkspaceAndExecute(json, workspace, executeCode);
})
.catch((error) => {
Expand Down
8 changes: 6 additions & 2 deletions main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
saveWorkspace,
loadWorkspace,
exportCode,
autoSaveToFile,
setupFileInput,
setupDragAndDrop,
loadExampleWrapper,
Expand Down Expand Up @@ -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();
Expand Down