[Session] Extract resumeSession out (#3811)
parent
dadf27fd2f
commit
5ec945b762
|
@ -16,6 +16,7 @@ import {useLingui} from '@lingui/react'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
|
import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
|
||||||
|
import {logger} from '#/logger'
|
||||||
import {init as initPersistedState} from '#/state/persisted'
|
import {init as initPersistedState} from '#/state/persisted'
|
||||||
import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
|
import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
|
||||||
import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts'
|
import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts'
|
||||||
|
@ -34,6 +35,7 @@ import {Provider as PrefsStateProvider} from 'state/preferences'
|
||||||
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
|
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
|
||||||
import {
|
import {
|
||||||
Provider as SessionProvider,
|
Provider as SessionProvider,
|
||||||
|
SessionAccount,
|
||||||
useSession,
|
useSession,
|
||||||
useSessionApi,
|
useSessionApi,
|
||||||
} from 'state/session'
|
} from 'state/session'
|
||||||
|
@ -53,8 +55,9 @@ import {listenSessionDropped} from './state/events'
|
||||||
SplashScreen.preventAutoHideAsync()
|
SplashScreen.preventAutoHideAsync()
|
||||||
|
|
||||||
function InnerApp() {
|
function InnerApp() {
|
||||||
const {isInitialLoad, currentAccount} = useSession()
|
const [isReady, setIsReady] = React.useState(false)
|
||||||
const {resumeSession} = useSessionApi()
|
const {currentAccount} = useSession()
|
||||||
|
const {initSession} = useSessionApi()
|
||||||
const theme = useColorModeTheme()
|
const theme = useColorModeTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
|
||||||
|
@ -62,18 +65,31 @@ function InnerApp() {
|
||||||
|
|
||||||
// init
|
// init
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
listenSessionDropped(() => {
|
async function resumeSession(account?: SessionAccount) {
|
||||||
Toast.show(_(msg`Sorry! Your session expired. Please log in again.`))
|
try {
|
||||||
})
|
if (account) {
|
||||||
|
await initSession(account)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`session: resumeSession failed`, {message: e})
|
||||||
|
} finally {
|
||||||
|
setIsReady(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
const account = readLastActiveAccount()
|
const account = readLastActiveAccount()
|
||||||
resumeSession(account)
|
resumeSession(account)
|
||||||
}, [resumeSession, _])
|
}, [initSession])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return listenSessionDropped(() => {
|
||||||
|
Toast.show(_(msg`Sorry! Your session expired. Please log in again.`))
|
||||||
|
})
|
||||||
|
}, [_])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaProvider initialMetrics={initialWindowMetrics}>
|
<SafeAreaProvider initialMetrics={initialWindowMetrics}>
|
||||||
<Alf theme={theme}>
|
<Alf theme={theme}>
|
||||||
<Splash isReady={!isInitialLoad}>
|
<Splash isReady={isReady}>
|
||||||
<React.Fragment
|
<React.Fragment
|
||||||
// Resets the entire tree below when it changes:
|
// Resets the entire tree below when it changes:
|
||||||
key={currentAccount?.did}>
|
key={currentAccount?.did}>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {RootSiblingParent} from 'react-native-root-siblings'
|
||||||
import {SafeAreaProvider} from 'react-native-safe-area-context'
|
import {SafeAreaProvider} from 'react-native-safe-area-context'
|
||||||
|
|
||||||
import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
|
import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
|
||||||
|
import {logger} from '#/logger'
|
||||||
import {init as initPersistedState} from '#/state/persisted'
|
import {init as initPersistedState} from '#/state/persisted'
|
||||||
import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
|
import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
|
||||||
import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts'
|
import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts'
|
||||||
|
@ -22,6 +23,7 @@ import {Provider as PrefsStateProvider} from 'state/preferences'
|
||||||
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
|
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
|
||||||
import {
|
import {
|
||||||
Provider as SessionProvider,
|
Provider as SessionProvider,
|
||||||
|
SessionAccount,
|
||||||
useSession,
|
useSession,
|
||||||
useSessionApi,
|
useSessionApi,
|
||||||
} from 'state/session'
|
} from 'state/session'
|
||||||
|
@ -36,19 +38,31 @@ import {Provider as PortalProvider} from '#/components/Portal'
|
||||||
import I18nProvider from './locale/i18nProvider'
|
import I18nProvider from './locale/i18nProvider'
|
||||||
|
|
||||||
function InnerApp() {
|
function InnerApp() {
|
||||||
const {isInitialLoad, currentAccount} = useSession()
|
const [isReady, setIsReady] = React.useState(false)
|
||||||
const {resumeSession} = useSessionApi()
|
const {currentAccount} = useSession()
|
||||||
|
const {initSession} = useSessionApi()
|
||||||
const theme = useColorModeTheme()
|
const theme = useColorModeTheme()
|
||||||
useIntentHandler()
|
useIntentHandler()
|
||||||
|
|
||||||
// init
|
// init
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
async function resumeSession(account?: SessionAccount) {
|
||||||
|
try {
|
||||||
|
if (account) {
|
||||||
|
await initSession(account)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`session: resumeSession failed`, {message: e})
|
||||||
|
} finally {
|
||||||
|
setIsReady(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
const account = readLastActiveAccount()
|
const account = readLastActiveAccount()
|
||||||
resumeSession(account)
|
resumeSession(account)
|
||||||
}, [resumeSession])
|
}, [initSession])
|
||||||
|
|
||||||
// wait for session to resume
|
// wait for session to resume
|
||||||
if (isInitialLoad) return null
|
if (!isReady) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Alf theme={theme}>
|
<Alf theme={theme}>
|
||||||
|
|
|
@ -35,7 +35,6 @@ const PUBLIC_BSKY_AGENT = new BskyAgent({service: PUBLIC_BSKY_SERVICE})
|
||||||
configureModerationForGuest()
|
configureModerationForGuest()
|
||||||
|
|
||||||
const StateContext = React.createContext<SessionStateContext>({
|
const StateContext = React.createContext<SessionStateContext>({
|
||||||
isInitialLoad: true,
|
|
||||||
isSwitchingAccounts: false,
|
isSwitchingAccounts: false,
|
||||||
accounts: [],
|
accounts: [],
|
||||||
currentAccount: undefined,
|
currentAccount: undefined,
|
||||||
|
@ -47,7 +46,6 @@ const ApiContext = React.createContext<SessionApiContext>({
|
||||||
login: async () => {},
|
login: async () => {},
|
||||||
logout: async () => {},
|
logout: async () => {},
|
||||||
initSession: async () => {},
|
initSession: async () => {},
|
||||||
resumeSession: async () => {},
|
|
||||||
removeAccount: () => {},
|
removeAccount: () => {},
|
||||||
selectAccount: async () => {},
|
selectAccount: async () => {},
|
||||||
updateCurrentAccount: () => {},
|
updateCurrentAccount: () => {},
|
||||||
|
@ -67,7 +65,6 @@ type State = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Provider({children}: React.PropsWithChildren<{}>) {
|
export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||||
const [isInitialLoad, setIsInitialLoad] = React.useState(true)
|
|
||||||
const [isSwitchingAccounts, setIsSwitchingAccounts] = React.useState(false)
|
const [isSwitchingAccounts, setIsSwitchingAccounts] = React.useState(false)
|
||||||
const [state, setState] = React.useState<State>({
|
const [state, setState] = React.useState<State>({
|
||||||
accounts: persisted.get('session').accounts,
|
accounts: persisted.get('session').accounts,
|
||||||
|
@ -389,21 +386,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||||
[upsertAccount, clearCurrentAccount, createPersistSessionHandler],
|
[upsertAccount, clearCurrentAccount, createPersistSessionHandler],
|
||||||
)
|
)
|
||||||
|
|
||||||
const resumeSession = React.useCallback<SessionApiContext['resumeSession']>(
|
|
||||||
async account => {
|
|
||||||
try {
|
|
||||||
if (account) {
|
|
||||||
await initSession(account)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
logger.error(`session: resumeSession failed`, {message: e})
|
|
||||||
} finally {
|
|
||||||
setIsInitialLoad(false)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[initSession],
|
|
||||||
)
|
|
||||||
|
|
||||||
const removeAccount = React.useCallback<SessionApiContext['removeAccount']>(
|
const removeAccount = React.useCallback<SessionApiContext['removeAccount']>(
|
||||||
account => {
|
account => {
|
||||||
setState(s => {
|
setState(s => {
|
||||||
|
@ -547,11 +529,10 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||||
currentAccount: state.accounts.find(
|
currentAccount: state.accounts.find(
|
||||||
a => a.did === state.currentAccountDid,
|
a => a.did === state.currentAccountDid,
|
||||||
),
|
),
|
||||||
isInitialLoad,
|
|
||||||
isSwitchingAccounts,
|
isSwitchingAccounts,
|
||||||
hasSession: !!state.currentAccountDid,
|
hasSession: !!state.currentAccountDid,
|
||||||
}),
|
}),
|
||||||
[state, isInitialLoad, isSwitchingAccounts],
|
[state, isSwitchingAccounts],
|
||||||
)
|
)
|
||||||
|
|
||||||
const api = React.useMemo(
|
const api = React.useMemo(
|
||||||
|
@ -560,7 +541,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||||
login,
|
login,
|
||||||
logout,
|
logout,
|
||||||
initSession,
|
initSession,
|
||||||
resumeSession,
|
|
||||||
removeAccount,
|
removeAccount,
|
||||||
selectAccount,
|
selectAccount,
|
||||||
updateCurrentAccount,
|
updateCurrentAccount,
|
||||||
|
@ -571,7 +551,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||||
login,
|
login,
|
||||||
logout,
|
logout,
|
||||||
initSession,
|
initSession,
|
||||||
resumeSession,
|
|
||||||
removeAccount,
|
removeAccount,
|
||||||
selectAccount,
|
selectAccount,
|
||||||
updateCurrentAccount,
|
updateCurrentAccount,
|
||||||
|
|
|
@ -6,7 +6,6 @@ export type SessionAccount = PersistedAccount
|
||||||
export type SessionStateContext = {
|
export type SessionStateContext = {
|
||||||
accounts: SessionAccount[]
|
accounts: SessionAccount[]
|
||||||
currentAccount: SessionAccount | undefined
|
currentAccount: SessionAccount | undefined
|
||||||
isInitialLoad: boolean
|
|
||||||
isSwitchingAccounts: boolean
|
isSwitchingAccounts: boolean
|
||||||
hasSession: boolean
|
hasSession: boolean
|
||||||
}
|
}
|
||||||
|
@ -46,7 +45,6 @@ export type SessionApiContext = {
|
||||||
*/
|
*/
|
||||||
clearCurrentAccount: () => void
|
clearCurrentAccount: () => void
|
||||||
initSession: (account: SessionAccount) => Promise<void>
|
initSession: (account: SessionAccount) => Promise<void>
|
||||||
resumeSession: (account?: SessionAccount) => Promise<void>
|
|
||||||
removeAccount: (account: SessionAccount) => void
|
removeAccount: (account: SessionAccount) => void
|
||||||
selectAccount: (
|
selectAccount: (
|
||||||
account: SessionAccount,
|
account: SessionAccount,
|
||||||
|
|
Loading…
Reference in New Issue