66 * provider returns the user to `/` with params, and we finish sign-in at
77 * app startup here.
88 */
9- import * as persisted from '#/state/persisted'
109import { type SessionApiContext } from '#/state/session/types'
1110import {
1211 getWebOAuthClient ,
@@ -46,17 +45,12 @@ function hasOAuthCallbackParams(): boolean {
4645 */
4746export async function tryFinishWebOAuthSignIn (
4847 login : SessionApiContext [ 'login' ] ,
48+ startOnboarding : ( ) => void ,
4949) : Promise < boolean > {
5050 if ( ! hasOAuthCallbackParams ( ) ) return false
5151 const client = getWebOAuthClient ( )
5252 const result = await client . init ( )
5353 if ( result ?. session ) {
54- // A fresh signup (prompt=create) is created on the external PDS page, which
55- // never runs our in-app signup wizard - so start onboarding here, the same
56- // way that wizard does. Plain sign-ins carry no state and are untouched.
57- if ( result . state === OAUTH_SIGNUP_STATE ) {
58- await persisted . write ( 'onboarding' , { step : 'Welcome' } )
59- }
6054 // For a handle step-up the DID is unchanged, so login() replaces the
6155 // existing session in place with the upgraded (identity:handle) tokens.
6256 await login (
@@ -68,6 +62,20 @@ export async function tryFinishWebOAuthSignIn(
6862 } ,
6963 'LoginForm' ,
7064 )
65+ // A fresh signup (prompt=create) is created on the external PDS page, which
66+ // never runs our in-app signup wizard - so start onboarding here, the same
67+ // way that wizard does. Plain sign-ins carry no state and are untouched.
68+ //
69+ // We drive the in-memory onboarding reducer (startOnboarding) rather than
70+ // only writing persisted state. OnboardingProvider is mounted above the
71+ // session, so login() never remounts it, and on web persisted.write() does
72+ // not fire onUpdate listeners in the same tab (its cross-tab
73+ // BroadcastChannel never echoes back to the sender). A bare write would
74+ // leave the onboarding context stale and the wizard would not appear until
75+ // a manual reload. The reducer's 'start' action persists the step itself.
76+ if ( result . state === OAUTH_SIGNUP_STATE ) {
77+ startOnboarding ( )
78+ }
7179 if ( result . state === OAUTH_HANDLE_STEPUP_STATE ) {
7280 // The redirect lands at the site root; rewrite the path before the
7381 // navigator reads it so web linking resolves to account settings, where
0 commit comments