First pass at a session handler (#1850)
* First pass at a session handler * TODOs * Fix recursion * Couple more things * Add back resume session concept * Handle ready * Cleanup of initial loading states * Handle init failure * Cleanup * Remove account * Add updateCurrentAccount * Remove log * Cleanup * Integrate removeAccount * Add hasSession * Add to App.native, harden migration * Use effect to persist data
This commit is contained in:
parent
664e7a91a9
commit
625cbc435f
9 changed files with 488 additions and 56 deletions
|
@ -5,7 +5,7 @@ import {migrate} from '#/state/persisted/legacy'
|
|||
import * as store from '#/state/persisted/store'
|
||||
import BroadcastChannel from '#/state/persisted/broadcast'
|
||||
|
||||
export type {Schema} from '#/state/persisted/schema'
|
||||
export type {Schema, PersistedAccount} from '#/state/persisted/schema'
|
||||
export {defaults} from '#/state/persisted/schema'
|
||||
|
||||
const broadcast = new BroadcastChannel('BSKY_BROADCAST_CHANNEL')
|
||||
|
@ -50,7 +50,9 @@ export async function write<K extends keyof Schema>(
|
|||
await store.write(_state)
|
||||
// must happen on next tick, otherwise the tab will read stale storage data
|
||||
setTimeout(() => broadcast.postMessage({event: UPDATE_EVENT}), 0)
|
||||
logger.debug(`persisted state: wrote root state to storage`)
|
||||
logger.debug(`persisted state: wrote root state to storage`, {
|
||||
updatedKey: key,
|
||||
})
|
||||
} catch (e) {
|
||||
logger.error(`persisted state: failed writing root state to storage`, {
|
||||
error: e,
|
||||
|
|
|
@ -66,43 +66,45 @@ type LegacySchema = {
|
|||
|
||||
const DEPRECATED_ROOT_STATE_STORAGE_KEY = 'root'
|
||||
|
||||
export function transform(legacy: LegacySchema): Schema {
|
||||
// TODO remove, assume that partial data may be here during our refactor
|
||||
export function transform(legacy: Partial<LegacySchema>): Schema {
|
||||
return {
|
||||
colorMode: legacy.shell?.colorMode || defaults.colorMode,
|
||||
session: {
|
||||
accounts: legacy.session.accounts || defaults.session.accounts,
|
||||
accounts: legacy.session?.accounts || defaults.session.accounts,
|
||||
currentAccount:
|
||||
legacy.session.accounts.find(a => a.did === legacy.session.data.did) ||
|
||||
defaults.session.currentAccount,
|
||||
legacy.session?.accounts?.find(
|
||||
a => a.did === legacy.session?.data?.did,
|
||||
) || defaults.session.currentAccount,
|
||||
},
|
||||
reminders: {
|
||||
lastEmailConfirm:
|
||||
legacy.reminders.lastEmailConfirm ||
|
||||
legacy.reminders?.lastEmailConfirm ||
|
||||
defaults.reminders.lastEmailConfirm,
|
||||
},
|
||||
languagePrefs: {
|
||||
primaryLanguage:
|
||||
legacy.preferences.primaryLanguage ||
|
||||
legacy.preferences?.primaryLanguage ||
|
||||
defaults.languagePrefs.primaryLanguage,
|
||||
contentLanguages:
|
||||
legacy.preferences.contentLanguages ||
|
||||
legacy.preferences?.contentLanguages ||
|
||||
defaults.languagePrefs.contentLanguages,
|
||||
postLanguage:
|
||||
legacy.preferences.postLanguage || defaults.languagePrefs.postLanguage,
|
||||
legacy.preferences?.postLanguage || defaults.languagePrefs.postLanguage,
|
||||
postLanguageHistory:
|
||||
legacy.preferences.postLanguageHistory ||
|
||||
legacy.preferences?.postLanguageHistory ||
|
||||
defaults.languagePrefs.postLanguageHistory,
|
||||
},
|
||||
requireAltTextEnabled:
|
||||
legacy.preferences.requireAltTextEnabled ||
|
||||
legacy.preferences?.requireAltTextEnabled ||
|
||||
defaults.requireAltTextEnabled,
|
||||
mutedThreads: legacy.mutedThreads.uris || defaults.mutedThreads,
|
||||
mutedThreads: legacy.mutedThreads?.uris || defaults.mutedThreads,
|
||||
invites: {
|
||||
copiedInvites:
|
||||
legacy.invitedUsers.copiedInvites || defaults.invites.copiedInvites,
|
||||
legacy.invitedUsers?.copiedInvites || defaults.invites.copiedInvites,
|
||||
},
|
||||
onboarding: {
|
||||
step: legacy.onboarding.step || defaults.onboarding.step,
|
||||
step: legacy.onboarding?.step || defaults.onboarding.step,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,17 @@ import {z} from 'zod'
|
|||
import {deviceLocales} from '#/platform/detection'
|
||||
|
||||
// only data needed for rendering account page
|
||||
// TODO agent.resumeSession requires the following fields
|
||||
const accountSchema = z.object({
|
||||
service: z.string(),
|
||||
did: z.string(),
|
||||
refreshJwt: z.string().optional(),
|
||||
accessJwt: z.string().optional(),
|
||||
handle: z.string().optional(),
|
||||
displayName: z.string().optional(),
|
||||
aviUrl: z.string().optional(),
|
||||
handle: z.string(),
|
||||
refreshJwt: z.string().optional(), // optional because it can expire
|
||||
accessJwt: z.string().optional(), // optional because it can expire
|
||||
// displayName: z.string().optional(),
|
||||
// aviUrl: z.string().optional(),
|
||||
})
|
||||
export type PersistedAccount = z.infer<typeof accountSchema>
|
||||
|
||||
export const schema = z.object({
|
||||
colorMode: z.enum(['system', 'light', 'dark']),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue