Fixes issue with (#2119)
* Allow going directly to password input screen when switching accounts and password is required * Revise state handling * Handle logged out states, enable clearing requestedAccount --------- Co-authored-by: Eric Bailey <git@esb.lol>zio/stable
parent
afca4bf701
commit
9d51886e43
|
@ -11,7 +11,7 @@ export function useAccountSwitcher() {
|
||||||
const {track} = useAnalytics()
|
const {track} = useAnalytics()
|
||||||
const {selectAccount, clearCurrentAccount} = useSessionApi()
|
const {selectAccount, clearCurrentAccount} = useSessionApi()
|
||||||
const closeAllActiveElements = useCloseAllActiveElements()
|
const closeAllActiveElements = useCloseAllActiveElements()
|
||||||
const {setShowLoggedOut} = useLoggedOutViewControls()
|
const {requestSwitchToAccount} = useLoggedOutViewControls()
|
||||||
|
|
||||||
const onPressSwitchAccount = useCallback(
|
const onPressSwitchAccount = useCallback(
|
||||||
async (account: SessionAccount) => {
|
async (account: SessionAccount) => {
|
||||||
|
@ -34,7 +34,7 @@ export function useAccountSwitcher() {
|
||||||
}, 100)
|
}, 100)
|
||||||
} else {
|
} else {
|
||||||
closeAllActiveElements()
|
closeAllActiveElements()
|
||||||
setShowLoggedOut(true)
|
requestSwitchToAccount({requestedAccount: account.did})
|
||||||
Toast.show(
|
Toast.show(
|
||||||
`Please sign in as @${account.handle}`,
|
`Please sign in as @${account.handle}`,
|
||||||
'circle-exclamation',
|
'circle-exclamation',
|
||||||
|
@ -50,7 +50,7 @@ export function useAccountSwitcher() {
|
||||||
clearCurrentAccount,
|
clearCurrentAccount,
|
||||||
selectAccount,
|
selectAccount,
|
||||||
closeAllActiveElements,
|
closeAllActiveElements,
|
||||||
setShowLoggedOut,
|
requestSwitchToAccount,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,77 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
type StateContext = {
|
type State = {
|
||||||
showLoggedOut: boolean
|
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 = {
|
||||||
showLoggedOut: false,
|
/**
|
||||||
})
|
* Show or hide the logged out view.
|
||||||
const ControlsContext = React.createContext<{
|
*/
|
||||||
setShowLoggedOut: (show: boolean) => void
|
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<Controls>({
|
||||||
setShowLoggedOut: () => {},
|
setShowLoggedOut: () => {},
|
||||||
|
requestSwitchToAccount: () => {},
|
||||||
|
clearRequestedAccount: () => {},
|
||||||
})
|
})
|
||||||
|
|
||||||
export function Provider({children}: React.PropsWithChildren<{}>) {
|
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<Controls>(
|
||||||
const controls = React.useMemo(() => ({setShowLoggedOut}), [setShowLoggedOut])
|
() => ({
|
||||||
|
setShowLoggedOut(show) {
|
||||||
|
setState(s => ({
|
||||||
|
...s,
|
||||||
|
showLoggedOut: show,
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
requestSwitchToAccount({requestedAccount}) {
|
||||||
|
setState(s => ({
|
||||||
|
...s,
|
||||||
|
showLoggedOut: true,
|
||||||
|
requestedAccountSwitchTo: requestedAccount,
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
clearRequestedAccount() {
|
||||||
|
setState(s => ({
|
||||||
|
...s,
|
||||||
|
requestedAccountSwitchTo: undefined,
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[setState],
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StateContext.Provider value={state}>
|
<StateContext.Provider value={state}>
|
||||||
|
|
|
@ -14,6 +14,10 @@ import {useAnalytics} from 'lib/analytics/analytics'
|
||||||
import {SplashScreen} from './SplashScreen'
|
import {SplashScreen} from './SplashScreen'
|
||||||
import {useSetMinimalShellMode} from '#/state/shell/minimal-mode'
|
import {useSetMinimalShellMode} from '#/state/shell/minimal-mode'
|
||||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||||
|
import {
|
||||||
|
useLoggedOutView,
|
||||||
|
useLoggedOutViewControls,
|
||||||
|
} from '#/state/shell/logged-out'
|
||||||
|
|
||||||
enum ScreenState {
|
enum ScreenState {
|
||||||
S_LoginOrCreateAccount,
|
S_LoginOrCreateAccount,
|
||||||
|
@ -26,16 +30,27 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const setMinimalShellMode = useSetMinimalShellMode()
|
const setMinimalShellMode = useSetMinimalShellMode()
|
||||||
const {screen} = useAnalytics()
|
const {screen} = useAnalytics()
|
||||||
|
const {requestedAccountSwitchTo} = useLoggedOutView()
|
||||||
const [screenState, setScreenState] = React.useState<ScreenState>(
|
const [screenState, setScreenState] = React.useState<ScreenState>(
|
||||||
ScreenState.S_LoginOrCreateAccount,
|
requestedAccountSwitchTo
|
||||||
|
? ScreenState.S_Login
|
||||||
|
: ScreenState.S_LoginOrCreateAccount,
|
||||||
)
|
)
|
||||||
const {isMobile} = useWebMediaQueries()
|
const {isMobile} = useWebMediaQueries()
|
||||||
|
const {clearRequestedAccount} = useLoggedOutViewControls()
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
screen('Login')
|
screen('Login')
|
||||||
setMinimalShellMode(true)
|
setMinimalShellMode(true)
|
||||||
}, [screen, setMinimalShellMode])
|
}, [screen, setMinimalShellMode])
|
||||||
|
|
||||||
|
const onPressDismiss = React.useCallback(() => {
|
||||||
|
if (onDismiss) {
|
||||||
|
onDismiss()
|
||||||
|
}
|
||||||
|
clearRequestedAccount()
|
||||||
|
}, [clearRequestedAccount, onDismiss])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
testID="noSessionView"
|
testID="noSessionView"
|
||||||
|
@ -62,7 +77,7 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
|
||||||
backgroundColor: pal.text.color,
|
backgroundColor: pal.text.color,
|
||||||
borderRadius: 100,
|
borderRadius: 100,
|
||||||
}}
|
}}
|
||||||
onPress={onDismiss}>
|
onPress={onPressDismiss}>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon="x"
|
icon="x"
|
||||||
size={12}
|
size={12}
|
||||||
|
@ -83,9 +98,10 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{screenState === ScreenState.S_Login ? (
|
{screenState === ScreenState.S_Login ? (
|
||||||
<Login
|
<Login
|
||||||
onPressBack={() =>
|
onPressBack={() => {
|
||||||
setScreenState(ScreenState.S_LoginOrCreateAccount)
|
setScreenState(ScreenState.S_LoginOrCreateAccount)
|
||||||
}
|
clearRequestedAccount()
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{screenState === ScreenState.S_CreateAccount ? (
|
{screenState === ScreenState.S_CreateAccount ? (
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {useLingui} from '@lingui/react'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useSession, SessionAccount} from '#/state/session'
|
import {useSession, SessionAccount} from '#/state/session'
|
||||||
import {useServiceQuery} from '#/state/queries/service'
|
import {useServiceQuery} from '#/state/queries/service'
|
||||||
|
import {useLoggedOutView} from '#/state/shell/logged-out'
|
||||||
|
|
||||||
enum Forms {
|
enum Forms {
|
||||||
Login,
|
Login,
|
||||||
|
@ -24,16 +25,31 @@ enum Forms {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Login = ({onPressBack}: {onPressBack: () => void}) => {
|
export const Login = ({onPressBack}: {onPressBack: () => void}) => {
|
||||||
|
const {_} = useLingui()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
|
||||||
const {accounts} = useSession()
|
const {accounts} = useSession()
|
||||||
const {track} = useAnalytics()
|
const {track} = useAnalytics()
|
||||||
const {_} = useLingui()
|
const {requestedAccountSwitchTo} = useLoggedOutView()
|
||||||
const [error, setError] = useState<string>('')
|
const requestedAccount = accounts.find(
|
||||||
const [serviceUrl, setServiceUrl] = useState<string>(DEFAULT_SERVICE)
|
a => a.did === requestedAccountSwitchTo,
|
||||||
const [initialHandle, setInitialHandle] = useState<string>('')
|
|
||||||
const [currentForm, setCurrentForm] = useState<Forms>(
|
|
||||||
accounts.length ? Forms.ChooseAccount : Forms.Login,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const [error, setError] = useState<string>('')
|
||||||
|
const [serviceUrl, setServiceUrl] = useState<string>(
|
||||||
|
requestedAccount?.service || DEFAULT_SERVICE,
|
||||||
|
)
|
||||||
|
const [initialHandle, setInitialHandle] = useState<string>(
|
||||||
|
requestedAccount?.handle || '',
|
||||||
|
)
|
||||||
|
const [currentForm, setCurrentForm] = useState<Forms>(
|
||||||
|
requestedAccount
|
||||||
|
? Forms.Login
|
||||||
|
: accounts.length
|
||||||
|
? Forms.ChooseAccount
|
||||||
|
: Forms.Login,
|
||||||
|
)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: serviceDescription,
|
data: serviceDescription,
|
||||||
error: serviceError,
|
error: serviceError,
|
||||||
|
|
Loading…
Reference in New Issue