From cb54cd87bb36c92ebcd59cd0b2edb77245b1b999 Mon Sep 17 00:00:00 2001 From: "xan.lol" Date: Thu, 22 Jan 2026 01:28:31 -0800 Subject: [PATCH] feat(mobile): stay on the same page when switching accounts --- src/Navigation.tsx | 25 ++++++++++++++++++++++++- src/lib/hooks/useAccountSwitcher.ts | 3 +++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 626c4f780..a15af4908 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -38,9 +38,10 @@ import { type MessagesTabNavigatorParams, type MyProfileTabNavigatorParams, type NotificationsTabNavigatorParams, + type RouteParams, type SearchTabNavigatorParams, + type State, } from '#/lib/routes/types' -import {type RouteParams, type State} from '#/lib/routes/types' import {attachRouteToLogEvents, logEvent} from '#/lib/statsig/statsig' import {bskyTitle} from '#/lib/strings/headings' import {logger} from '#/logger' @@ -145,6 +146,24 @@ import {Referrer} from '../modules/expo-bluesky-swiss-army' const navigationRef = createNavigationContainerRef() +/** + * Stores the navigation state before account switch on native. + * This allows the user to stay on the same page when switching accounts. + */ +let storedNavigationStateForAccountSwitch: State | undefined + +export function storeNavigationStateForAccountSwitch() { + if (IS_NATIVE && navigationRef.isReady()) { + storedNavigationStateForAccountSwitch = navigationRef.getRootState() + } +} + +function consumeStoredNavigationState(): State | undefined { + const state = storedNavigationStateForAccountSwitch + storedNavigationStateForAccountSwitch = undefined + return state +} + const HomeTab = createNativeStackNavigatorWithAuth() const SearchTab = createNativeStackNavigatorWithAuth() const NotificationsTab = @@ -899,6 +918,9 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { const disableVerifyEmailReminder = useDisableVerifyEmailReminder() + // Consume stored navigation state from account switch (native only) + const initialState = IS_NATIVE ? consumeStoredNavigationState() : undefined + /** * Handle navigation to a conversation, or prepares for account switch. * @@ -1005,6 +1027,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) { ref={navigationRef} linking={LINKING} theme={theme} + initialState={initialState} onStateChange={() => { logger.metric( 'router:navigate', diff --git a/src/lib/hooks/useAccountSwitcher.ts b/src/lib/hooks/useAccountSwitcher.ts index 5c0485c9f..4c86be215 100644 --- a/src/lib/hooks/useAccountSwitcher.ts +++ b/src/lib/hooks/useAccountSwitcher.ts @@ -6,6 +6,7 @@ import {logger} from '#/logger' import {type SessionAccount, useSessionApi} from '#/state/session' import {useLoggedOutViewControls} from '#/state/shell/logged-out' import * as Toast from '#/view/com/util/Toast' +import {storeNavigationStateForAccountSwitch} from '#/Navigation' import {logEvent} from '../statsig/statsig' import {type LogEvents} from '../statsig/statsig' @@ -27,6 +28,8 @@ export function useAccountSwitcher() { try { setPendingDid(account.did) if (account.accessJwt) { + // Store navigation state before switching so user stays on the same page + storeNavigationStateForAccountSwitch() await resumeSession(account, true) logEvent('account:loggedIn', {logContext, withPassword: false}) Toast.show(_(msg`Signed in as @${account.handle}`)) -- 2.51.2