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 {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,
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -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>({
|
||||
showLoggedOut: false,
|
||||
})
|
||||
const ControlsContext = React.createContext<{
|
||||
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<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}>
|
||||
|
|
|
@ -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 ? (
|
||||
|
|
|
@ -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 [error, setError] = useState<string>('')
|
||||
const [serviceUrl, setServiceUrl] = useState<string>(DEFAULT_SERVICE)
|
||||
const [initialHandle, setInitialHandle] = useState<string>('')
|
||||
const [currentForm, setCurrentForm] = useState<Forms>(
|
||||
accounts.length ? Forms.ChooseAccount : Forms.Login,
|
||||
const {requestedAccountSwitchTo} = useLoggedOutView()
|
||||
const requestedAccount = accounts.find(
|
||||
a => a.did === requestedAccountSwitchTo,
|
||||
)
|
||||
|
||||
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 {
|
||||
data: serviceDescription,
|
||||
error: serviceError,
|
||||
|
|
Loading…
Reference in New Issue