diff --git a/src/asset_store.js b/src/asset_store.js index e658992..d89932f 100644 --- a/src/asset_store.js +++ b/src/asset_store.js @@ -91,8 +91,18 @@ export class AssetStore { return new AssetStore(db); } - static async requestPersistance() { + static async requestPersistence() { const storage = globalThis.navigator.storage; + + // Chrome silently allows/denies based on user interaction + if (globalThis.chrome) { + if (!await storage.persisted()) { + await storage.persist(); + } + + return; + } + let isAlreadyPersisted; try { isAlreadyPersisted = await storage.persisted(); @@ -101,11 +111,11 @@ export class AssetStore { return; } if (isAlreadyPersisted) { - console.log("[AssetStore] already got persistant storage!"); + console.log("[AssetStore] already got persistent storage!"); return; } - if (globalThis.localStorage.getItem("persistance-denied")) { - console.log("[AssetStore] already denied persistant storage!"); + if (globalThis.localStorage.getItem("persistence-denied")) { + console.log("[AssetStore] already denied persistent storage!"); return; } const dialog = document.querySelector("#AssetStore-popup"); @@ -125,7 +135,7 @@ export class AssetStore { } }); deny.addEventListener("click", () => { - globalThis.localStorage.setItem("persistance-denied", true); + globalThis.localStorage.setItem("persistence-denied", true); dialog.close(); }); dialog.showModal(); diff --git a/src/index.js b/src/index.js index e85fef0..47d92c1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,5 @@ /// -import { Debounce } from "./debounce.js"; import { PlaygroundConsole } from "./playground_console.js"; import { CodeRunner } from "./code_runner.js"; import { AssetEditor } from "./asset_editor.js"; @@ -9,6 +8,7 @@ import { Gamelib } from "./gamelib.js"; import { ConsoleInput } from "./console_input.js"; import { ProjectSaveHandler } from "./project_save_handler.js"; import { AssetStore } from "./asset_store.js"; +import { SessionSaveHandler } from "./session_save_handler.js"; const editor = ace.edit("editor"); editor.setTheme("ace/theme/gruvbox"); @@ -20,8 +20,6 @@ editor.setOptions({ copyWithEmptySelection: true, }); -editor.setValue(sessionStorage.getItem("code") ?? editor.getValue(), -1); - const languageProvider = LanguageProvider.fromCdn( "https://www.unpkg.com/ace-linters@latest/build", undefined, @@ -83,22 +81,15 @@ const loadButton = document.querySelector("#load-button"); const exportButton = document.querySelector("#export-button"); const dropZone = document.querySelector("main"); -const projectSaveHandler = new ProjectSaveHandler(editor, assetEditor, assetProvider, projectName); +const sessionSaveHandler = new SessionSaveHandler(editor, projectName); +sessionSaveHandler.loadAll(); -const sessionSaveDebounce = new Debounce(1000); -editor.addEventListener("change", () => { - sessionSaveDebounce.run(() => { - sessionStorage.setItem("code", editor.getValue()); - }); -}); - -if (sessionStorage.getItem("project-name")) { - projectName.value = sessionStorage.getItem("project-name"); -} - -projectName.onchange = () => { - sessionStorage.setItem("project-name", projectName.value); -}; +const projectSaveHandler = new ProjectSaveHandler( + editor, + assetEditor, + assetProvider, + sessionSaveHandler, +); runButton.onclick = async () => { const code = editor.getValue(); @@ -166,4 +157,4 @@ dropZone.ondrop = async (ev) => { ev.preventDefault(); }; -AssetStore.requestPersistance(); +AssetStore.requestPersistence(); diff --git a/src/project_save_handler.js b/src/project_save_handler.js index 8549681..df3c46b 100644 --- a/src/project_save_handler.js +++ b/src/project_save_handler.js @@ -4,10 +4,10 @@ import { HtmlExporter } from "./html_exporter.js"; import { KarlkoderCodec } from "./karlkoder_codec.js"; export class ProjectSaveHandler { - constructor(editor, assetEditor, assetProvider, projectName) { + constructor(editor, assetEditor, assetProvider, sessionSaveHandler) { this.editor = editor; this.assetEditor = assetEditor; - this.projectName = projectName; + this.sessionSaveHandler = sessionSaveHandler; this.htmlExporter = new HtmlExporter(assetProvider); @@ -36,7 +36,7 @@ export class ProjectSaveHandler { ); } - this.loadFromFile(files[0]); + await this.loadFromFile(files[0]); } async loadFromFile(file) { @@ -71,11 +71,9 @@ export class ProjectSaveHandler { }), ); - this.projectName.value = code.name; - sessionStorage.setItem("project-name", code.name); - const dec = new TextDecoder(); - this.editor.setValue(dec.decode(code.content)); + this.sessionSaveHandler.saveEditorCode(dec.decode(code.content)); + this.sessionSaveHandler.saveProjectName(code.name); this.isSaved = true; this.fileHandles = {}; diff --git a/src/session_save_handler.js b/src/session_save_handler.js new file mode 100644 index 0000000..b79c031 --- /dev/null +++ b/src/session_save_handler.js @@ -0,0 +1,49 @@ +import { Debounce } from "./debounce.js"; + +export class SessionSaveHandler { + constructor(editor, projectName) { + this.editor = editor; + this.projectName = projectName; + + const sessionSaveDebounce = new Debounce(1000); + editor.addEventListener("change", () => { + sessionSaveDebounce.run(() => this.saveEditorCode()); + }); + + projectName.addEventListener("change", () => this.saveProjectName()); + } + + saveEditorCode(code = null) { + if (code) { + this.editor.setValue(code, -1); + } + + localStorage.setItem("code", this.editor.getValue()); + } + + saveProjectName(name = null) { + if (name) { + this.projectName.value = name; + } + + localStorage.setItem("project-name", this.projectName.value); + } + + saveAll() { + this.saveEditorCode(); + this.saveProjectName(); + } + + loadEditorCode() { + this.editor.setValue(localStorage.getItem("code") ?? this.editor.getValue(), -1); + } + + loadProjectName() { + this.projectName.value = localStorage.getItem("project-name") ?? ""; + } + + loadAll() { + this.loadEditorCode(); + this.loadProjectName(); + } +}