diff options
Diffstat (limited to 'src/state/models/root-store.ts')
-rw-r--r-- | src/state/models/root-store.ts | 207 |
1 files changed, 0 insertions, 207 deletions
diff --git a/src/state/models/root-store.ts b/src/state/models/root-store.ts deleted file mode 100644 index 6d7c2c12e..000000000 --- a/src/state/models/root-store.ts +++ /dev/null @@ -1,207 +0,0 @@ -/** - * The root store is the base of all modeled state. - */ - -import {makeAutoObservable} from 'mobx' -import {BskyAgent} from '@atproto/api' -import {createContext, useContext} from 'react' -import {DeviceEventEmitter, EmitterSubscription} from 'react-native' -import {z} from 'zod' -import {isObj, hasProp} from 'lib/type-guards' -import {SessionModel} from './session' -import {ShellUiModel} from './ui/shell' -import {HandleResolutionsCache} from './cache/handle-resolutions' -import {ProfilesCache} from './cache/profiles-view' -import {PostsCache} from './cache/posts' -import {LinkMetasCache} from './cache/link-metas' -import {MeModel} from './me' -import {resetToTab} from '../../Navigation' -import {ImageSizesCache} from './cache/image-sizes' -import {reset as resetNavigation} from '../../Navigation' -import {logger} from '#/logger' - -// TEMPORARY (APP-700) -// remove after backend testing finishes -// -prf -import {applyDebugHeader} from 'lib/api/debug-appview-proxy-header' - -export const appInfo = z.object({ - build: z.string(), - name: z.string(), - namespace: z.string(), - version: z.string(), -}) -export type AppInfo = z.infer<typeof appInfo> - -export class RootStoreModel { - agent: BskyAgent - appInfo?: AppInfo - session = new SessionModel(this) - shell = new ShellUiModel(this) - me = new MeModel(this) - handleResolutions = new HandleResolutionsCache() - profiles = new ProfilesCache(this) - posts = new PostsCache(this) - linkMetas = new LinkMetasCache(this) - imageSizes = new ImageSizesCache() - - constructor(agent: BskyAgent) { - this.agent = agent - makeAutoObservable(this, { - agent: false, - serialize: false, - hydrate: false, - }) - } - - setAppInfo(info: AppInfo) { - this.appInfo = info - } - - serialize(): unknown { - return { - appInfo: this.appInfo, - me: this.me.serialize(), - } - } - - hydrate(v: unknown) { - if (isObj(v)) { - if (hasProp(v, 'appInfo')) { - const appInfoParsed = appInfo.safeParse(v.appInfo) - if (appInfoParsed.success) { - this.setAppInfo(appInfoParsed.data) - } - } - if (hasProp(v, 'me')) { - this.me.hydrate(v.me) - } - } - } - - /** - * Called during init to resume any stored session. - */ - async attemptSessionResumption() {} - - /** - * Called by the session model. Refreshes session-oriented state. - */ - async handleSessionChange( - agent: BskyAgent, - {hadSession}: {hadSession: boolean}, - ) { - logger.debug('RootStoreModel:handleSessionChange') - this.agent = agent - applyDebugHeader(this.agent) - this.me.clear() - await this.me.load() - if (!hadSession) { - await resetNavigation() - } - this.emitSessionReady() - } - - /** - * Called by the session model. Handles session drops by informing the user. - */ - async handleSessionDrop() { - logger.debug('RootStoreModel:handleSessionDrop') - resetToTab('HomeTab') - this.me.clear() - this.emitSessionDropped() - } - - /** - * Clears all session-oriented state, previously called on LOGOUT - */ - clearAllSessionState() { - logger.debug('RootStoreModel:clearAllSessionState') - resetToTab('HomeTab') - this.me.clear() - } - - /** - * Periodic poll for new session state. - */ - async updateSessionState() { - if (!this.session.hasSession) { - return - } - try { - await this.me.updateIfNeeded() - } catch (e: any) { - logger.error('Failed to fetch latest state', {error: e}) - } - } - - // global event bus - // = - // - some events need to be passed around between views and models - // in order to keep state in sync; these methods are for that - - // a post was deleted by the local user - onPostDeleted(handler: (uri: string) => void): EmitterSubscription { - return DeviceEventEmitter.addListener('post-deleted', handler) - } - emitPostDeleted(uri: string) { - DeviceEventEmitter.emit('post-deleted', uri) - } - - // a list was deleted by the local user - onListDeleted(handler: (uri: string) => void): EmitterSubscription { - return DeviceEventEmitter.addListener('list-deleted', handler) - } - emitListDeleted(uri: string) { - DeviceEventEmitter.emit('list-deleted', uri) - } - - // the session has started and been fully hydrated - onSessionLoaded(handler: () => void): EmitterSubscription { - return DeviceEventEmitter.addListener('session-loaded', handler) - } - emitSessionLoaded() { - DeviceEventEmitter.emit('session-loaded') - } - - // the session has completed all setup; good for post-initialization behaviors like triggering modals - onSessionReady(handler: () => void): EmitterSubscription { - return DeviceEventEmitter.addListener('session-ready', handler) - } - emitSessionReady() { - DeviceEventEmitter.emit('session-ready') - } - - // the session was dropped due to bad/expired refresh tokens - onSessionDropped(handler: () => void): EmitterSubscription { - return DeviceEventEmitter.addListener('session-dropped', handler) - } - emitSessionDropped() { - DeviceEventEmitter.emit('session-dropped') - } - - // the current screen has changed - // TODO is this still needed? - onNavigation(handler: () => void): EmitterSubscription { - return DeviceEventEmitter.addListener('navigation', handler) - } - emitNavigation() { - DeviceEventEmitter.emit('navigation') - } - - // a "soft reset" typically means scrolling to top and loading latest - // but it can depend on the screen - onScreenSoftReset(handler: () => void): EmitterSubscription { - return DeviceEventEmitter.addListener('screen-soft-reset', handler) - } - emitScreenSoftReset() { - DeviceEventEmitter.emit('screen-soft-reset') - } -} - -const throwawayInst = new RootStoreModel( - new BskyAgent({service: 'http://localhost'}), -) // this will be replaced by the loader, we just need to supply a value at init -const RootStoreContext = createContext<RootStoreModel>(throwawayInst) -export const RootStoreProvider = RootStoreContext.Provider -export const useStores = () => useContext(RootStoreContext) |