about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/lib/hooks/useAccountSwitcher.ts6
-rw-r--r--src/state/shell/logged-out.tsx70
-rw-r--r--src/view/com/auth/LoggedOut.tsx24
-rw-r--r--src/view/com/auth/login/Login.tsx24
4 files changed, 105 insertions, 19 deletions
diff --git a/src/lib/hooks/useAccountSwitcher.ts b/src/lib/hooks/useAccountSwitcher.ts
index 2f2c110d9..74b5674d5 100644
--- a/src/lib/hooks/useAccountSwitcher.ts
+++ b/src/lib/hooks/useAccountSwitcher.ts
@@ -11,7 +11,7 @@ export function useAccountSwitcher() {
   const {track} = useAnalytics()
   const {selectAccount, clearCurrentAccount} = useSessionApi()
   const closeAllActiveElements = useCloseAllActiveElements()
-  const {setShowLoggedOut} = useLoggedOutViewControls()
+  const {requestSwitchToAccount} = useLoggedOutViewControls()
 
   const onPressSwitchAccount = useCallback(
     async (account: SessionAccount) => {
@@ -34,7 +34,7 @@ export function useAccountSwitcher() {
           }, 100)
         } else {
           closeAllActiveElements()
-          setShowLoggedOut(true)
+          requestSwitchToAccount({requestedAccount: account.did})
           Toast.show(
             `Please sign in as @${account.handle}`,
             'circle-exclamation',
@@ -50,7 +50,7 @@ export function useAccountSwitcher() {
       clearCurrentAccount,
       selectAccount,
       closeAllActiveElements,
-      setShowLoggedOut,
+      requestSwitchToAccount,
     ],
   )
 
diff --git a/src/state/shell/logged-out.tsx b/src/state/shell/logged-out.tsx
index 19eaee76b..a06a6d969 100644
--- a/src/state/shell/logged-out.tsx
+++ b/src/state/shell/logged-out.tsx
@@ -1,23 +1,77 @@
 import React from 'react'
 
-type StateContext = {
+type State = {
   showLoggedOut: boolean
+  /**
+   * Account did used to populate the login form when the logged out view is
+   * shown.
+   */
+  requestedAccountSwitchTo?: string
 }
 
-const StateContext = React.createContext<StateContext>({
+type Controls = {
+  /**
+   * Show or hide the logged out view.
+   */
+  setShowLoggedOut: (show: boolean) => void
+  /**
+   * Shows the logged out view and drops the user into the login form using the
+   * requested account.
+   */
+  requestSwitchToAccount: (props: {
+    /**
+     * The did of the account to populate the login form with.
+     */
+    requestedAccount?: string
+  }) => void
+  /**
+   * Clears the requested account so that next time the logged out view is
+   * show, no account is pre-populated.
+   */
+  clearRequestedAccount: () => void
+}
+
+const StateContext = React.createContext<State>({
   showLoggedOut: false,
+  requestedAccountSwitchTo: undefined,
 })
-const ControlsContext = React.createContext<{
-  setShowLoggedOut: (show: boolean) => void
-}>({
+
+const ControlsContext = React.createContext<Controls>({
   setShowLoggedOut: () => {},
+  requestSwitchToAccount: () => {},
+  clearRequestedAccount: () => {},
 })
 
 export function Provider({children}: React.PropsWithChildren<{}>) {
-  const [showLoggedOut, setShowLoggedOut] = React.useState(false)
+  const [state, setState] = React.useState<State>({
+    showLoggedOut: false,
+    requestedAccountSwitchTo: undefined,
+  })
 
-  const state = React.useMemo(() => ({showLoggedOut}), [showLoggedOut])
-  const controls = React.useMemo(() => ({setShowLoggedOut}), [setShowLoggedOut])
+  const controls = React.useMemo<Controls>(
+    () => ({
+      setShowLoggedOut(show) {
+        setState(s => ({
+          ...s,
+          showLoggedOut: show,
+        }))
+      },
+      requestSwitchToAccount({requestedAccount}) {
+        setState(s => ({
+          ...s,
+          showLoggedOut: true,
+          requestedAccountSwitchTo: requestedAccount,
+        }))
+      },
+      clearRequestedAccount() {
+        setState(s => ({
+          ...s,
+          requestedAccountSwitchTo: undefined,
+        }))
+      },
+    }),
+    [setState],
+  )
 
   return (
     <StateContext.Provider value={state}>
diff --git a/src/view/com/auth/LoggedOut.tsx b/src/view/com/auth/LoggedOut.tsx
index 030ae68b1..fcff4f782 100644
--- a/src/view/com/auth/LoggedOut.tsx
+++ b/src/view/com/auth/LoggedOut.tsx
@@ -14,6 +14,10 @@ import {useAnalytics} from 'lib/analytics/analytics'
 import {SplashScreen} from './SplashScreen'
 import {useSetMinimalShellMode} from '#/state/shell/minimal-mode'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
+import {
+  useLoggedOutView,
+  useLoggedOutViewControls,
+} from '#/state/shell/logged-out'
 
 enum ScreenState {
   S_LoginOrCreateAccount,
@@ -26,16 +30,27 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
   const pal = usePalette('default')
   const setMinimalShellMode = useSetMinimalShellMode()
   const {screen} = useAnalytics()
+  const {requestedAccountSwitchTo} = useLoggedOutView()
   const [screenState, setScreenState] = React.useState<ScreenState>(
-    ScreenState.S_LoginOrCreateAccount,
+    requestedAccountSwitchTo
+      ? ScreenState.S_Login
+      : ScreenState.S_LoginOrCreateAccount,
   )
   const {isMobile} = useWebMediaQueries()
+  const {clearRequestedAccount} = useLoggedOutViewControls()
 
   React.useEffect(() => {
     screen('Login')
     setMinimalShellMode(true)
   }, [screen, setMinimalShellMode])
 
+  const onPressDismiss = React.useCallback(() => {
+    if (onDismiss) {
+      onDismiss()
+    }
+    clearRequestedAccount()
+  }, [clearRequestedAccount, onDismiss])
+
   return (
     <View
       testID="noSessionView"
@@ -62,7 +77,7 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
               backgroundColor: pal.text.color,
               borderRadius: 100,
             }}
-            onPress={onDismiss}>
+            onPress={onPressDismiss}>
             <FontAwesomeIcon
               icon="x"
               size={12}
@@ -83,9 +98,10 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
         ) : undefined}
         {screenState === ScreenState.S_Login ? (
           <Login
-            onPressBack={() =>
+            onPressBack={() => {
               setScreenState(ScreenState.S_LoginOrCreateAccount)
-            }
+              clearRequestedAccount()
+            }}
           />
         ) : undefined}
         {screenState === ScreenState.S_CreateAccount ? (
diff --git a/src/view/com/auth/login/Login.tsx b/src/view/com/auth/login/Login.tsx
index 67d0afdf1..bc931ac04 100644
--- a/src/view/com/auth/login/Login.tsx
+++ b/src/view/com/auth/login/Login.tsx
@@ -14,6 +14,7 @@ import {useLingui} from '@lingui/react'
 import {msg} from '@lingui/macro'
 import {useSession, SessionAccount} from '#/state/session'
 import {useServiceQuery} from '#/state/queries/service'
+import {useLoggedOutView} from '#/state/shell/logged-out'
 
 enum Forms {
   Login,
@@ -24,16 +25,31 @@ enum Forms {
 }
 
 export const Login = ({onPressBack}: {onPressBack: () => void}) => {
+  const {_} = useLingui()
   const pal = usePalette('default')
+
   const {accounts} = useSession()
   const {track} = useAnalytics()
-  const {_} = useLingui()
+  const {requestedAccountSwitchTo} = useLoggedOutView()
+  const requestedAccount = accounts.find(
+    a => a.did === requestedAccountSwitchTo,
+  )
+
   const [error, setError] = useState<string>('')
-  const [serviceUrl, setServiceUrl] = useState<string>(DEFAULT_SERVICE)
-  const [initialHandle, setInitialHandle] = useState<string>('')
+  const [serviceUrl, setServiceUrl] = useState<string>(
+    requestedAccount?.service || DEFAULT_SERVICE,
+  )
+  const [initialHandle, setInitialHandle] = useState<string>(
+    requestedAccount?.handle || '',
+  )
   const [currentForm, setCurrentForm] = useState<Forms>(
-    accounts.length ? Forms.ChooseAccount : Forms.Login,
+    requestedAccount
+      ? Forms.Login
+      : accounts.length
+      ? Forms.ChooseAccount
+      : Forms.Login,
   )
+
   const {
     data: serviceDescription,
     error: serviceError,