diff --git a/wasm/app/app.js b/wasm/app/app.js index 4482392..1f9d71e 100644 --- a/wasm/app/app.js +++ b/wasm/app/app.js @@ -72,20 +72,7 @@ function getEditorText() { async function loadCurrentDemo() { const sel = document.querySelector('input[name="program"]:checked').value; const vaultBar = document.getElementById("vault-bar"); - // Vault bar visible whenever the vault gate has been engaged - // (locked or unlocked) — drafts live per-program now, not just - // for free-form, so the lock/unlock affordance stays useful on - // every demo. Hide entirely only if the user explicitly hasn't - // set up a vault yet (vault.exists()) — kept as-is to avoid - // a "first-paint shows lock UI to a fresh customer" surprise. - vaultBar.hidden = sel !== "free-form" && !vaultState.vault; - // If the vault is unlocked and has a saved draft for this - // program, use it; otherwise fall back to the demo's source. - if (vaultState.vault && vaultState.drafts - && typeof vaultState.drafts[sel] === "string") { - setEditorText(vaultState.drafts[sel]); - return; - } + vaultBar.hidden = sel !== "free-form"; const src = await loadDemoSource(sel); setEditorText(src); } @@ -115,30 +102,18 @@ async function unlockVault() { vaultState.vault = null; return; } - // Per-program draft map. Back-compat: lift any legacy - // top-level freeForm field into drafts['free-form'] so users - // who already had a free-form draft don't lose it. - vaultState.drafts = (data && data.drafts && typeof data.drafts === "object") - ? Object.assign({}, data.drafts) - : {}; - if (data && typeof data.freeForm === "string" && !vaultState.drafts["free-form"]) { - vaultState.drafts["free-form"] = data.freeForm; - } - vaultState.freeForm = vaultState.drafts["free-form"] || FREE_FORM_DEFAULT; + vaultState.freeForm = (data && typeof data.freeForm === "string") + ? data.freeForm + : FREE_FORM_DEFAULT; vaultStateEl.textContent = "unlocked"; vaultStateEl.classList.add("unlocked"); vaultUnlockBtn.hidden = true; vaultLockBtn.hidden = false; vaultPwEl.value = ""; vaultPwEl.disabled = true; - // If the currently-selected program has a saved draft, load it. - // Otherwise leave the demo's default source in place. + // If free-form is the current program, swap the editor in. const sel = document.querySelector('input[name="program"]:checked').value; - if (typeof vaultState.drafts[sel] === "string") { - setEditorText(vaultState.drafts[sel]); - } else if (sel === "free-form") { - setEditorText(vaultState.freeForm); - } + if (sel === "free-form") setEditorText(vaultState.freeForm); setVaultNote("ok — edits auto-save"); } catch (e) { setVaultNote("unlock failed: " + e.message, true); @@ -147,7 +122,6 @@ async function unlockVault() { function lockVault() { vaultState.vault = null; - vaultState.drafts = null; vaultState.freeForm = null; if (vaultState.saveTimer) { clearTimeout(vaultState.saveTimer); vaultState.saveTimer = null; } vaultStateEl.textContent = "locked"; @@ -157,38 +131,21 @@ function lockVault() { vaultPwEl.disabled = false; vaultPwEl.value = ""; setVaultNote(""); - // Reset the editor to whatever the current program ships with - // (drafts only live while the vault is unlocked). - loadCurrentDemo(); + // If free-form is current program, swap to the placeholder. + const sel = document.querySelector('input[name="program"]:checked').value; + if (sel === "free-form") setEditorText(FREE_FORM_DEFAULT); } -// Debounced autosave — fires on every editor doc change while the -// vault is unlocked. Saves under drafts[program-name] so each demo's -// edits persist independently. Previously this was free-form-only, -// which surprised users who edited a demo, switched tabs, and came -// back to their original demo source untouched. function scheduleFreeFormSave() { if (!vaultState.vault) return; const sel = document.querySelector('input[name="program"]:checked').value; + if (sel !== "free-form") return; if (vaultState.saveTimer) clearTimeout(vaultState.saveTimer); vaultState.saveTimer = setTimeout(async () => { const text = getEditorText(); - vaultState.drafts = vaultState.drafts || {}; - vaultState.drafts[sel] = text; - // Keep the legacy freeForm field in sync so older builds that - // only know about that field still see the user's free-form - // edits if they re-open the vault from a different tab. - if (sel === "free-form") vaultState.freeForm = text; - try { - await vaultState.vault.write({ - drafts: vaultState.drafts, - freeForm: vaultState.drafts["free-form"] || "", - savedAt: Date.now(), - }); - setVaultNote(`saved ${sel} @ ${new Date().toLocaleTimeString()}`); - } catch (e) { - setVaultNote("save failed: " + e.message, true); - } + vaultState.freeForm = text; + try { await vaultState.vault.write({ freeForm: text, savedAt: Date.now() }); } + catch (e) { setVaultNote("save failed: " + e.message, true); } }, 350); } diff --git a/www/playground/app.js b/www/playground/app.js index 4482392..1f9d71e 100644 --- a/www/playground/app.js +++ b/www/playground/app.js @@ -72,20 +72,7 @@ function getEditorText() { async function loadCurrentDemo() { const sel = document.querySelector('input[name="program"]:checked').value; const vaultBar = document.getElementById("vault-bar"); - // Vault bar visible whenever the vault gate has been engaged - // (locked or unlocked) — drafts live per-program now, not just - // for free-form, so the lock/unlock affordance stays useful on - // every demo. Hide entirely only if the user explicitly hasn't - // set up a vault yet (vault.exists()) — kept as-is to avoid - // a "first-paint shows lock UI to a fresh customer" surprise. - vaultBar.hidden = sel !== "free-form" && !vaultState.vault; - // If the vault is unlocked and has a saved draft for this - // program, use it; otherwise fall back to the demo's source. - if (vaultState.vault && vaultState.drafts - && typeof vaultState.drafts[sel] === "string") { - setEditorText(vaultState.drafts[sel]); - return; - } + vaultBar.hidden = sel !== "free-form"; const src = await loadDemoSource(sel); setEditorText(src); } @@ -115,30 +102,18 @@ async function unlockVault() { vaultState.vault = null; return; } - // Per-program draft map. Back-compat: lift any legacy - // top-level freeForm field into drafts['free-form'] so users - // who already had a free-form draft don't lose it. - vaultState.drafts = (data && data.drafts && typeof data.drafts === "object") - ? Object.assign({}, data.drafts) - : {}; - if (data && typeof data.freeForm === "string" && !vaultState.drafts["free-form"]) { - vaultState.drafts["free-form"] = data.freeForm; - } - vaultState.freeForm = vaultState.drafts["free-form"] || FREE_FORM_DEFAULT; + vaultState.freeForm = (data && typeof data.freeForm === "string") + ? data.freeForm + : FREE_FORM_DEFAULT; vaultStateEl.textContent = "unlocked"; vaultStateEl.classList.add("unlocked"); vaultUnlockBtn.hidden = true; vaultLockBtn.hidden = false; vaultPwEl.value = ""; vaultPwEl.disabled = true; - // If the currently-selected program has a saved draft, load it. - // Otherwise leave the demo's default source in place. + // If free-form is the current program, swap the editor in. const sel = document.querySelector('input[name="program"]:checked').value; - if (typeof vaultState.drafts[sel] === "string") { - setEditorText(vaultState.drafts[sel]); - } else if (sel === "free-form") { - setEditorText(vaultState.freeForm); - } + if (sel === "free-form") setEditorText(vaultState.freeForm); setVaultNote("ok — edits auto-save"); } catch (e) { setVaultNote("unlock failed: " + e.message, true); @@ -147,7 +122,6 @@ async function unlockVault() { function lockVault() { vaultState.vault = null; - vaultState.drafts = null; vaultState.freeForm = null; if (vaultState.saveTimer) { clearTimeout(vaultState.saveTimer); vaultState.saveTimer = null; } vaultStateEl.textContent = "locked"; @@ -157,38 +131,21 @@ function lockVault() { vaultPwEl.disabled = false; vaultPwEl.value = ""; setVaultNote(""); - // Reset the editor to whatever the current program ships with - // (drafts only live while the vault is unlocked). - loadCurrentDemo(); + // If free-form is current program, swap to the placeholder. + const sel = document.querySelector('input[name="program"]:checked').value; + if (sel === "free-form") setEditorText(FREE_FORM_DEFAULT); } -// Debounced autosave — fires on every editor doc change while the -// vault is unlocked. Saves under drafts[program-name] so each demo's -// edits persist independently. Previously this was free-form-only, -// which surprised users who edited a demo, switched tabs, and came -// back to their original demo source untouched. function scheduleFreeFormSave() { if (!vaultState.vault) return; const sel = document.querySelector('input[name="program"]:checked').value; + if (sel !== "free-form") return; if (vaultState.saveTimer) clearTimeout(vaultState.saveTimer); vaultState.saveTimer = setTimeout(async () => { const text = getEditorText(); - vaultState.drafts = vaultState.drafts || {}; - vaultState.drafts[sel] = text; - // Keep the legacy freeForm field in sync so older builds that - // only know about that field still see the user's free-form - // edits if they re-open the vault from a different tab. - if (sel === "free-form") vaultState.freeForm = text; - try { - await vaultState.vault.write({ - drafts: vaultState.drafts, - freeForm: vaultState.drafts["free-form"] || "", - savedAt: Date.now(), - }); - setVaultNote(`saved ${sel} @ ${new Date().toLocaleTimeString()}`); - } catch (e) { - setVaultNote("save failed: " + e.message, true); - } + vaultState.freeForm = text; + try { await vaultState.vault.write({ freeForm: text, savedAt: Date.now() }); } + catch (e) { setVaultNote("save failed: " + e.message, true); } }, 350); }