From 91cccba7b4cde47c659e33ed9d62025a41a3cdb2 Mon Sep 17 00:00:00 2001 From: dawn Date: Sat, 29 Aug 2026 16:50:04 +0900 Subject: [PATCH] web/onboarding: persist profile edits made after revisiting the step Signed-off-by: dawn --- web/src/routes/welcome/+page.svelte | 34 +++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/web/src/routes/welcome/+page.svelte b/web/src/routes/welcome/+page.svelte index b46681048..97374b333 100644 --- a/web/src/routes/welcome/+page.svelte +++ b/web/src/routes/welcome/+page.svelte @@ -37,7 +37,9 @@ let furthest = $state(0); let direction = $state(1); let savingProfile = $state(false); - let profileWritten = $state(false); + // the last draft actually written, so revisiting step one re-saves real edits + // but advancing without changes stays a no-op + let savedDraft = $state(); let profileError = $state(); let socialTouched = $state( untrack( @@ -57,6 +59,24 @@ [profileComplete, socialTouched, keys.length > 0, true][step] ?? false ); + const draftSnapshot = (value: ProfileDraft) => + JSON.stringify([ + value.description.trim(), + value.pronouns.trim(), + value.website.trim(), + value.avatarFile && [ + value.avatarFile.name, + value.avatarFile.size, + value.avatarFile.lastModified + ] + ]); + const emptyDraft = draftSnapshot({ + description: "", + pronouns: "", + website: "", + avatarFile: null + }); + const go = (to: number) => { if (to < 0 || to >= WELCOME_TOTAL || savingProfile) return; direction = to > step ? 1 : -1; @@ -65,7 +85,11 @@ }; const persistProfile = async (saveDraft: boolean): Promise => { - if (profileWritten || (!saveDraft && profileExists)) return true; + const snapshot = draftSnapshot(draft); + if (saveDraft && snapshot === savedDraft) return true; + // the placeholder record is only for accounts that never had a profile and + // never typed anything; it must never overwrite a saved draft + if (!saveDraft && (profileExists || savedDraft !== undefined)) return true; const agent = auth.agent; if (!agent) { profileError = "Your session is still loading. Try again."; @@ -107,7 +131,7 @@ } await putProfile(agent, record); - profileWritten = true; + savedDraft = snapshot; if (browser) sessionStorage.setItem("tangled.onboarding.profile", agent.sub); return true; } catch (cause) { @@ -138,7 +162,9 @@ }; const leave = async () => { - if (!(await persistProfile(false))) return; + // leaving from any step still owes the profile step its unsaved edits + const hasDraft = savedDraft !== undefined || draftSnapshot(draft) !== emptyDraft; + if (!(await persistProfile(hasDraft))) return; await goto(resolve("/")); }; -- 2.51.2