Nostr login: persist to autosave on completion, not just on next render

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 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.7 committed 2026-05-27 19:46:20 -04:00
1 parent d6dcdfba11
commit 15ad4e93c3
1 file changed
+14 -1
+14 -1
View File
@@ -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 <defs> 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();
}