Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 33 additions & 19 deletions apps/web/src/domains/onboarding/pages/pre-chat-flow.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as Sentry from "@sentry/browser";
import { useQuery } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { useEffect, useLayoutEffect, useState } from "react";
import { useNavigate } from "react-router";

import { useIsIOSWeb } from "@/domains/nudges/ios-app-platform.js";
Expand Down Expand Up @@ -75,16 +75,24 @@ export function PreChatFlow() {
// Native pre-chat restores its position across reloads via sessionStorage
// — without this, an iOS user who's tapped through to the vibe step and
// hot-reloads (or returns after the OS reclaims memory) is silently
// dropped back to the name step.
const [screen, setScreen] = useState<Screen>(() => {
// dropped back to the name step. The key is user-scoped so a stale value
// from user A doesn't bleed into user B if they log in next in the same
// webview session — `useLayoutEffect` restores before paint once `userId`
// is known, so the user never sees an incorrect step momentarily.
const screenStorageKey = userId ? `prechat_native_screen:${userId}` : null;
const [screen, setScreen] = useState<Screen>(0);
useLayoutEffect(() => {
if (!screenStorageKey) return;
try {
const saved = sessionStorage.getItem("prechat_native_screen");
if (saved === "1") return 1;
const saved = sessionStorage.getItem(screenStorageKey);
if (saved === "1") setScreen(1);
Comment on lines +87 to +88

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reset screen for users without a saved native prechat step

When screenStorageKey changes, this effect only updates state if the new key stores "1". If user A was on screen === 1 and user B logs in without a saved key, screen stays at 1 in memory, so user B can still land on the vibe step despite having no persisted progress. This can happen whenever the component remains mounted across an auth identity swap (the exact scenario this change is targeting). The restore path should explicitly set screen back to 0 when no saved value exists for the active user key.

Useful? React with 👍 / 👎.

} catch {
// sessionStorage can throw under privacy modes — ignore.
}
return 0;
});
// Restore only when the active user changes (mount, or logout→login).
// Intentionally omitting `screen` from deps so we don't re-restore mid-flow.
}, [screenStorageKey]);

const [selectedTools, setSelectedTools] = useState<Set<string>>(
() => new Set(),
);
Expand Down Expand Up @@ -207,10 +215,12 @@ export function PreChatFlow() {
// keeps the two callsites from drifting.
const goToVibeStep = () => {
setScreen(1);
try {
sessionStorage.setItem("prechat_native_screen", "1");
} catch {
// ignore — see initial-state comment.
if (screenStorageKey) {
try {
sessionStorage.setItem(screenStorageKey, "1");
} catch {
// ignore — see initial-state comment.
}
}
};
return (
Expand Down Expand Up @@ -246,10 +256,12 @@ export function PreChatFlow() {
if (trimmedAssistant) {
setPendingAssistantName(trimmedAssistant);
}
try {
sessionStorage.removeItem("prechat_native_screen");
} catch {
// ignore — see initial-state comment.
if (screenStorageKey) {
try {
sessionStorage.removeItem(screenStorageKey);
} catch {
// ignore — see initial-state comment.
}
}
void navigate(routes.onboarding.privacy);
};
Expand All @@ -259,10 +271,12 @@ export function PreChatFlow() {
onGroupChange={setSelectedGroupId}
onBack={() => {
setScreen(0);
try {
sessionStorage.removeItem("prechat_native_screen");
} catch {
// ignore — see initial-state comment.
if (screenStorageKey) {
try {
sessionStorage.removeItem(screenStorageKey);
} catch {
// ignore — see initial-state comment.
}
}
}}
onContinue={finishNativePreChat}
Expand Down