[Session] Derive currentAccount from accounts + currentAccountDid (#3795)

* Derive currentAccount from accounts and currentAccountDid

* Add TODOs for divergence with __globalAgent
zio/stable
dan 2024-05-01 17:35:27 +01:00 committed by GitHub
parent df9af92eb2
commit d61b366b26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 28 additions and 22 deletions

View File

@ -62,7 +62,7 @@ function __getAgent() {
type State = { type State = {
accounts: SessionStateContext['accounts'] accounts: SessionStateContext['accounts']
currentAccount: SessionStateContext['currentAccount'] currentAccountDid: string | undefined
needsPersist: boolean needsPersist: boolean
} }
@ -71,7 +71,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
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,
currentAccount: undefined, // assume logged out to start currentAccountDid: undefined, // assume logged out to start
needsPersist: false, needsPersist: false,
}) })
@ -80,7 +80,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
setState(s => { setState(s => {
return { return {
accounts: [account, ...s.accounts.filter(a => a.did !== account.did)], accounts: [account, ...s.accounts.filter(a => a.did !== account.did)],
currentAccount: expired ? undefined : account, currentAccountDid: expired ? undefined : account.did,
needsPersist: true, needsPersist: true,
} }
}) })
@ -94,7 +94,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
configureModerationForGuest() configureModerationForGuest()
setState(s => ({ setState(s => ({
accounts: s.accounts, accounts: s.accounts,
currentAccount: undefined, currentAccountDid: undefined,
needsPersist: true, needsPersist: true,
})) }))
}, [setState]) }, [setState])
@ -265,7 +265,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
refreshJwt: undefined, refreshJwt: undefined,
accessJwt: undefined, accessJwt: undefined,
})), })),
currentAccount: s.currentAccount, currentAccountDid: s.currentAccountDid,
needsPersist: true, needsPersist: true,
} }
}) })
@ -329,6 +329,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
}) })
__globalAgent = PUBLIC_BSKY_AGENT __globalAgent = PUBLIC_BSKY_AGENT
// TODO: Should this update currentAccountDid?
} }
} else { } else {
logger.debug(`session: attempting to reuse previous session`) logger.debug(`session: attempting to reuse previous session`)
@ -366,6 +367,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
}) })
__globalAgent = PUBLIC_BSKY_AGENT __globalAgent = PUBLIC_BSKY_AGENT
// TODO: Should this update currentAccountDid?
}) })
} }
@ -407,7 +409,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
setState(s => { setState(s => {
return { return {
accounts: s.accounts.filter(a => a.did !== account.did), accounts: s.accounts.filter(a => a.did !== account.did),
currentAccount: s.currentAccount, currentAccountDid: s.currentAccountDid,
needsPersist: true, needsPersist: true,
} }
}) })
@ -420,8 +422,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
>( >(
account => { account => {
setState(s => { setState(s => {
const currentAccount = s.currentAccount const currentAccount = s.accounts.find(
a => a.did === s.currentAccountDid,
)
// ignore, should never happen // ignore, should never happen
if (!currentAccount) return s if (!currentAccount) return s
@ -444,7 +447,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
updatedAccount, updatedAccount,
...s.accounts.filter(a => a.did !== currentAccount.did), ...s.accounts.filter(a => a.did !== currentAccount.did),
], ],
currentAccount: updatedAccount, currentAccountDid: s.currentAccountDid,
needsPersist: true, needsPersist: true,
} }
}) })
@ -474,31 +477,31 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
state.needsPersist = false state.needsPersist = false
persisted.write('session', { persisted.write('session', {
accounts: state.accounts, accounts: state.accounts,
currentAccount: state.currentAccount, currentAccount: state.accounts.find(
a => a.did === state.currentAccountDid,
),
}) })
} }
}, [state]) }, [state])
React.useEffect(() => { React.useEffect(() => {
return persisted.onUpdate(() => { return persisted.onUpdate(() => {
const session = persisted.get('session') const persistedSession = persisted.get('session')
logger.debug(`session: persisted onUpdate`, {}) logger.debug(`session: persisted onUpdate`, {})
const selectedAccount = session.accounts.find( const selectedAccount = persistedSession.accounts.find(
a => a.did === session.currentAccount?.did, a => a.did === persistedSession.currentAccount?.did,
) )
if (selectedAccount && selectedAccount.refreshJwt) { if (selectedAccount && selectedAccount.refreshJwt) {
if (selectedAccount.did !== state.currentAccount?.did) { if (selectedAccount.did !== state.currentAccountDid) {
logger.debug(`session: persisted onUpdate, switching accounts`, { logger.debug(`session: persisted onUpdate, switching accounts`, {
from: { from: {
did: state.currentAccount?.did, did: state.currentAccountDid,
handle: state.currentAccount?.handle,
}, },
to: { to: {
did: selectedAccount.did, did: selectedAccount.did,
handle: selectedAccount.handle,
}, },
}) })
@ -514,7 +517,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
// @ts-ignore we checked for `refreshJwt` above // @ts-ignore we checked for `refreshJwt` above
__globalAgent.session = selectedAccount __globalAgent.session = selectedAccount
} }
} else if (!selectedAccount && state.currentAccount) { } else if (!selectedAccount && state.currentAccountDid) {
logger.debug( logger.debug(
`session: persisted onUpdate, logging out`, `session: persisted onUpdate, logging out`,
{}, {},
@ -531,8 +534,8 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
} }
setState(() => ({ setState(() => ({
accounts: session.accounts, accounts: persistedSession.accounts,
currentAccount: selectedAccount, currentAccountDid: selectedAccount?.did,
needsPersist: false, // Synced from another tab. Don't persist to avoid cycles. needsPersist: false, // Synced from another tab. Don't persist to avoid cycles.
})) }))
}) })
@ -540,10 +543,13 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
const stateContext = React.useMemo( const stateContext = React.useMemo(
() => ({ () => ({
...state, accounts: state.accounts,
currentAccount: state.accounts.find(
a => a.did === state.currentAccountDid,
),
isInitialLoad, isInitialLoad,
isSwitchingAccounts, isSwitchingAccounts,
hasSession: !!state.currentAccount, hasSession: !!state.currentAccountDid,
}), }),
[state, isInitialLoad, isSwitchingAccounts], [state, isInitialLoad, isSwitchingAccounts],
) )