4bb8cb4b18bc

fix onboarding state persistence: Onboarding.tsx no longer writes peach_onboarded='true' on completion (caused stranded users mid-vault-creation with no back path on Android); App.tsx still persists when vault actually exists, so the flag tracks reality not intent. Also wire peach:back event handler in App.tsx to take the user back to onboarding from create-vault, and to handle in-app surface back nav (settings/add/etc) on Android

time
2026-05-07 02:48 UTC · 5 months ago
machine
koh2
parent
c03f67121dd8
2 files src/popup/App.tsx+19 −0src/popup/views/Onboarding.tsx+4 −6
src/popup/App.tsx+19 −0
@@ -464,6 +464,25 @@464464     chrome.runtime.onMessage.addListener(handleRuntimeMessage);465465     onCleanup(() => chrome.runtime.onMessage.removeListener(handleRuntimeMessage));466466 467+    // Android hardware/gesture back. MainActivity fires peach:back; the popup468+    // decides what "back" means per surface. Lock+no-vault is the common case469+    // — return to onboarding rather than letting the OS dismiss the activity.470+    const handlePeachBack = () => {471+      const v = view();472+      if (v === "lock" && !hasVault() && onboarded()) {473+        setOnboarded(false);474+        return;475+      }476+      if (v === "list") { setView("entry"); return; }477+      if (v === "settings" || v === "import" || v === "export" || v === "add" || v === "health") {478+        handleBack();479+        return;480+      }481+      if (v === "sync-pairing") { setView("settings"); return; }482+    };483+    window.addEventListener("peach:back", handlePeachBack);484+    onCleanup(() => window.removeEventListener("peach:back", handlePeachBack));485+467486     // Action handlers — keyed by ShortcutAction. The dispatcher below tests468487     // each binding against the event and runs the matching handler. New469488     // shortcuts only need an entry here; the binding is data, not code.

view file

src/popup/views/Onboarding.tsx+4 −6
@@ -1,7 +1,6 @@11 import { For, Show, createSignal } from "solid-js";22 import { PeachWordmark } from "../components/PeachMark";33 import { RuneBackground } from "../components/RuneBackground";4-import { storageSet } from "../../shared/storage";54 65 interface OnboardingCard {76   headline: string;@@ -61,11 +60,10 @@6160       }, CARD_EXIT_MS + CARD_ENTER_GAP_MS);6261     } else {6362       setCompleting(true);64-      try {65-        await storageSet("peach_onboarded", "true");66-      } catch {67-        // storage unavailable — still complete the flow68-      }63+      // Don't persist peach_onboarded here. App.tsx persists it only when a64+      // vault actually exists — so a user who quits mid-vault-creation65+      // returns to the start of onboarding instead of getting stranded on66+      // the create-vault screen with no back path.6967       window.setTimeout(() => {7068         void props.onComplete();7169       }, 200);

view file