From 15ad4e93c32f01d6bf6576caacbd5da1642309be Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Wed, 27 May 2026 19:46:20 -0400 Subject: [PATCH] Nostr login: persist to autosave on completion, not just on next render MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported: "the nostr login doesnt persist after a refresh now." Root cause: state.community.myPubkey is written by loadCommunityIdentity, but the localStorage write only fires from inside render(). nostrLogin calls loadCommunityIdentity → syncCommunityInputs + updateNostrWidget, none of which call render(). A user who signs in and refreshes immediately (without making any other interaction that triggers a render — adding a layer, toggling a setting, etc.) loses the login, because the autosave still reflects the pre-login state captured by an earlier init-time render(). Fix: extract the autosave write into a `persistAutosave()` helper and call it from both early-return paths of loadCommunityIdentity (logout / no extension and successful sign-in). render() now calls the same helper, so the on-disk format is identical to before. Verified end-to-end via CDP: - Stub window.nostr → call loadCommunityIdentity → no render → refresh → state.community.myPubkey restored, profile widget shows. - Same flow but window.nostr throws (logout) → cleared pubkey persisted as ''. - render() autosave still captures layers correctly (regression check on the helper extraction). Co-Authored-By: Claude Opus 4.7 --- src/index.html | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/index.html b/src/index.html index d3fcaef..bace3e0 100644 --- a/src/index.html +++ b/src/index.html @@ -7141,6 +7141,17 @@ // the Layers panel exactly once per selection change (not every render). let _panelLastSelection = null; + // Persist the full editor state without paying for a re-render. Login + // flows (and any path that mutates state without calling render()) need + // this so the change actually survives a refresh. + function persistAutosave() { + try { + localStorage.setItem('case-cover-template-maker-autosave', JSON.stringify({ ...state, layers: nonGeneratedLayers() })); + } catch (error) { + console.warn('Autosave write failed', error); + } + } + function render() { // Rebuild global clip-path before any renderer so layer // wrappers can reference them via clip-path: url(#…). @@ -7170,7 +7181,7 @@ if (layerControls) layerControls.open = true; } _panelLastSelection = state.selectedLayerId; - localStorage.setItem('case-cover-template-maker-autosave', JSON.stringify({ ...state, layers: nonGeneratedLayers() })); + persistAutosave(); } function buildSlotControls() { @@ -12955,6 +12966,7 @@ state.community.mutedPubkeys = []; state.community.muteListSyncedAt = 0; syncCommunityInputs(); + persistAutosave(); return; } @@ -12986,6 +12998,7 @@ fetchHop2Follows().catch(() => {}); syncCommunityInputs(); updateNostrWidget(); + persistAutosave(); if ($('nostrModal')?.classList.contains('open')) { await refreshCommunityView(); }