diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-11-16 12:53:43 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-16 12:53:43 -0800 |
commit | 54faa7e176ed2f8644ef4941c8a65522107a84c1 (patch) | |
tree | 336d69d37809041dcc38a932975fcf438ac60dfd /src/lib | |
parent | e637798e05ba3bfc1c78be1b0f70e8b0ac22554d (diff) | |
download | voidsky-54faa7e176ed2f8644ef4941c8a65522107a84c1.tar.zst |
Remove deprecated models and mobx usage (react-query refactor) (#1934)
* Update login page to use service query * Update modal to use session instead of store * Move image sizes cache off store * Update settings to no longer use store * Update link-meta fetch to use agent instead of rootstore * Remove deprecated resolveName() * Delete deprecated link-metas cache * Delete deprecated posts cache * Delete all remaining mobx models, including the root store * Strip out unused mobx observer wrappers
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/analytics/analytics.tsx | 18 | ||||
-rw-r--r-- | src/lib/api/index.ts | 28 | ||||
-rw-r--r-- | src/lib/async/revertible.ts | 68 | ||||
-rw-r--r-- | src/lib/link-meta/bsky.ts | 13 | ||||
-rw-r--r-- | src/lib/link-meta/link-meta.ts | 12 | ||||
-rw-r--r-- | src/lib/media/image-sizes.ts | 34 | ||||
-rw-r--r-- | src/lib/strings/url-helpers.ts | 2 |
7 files changed, 62 insertions, 113 deletions
diff --git a/src/lib/analytics/analytics.tsx b/src/lib/analytics/analytics.tsx index 4b955b365..3a8254eb1 100644 --- a/src/lib/analytics/analytics.tsx +++ b/src/lib/analytics/analytics.tsx @@ -7,13 +7,21 @@ import { useAnalytics as useAnalyticsOrig, ClientMethods, } from '@segment/analytics-react-native' -import {AppInfo} from 'state/models/root-store' +import {z} from 'zod' import {useSession} from '#/state/session' import {sha256} from 'js-sha256' import {ScreenEvent, TrackEvent} from './types' import {logger} from '#/logger' import {listenSessionLoaded} from '#/state/events' +export const appInfo = z.object({ + build: z.string().optional(), + name: z.string().optional(), + namespace: z.string().optional(), + version: z.string().optional(), +}) +export type AppInfo = z.infer<typeof appInfo> + const segmentClient = createClient({ writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI', trackAppLifecycleEvents: false, @@ -128,7 +136,11 @@ async function writeAppInfo(value: AppInfo) { await AsyncStorage.setItem('BSKY_APP_INFO', JSON.stringify(value)) } -async function readAppInfo(): Promise<Partial<AppInfo> | undefined> { +async function readAppInfo(): Promise<AppInfo | undefined> { const rawData = await AsyncStorage.getItem('BSKY_APP_INFO') - return rawData ? JSON.parse(rawData) : undefined + const obj = rawData ? JSON.parse(rawData) : undefined + if (!obj || typeof obj !== 'object') { + return undefined + } + return obj } diff --git a/src/lib/api/index.ts b/src/lib/api/index.ts index 92620c459..a78abcacd 100644 --- a/src/lib/api/index.ts +++ b/src/lib/api/index.ts @@ -10,7 +10,6 @@ import { RichText, } from '@atproto/api' import {AtUri} from '@atproto/api' -import {RootStoreModel} from 'state/models/root-store' import {isNetworkError} from 'lib/strings/errors' import {LinkMeta} from '../link-meta/link-meta' import {isWeb} from 'platform/detection' @@ -26,33 +25,6 @@ export interface ExternalEmbedDraft { localThumb?: ImageModel } -export async function resolveName(store: RootStoreModel, didOrHandle: string) { - if (!didOrHandle) { - throw new Error('Invalid handle: ""') - } - if (didOrHandle.startsWith('did:')) { - return didOrHandle - } - - // we run the resolution always to ensure freshness - const promise = store.agent - .resolveHandle({ - handle: didOrHandle, - }) - .then(res => { - store.handleResolutions.cache.set(didOrHandle, res.data.did) - return res.data.did - }) - - // but we can return immediately if it's cached - const cached = store.handleResolutions.cache.get(didOrHandle) - if (cached) { - return cached - } - - return promise -} - export async function uploadBlob( agent: BskyAgent, blob: string, diff --git a/src/lib/async/revertible.ts b/src/lib/async/revertible.ts deleted file mode 100644 index 43383b61e..000000000 --- a/src/lib/async/revertible.ts +++ /dev/null @@ -1,68 +0,0 @@ -import {runInAction} from 'mobx' -import {deepObserve} from 'mobx-utils' -import set from 'lodash.set' - -const ongoingActions = new Set<any>() - -/** - * This is a TypeScript function that optimistically updates data on the client-side before sending a - * request to the server and rolling back changes if the request fails. - * @param {T} model - The object or record that needs to be updated optimistically. - * @param preUpdate - `preUpdate` is a function that is called before the server update is executed. It - * can be used to perform any necessary actions or updates on the model or UI before the server update - * is initiated. - * @param serverUpdate - `serverUpdate` is a function that returns a Promise representing the server - * update operation. This function is called after the previous state of the model has been recorded - * and the `preUpdate` function has been executed. If the server update is successful, the `postUpdate` - * function is called with the result - * @param [postUpdate] - `postUpdate` is an optional callback function that will be called after the - * server update is successful. It takes in the response from the server update as its parameter. If - * this parameter is not provided, nothing will happen after the server update. - * @returns A Promise that resolves to `void`. - */ -export const updateDataOptimistically = async < - T extends Record<string, any>, - U, ->( - model: T, - preUpdate: () => void, - serverUpdate: () => Promise<U>, - postUpdate?: (res: U) => void, -): Promise<void> => { - if (ongoingActions.has(model)) { - return - } - ongoingActions.add(model) - - const prevState: Map<string, any> = new Map<string, any>() - const dispose = deepObserve(model, (change, path) => { - if (change.observableKind === 'object') { - if (change.type === 'update') { - prevState.set( - [path, change.name].filter(Boolean).join('.'), - change.oldValue, - ) - } else if (change.type === 'add') { - prevState.set([path, change.name].filter(Boolean).join('.'), undefined) - } - } - }) - preUpdate() - dispose() - - try { - const res = await serverUpdate() - runInAction(() => { - postUpdate?.(res) - }) - } catch (error) { - runInAction(() => { - prevState.forEach((value, path) => { - set(model, path, value) - }) - }) - throw error - } finally { - ongoingActions.delete(model) - } -} diff --git a/src/lib/link-meta/bsky.ts b/src/lib/link-meta/bsky.ts index 78d755331..322b02332 100644 --- a/src/lib/link-meta/bsky.ts +++ b/src/lib/link-meta/bsky.ts @@ -1,9 +1,8 @@ -import {AppBskyFeedPost} from '@atproto/api' +import {AppBskyFeedPost, BskyAgent} from '@atproto/api' import * as apilib from 'lib/api/index' import {LikelyType, LinkMeta} from './link-meta' // import {match as matchRoute} from 'view/routes' import {convertBskyAppUrlIfNeeded, makeRecordUri} from '../strings/url-helpers' -import {RootStoreModel} from 'state/index' import {ComposerOptsQuote} from 'state/shell/composer' import {useGetPost} from '#/state/queries/post' @@ -23,7 +22,7 @@ import {useGetPost} from '#/state/queries/post' // remove once that's implemented // -prf export async function extractBskyMeta( - store: RootStoreModel, + agent: BskyAgent, url: string, ): Promise<LinkMeta> { url = convertBskyAppUrlIfNeeded(url) @@ -120,13 +119,13 @@ export async function getPostAsQuote( } export async function getFeedAsEmbed( - store: RootStoreModel, + agent: BskyAgent, url: string, ): Promise<apilib.ExternalEmbedDraft> { url = convertBskyAppUrlIfNeeded(url) const [_0, user, _1, rkey] = url.split('/').filter(Boolean) const feed = makeRecordUri(user, 'app.bsky.feed.generator', rkey) - const res = await store.agent.app.bsky.feed.getFeedGenerator({feed}) + const res = await agent.app.bsky.feed.getFeedGenerator({feed}) return { isLoading: false, uri: feed, @@ -146,13 +145,13 @@ export async function getFeedAsEmbed( } export async function getListAsEmbed( - store: RootStoreModel, + agent: BskyAgent, url: string, ): Promise<apilib.ExternalEmbedDraft> { url = convertBskyAppUrlIfNeeded(url) const [_0, user, _1, rkey] = url.split('/').filter(Boolean) const list = makeRecordUri(user, 'app.bsky.graph.list', rkey) - const res = await store.agent.app.bsky.graph.getList({list}) + const res = await agent.app.bsky.graph.getList({list}) return { isLoading: false, uri: list, diff --git a/src/lib/link-meta/link-meta.ts b/src/lib/link-meta/link-meta.ts index c490fa292..c17dee51f 100644 --- a/src/lib/link-meta/link-meta.ts +++ b/src/lib/link-meta/link-meta.ts @@ -1,5 +1,5 @@ +import {BskyAgent} from '@atproto/api' import {isBskyAppUrl} from '../strings/url-helpers' -import {RootStoreModel} from 'state/index' import {extractBskyMeta} from './bsky' import {LINK_META_PROXY} from 'lib/constants' @@ -23,12 +23,12 @@ export interface LinkMeta { } export async function getLinkMeta( - store: RootStoreModel, + agent: BskyAgent, url: string, timeout = 5e3, ): Promise<LinkMeta> { if (isBskyAppUrl(url)) { - return extractBskyMeta(store, url) + return extractBskyMeta(agent, url) } let urlp @@ -55,9 +55,9 @@ export async function getLinkMeta( const to = setTimeout(() => controller.abort(), timeout || 5e3) const response = await fetch( - `${LINK_META_PROXY( - store.session.currentSession?.service || '', - )}${encodeURIComponent(url)}`, + `${LINK_META_PROXY(agent.service.toString() || '')}${encodeURIComponent( + url, + )}`, {signal: controller.signal}, ) diff --git a/src/lib/media/image-sizes.ts b/src/lib/media/image-sizes.ts new file mode 100644 index 000000000..4ea95ea23 --- /dev/null +++ b/src/lib/media/image-sizes.ts @@ -0,0 +1,34 @@ +import {Image} from 'react-native' +import type {Dimensions} from 'lib/media/types' + +const sizes: Map<string, Dimensions> = new Map() +const activeRequests: Map<string, Promise<Dimensions>> = new Map() + +export function get(uri: string): Dimensions | undefined { + return sizes.get(uri) +} + +export async function fetch(uri: string): Promise<Dimensions> { + const Dimensions = sizes.get(uri) + if (Dimensions) { + return Dimensions + } + + const prom = + activeRequests.get(uri) || + new Promise<Dimensions>(resolve => { + Image.getSize( + uri, + (width: number, height: number) => resolve({width, height}), + (err: any) => { + console.error('Failed to fetch image dimensions for', uri, err) + resolve({width: 0, height: 0}) + }, + ) + }) + activeRequests.set(uri, prom) + const res = await prom + activeRequests.delete(uri) + sizes.set(uri, res) + return res +} diff --git a/src/lib/strings/url-helpers.ts b/src/lib/strings/url-helpers.ts index 106d2ca31..d06bd8028 100644 --- a/src/lib/strings/url-helpers.ts +++ b/src/lib/strings/url-helpers.ts @@ -1,5 +1,5 @@ import {AtUri} from '@atproto/api' -import {PROD_SERVICE} from 'state/index' +import {PROD_SERVICE} from 'lib/constants' import TLDs from 'tlds' import psl from 'psl' |