migrate the actor search and autocomplete queries to the appview client
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,13 +6,14 @@ import {isJustAMute, moduiContainsHideableOffense} from '#/lib/moderation'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {STALE} from '#/state/queries'
|
||||
import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useAppviewClient} from '#/state/session'
|
||||
import {
|
||||
type AutocompleteApi,
|
||||
type AutocompleteItem,
|
||||
type AutocompleteItemType,
|
||||
type AutocompleteProfile,
|
||||
} from '#/components/Autocomplete/types'
|
||||
import {app} from '#/lexicons'
|
||||
import {useEmojiSearch} from './useEmojiSearch'
|
||||
|
||||
const DEFAULT_MOD_OPTS = {
|
||||
@@ -31,7 +32,7 @@ export function useAutocomplete({
|
||||
limit?: number
|
||||
showSearchFallback?: boolean
|
||||
}): AutocompleteApi {
|
||||
const agent = useAgent()
|
||||
const client = useAppviewClient()
|
||||
const moderationOpts = useModerationOpts()
|
||||
const emojiSearch = useEmojiSearch()
|
||||
|
||||
@@ -52,12 +53,12 @@ export function useAutocomplete({
|
||||
// Going from "foo" to "foo." should not clear matches.
|
||||
q = q.toLowerCase().trim().replace(/\.$/, '')
|
||||
|
||||
const res = await agent.searchActorsTypeahead({
|
||||
const data = await client.call(app.bsky.actor.searchActorsTypeahead, {
|
||||
q,
|
||||
limit: limit || 8,
|
||||
})
|
||||
|
||||
return (res?.data.actors || []).map(profile => ({
|
||||
return (data?.actors || []).map(profile => ({
|
||||
key: profile.did,
|
||||
type: 'profile' as const,
|
||||
value: '@' + profile.handle,
|
||||
|
||||
@@ -9,7 +9,8 @@ import {keepPreviousData, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
import {isJustAMute, moduiContainsHideableOffense} from '#/lib/moderation'
|
||||
import {logger} from '#/logger'
|
||||
import {STALE} from '#/state/queries'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useAppviewClient} from '#/state/session'
|
||||
import {app} from '#/lexicons'
|
||||
import {useModerationOpts} from '../preferences/moderation-opts'
|
||||
import {DEFAULT_LOGGED_OUT_PREFERENCES} from './preferences'
|
||||
|
||||
@@ -27,7 +28,7 @@ export function useActorAutocompleteQuery(
|
||||
limit?: number,
|
||||
) {
|
||||
const moderationOpts = useModerationOpts()
|
||||
const agent = useAgent()
|
||||
const client = useAppviewClient()
|
||||
|
||||
prefix = prefix.toLowerCase().trim()
|
||||
if (prefix.endsWith('.')) {
|
||||
@@ -39,13 +40,13 @@ export function useActorAutocompleteQuery(
|
||||
staleTime: STALE.MINUTES.ONE,
|
||||
queryKey: RQKEY(prefix || ''),
|
||||
async queryFn() {
|
||||
const res = prefix
|
||||
? await agent.searchActorsTypeahead({
|
||||
const data = prefix
|
||||
? await client.call(app.bsky.actor.searchActorsTypeahead, {
|
||||
q: prefix,
|
||||
limit: limit || 8,
|
||||
})
|
||||
: undefined
|
||||
return res?.data.actors || []
|
||||
return data?.actors || []
|
||||
},
|
||||
select: useCallback(
|
||||
(data: AppBskyActorDefs.ProfileViewBasic[]) => {
|
||||
@@ -65,7 +66,7 @@ export type ActorAutocompleteFn = ReturnType<typeof useActorAutocompleteFn>
|
||||
export function useActorAutocompleteFn() {
|
||||
const queryClient = useQueryClient()
|
||||
const moderationOpts = useModerationOpts()
|
||||
const agent = useAgent()
|
||||
const client = useAppviewClient()
|
||||
|
||||
return useCallback(
|
||||
async ({query, limit = 8}: {query: string; limit?: number}) => {
|
||||
@@ -77,7 +78,7 @@ export function useActorAutocompleteFn() {
|
||||
staleTime: STALE.MINUTES.ONE,
|
||||
queryKey: RQKEY(query || ''),
|
||||
queryFn: () =>
|
||||
agent.searchActorsTypeahead({
|
||||
client.call(app.bsky.actor.searchActorsTypeahead, {
|
||||
q: query,
|
||||
limit,
|
||||
}),
|
||||
@@ -91,11 +92,11 @@ export function useActorAutocompleteFn() {
|
||||
|
||||
return computeSuggestions({
|
||||
q: query,
|
||||
searched: res?.data.actors,
|
||||
searched: res?.actors,
|
||||
moderationOpts: moderationOpts || DEFAULT_MOD_OPTS,
|
||||
})
|
||||
},
|
||||
[queryClient, moderationOpts, agent],
|
||||
[queryClient, moderationOpts, client],
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorSearchActors} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
keepPreviousData,
|
||||
@@ -8,7 +7,8 @@ import {
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import {STALE} from '#/state/queries'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useAppviewClient} from '#/state/session'
|
||||
import {app} from '#/lexicons'
|
||||
|
||||
export const RQKEY_ROOT = 'actor-search'
|
||||
export const RQKEY = (query: string, limit?: number) => [
|
||||
@@ -28,23 +28,22 @@ export function useActorSearch({
|
||||
maintainData?: boolean
|
||||
limit?: number
|
||||
}) {
|
||||
const agent = useAgent()
|
||||
const client = useAppviewClient()
|
||||
return useInfiniteQuery<
|
||||
AppBskyActorSearchActors.OutputSchema,
|
||||
app.bsky.actor.searchActors.$OutputBody,
|
||||
Error,
|
||||
InfiniteData<AppBskyActorSearchActors.OutputSchema>,
|
||||
InfiniteData<app.bsky.actor.searchActors.$OutputBody>,
|
||||
QueryKey,
|
||||
string | undefined
|
||||
>({
|
||||
staleTime: STALE.MINUTES.FIVE,
|
||||
queryKey: RQKEY(query, limit),
|
||||
queryFn: async ({pageParam}) => {
|
||||
const res = await agent.searchActors({
|
||||
return await client.call(app.bsky.actor.searchActors, {
|
||||
q: query,
|
||||
limit,
|
||||
cursor: pageParam,
|
||||
})
|
||||
return res.data
|
||||
},
|
||||
enabled: enabled && !!query,
|
||||
initialPageParam: undefined,
|
||||
@@ -54,7 +53,7 @@ export function useActorSearch({
|
||||
})
|
||||
}
|
||||
|
||||
function select(data: InfiniteData<AppBskyActorSearchActors.OutputSchema>) {
|
||||
function select(data: InfiniteData<app.bsky.actor.searchActors.$OutputBody>) {
|
||||
// enforce uniqueness
|
||||
const dids = new Set()
|
||||
|
||||
@@ -77,7 +76,7 @@ export function* findAllProfilesInQueryData(
|
||||
did: string,
|
||||
) {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<AppBskyActorSearchActors.OutputSchema>
|
||||
InfiniteData<app.bsky.actor.searchActors.$OutputBody>
|
||||
>({
|
||||
queryKey: [RQKEY_ROOT],
|
||||
})
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import {type AtpAgent, AtUri} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type HandleString} from '@atproto/syntax'
|
||||
import {type QueryClient, queryOptions, useQuery} from '@tanstack/react-query'
|
||||
|
||||
import {STALE} from '#/state/queries'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useAppviewClient} from '#/state/session'
|
||||
import {com} from '#/lexicons'
|
||||
import {useUnstableProfileViewCache} from './profile'
|
||||
|
||||
const RQKEY_ROOT = 'resolved-did'
|
||||
export const RQKEY = (didOrHandle: string) => [RQKEY_ROOT, didOrHandle]
|
||||
|
||||
const resolvedDidQueryOptions = (
|
||||
agent: AtpAgent,
|
||||
client: Client,
|
||||
getUnstableProfile: (did: string) => {did: string} | undefined,
|
||||
didOrHandle: string | undefined,
|
||||
) =>
|
||||
@@ -21,8 +24,15 @@ const resolvedDidQueryOptions = (
|
||||
// Just return the did if it's already one
|
||||
if (didOrHandle.startsWith('did:')) return didOrHandle
|
||||
|
||||
const res = await agent.resolveHandle({handle: didOrHandle})
|
||||
return res.data.did
|
||||
/*
|
||||
* Resolution stays on the appview client: the old agent call was proxied
|
||||
* to the appview, and the PDS implementation is not equivalent for
|
||||
* handles hosted elsewhere.
|
||||
*/
|
||||
const data = await client.call(com.atproto.identity.resolveHandle, {
|
||||
handle: didOrHandle as HandleString,
|
||||
})
|
||||
return data.did
|
||||
},
|
||||
initialData: () => {
|
||||
// Return undefined if no did or handle
|
||||
@@ -37,11 +47,11 @@ export function useResolveUriQuery(uri: string | undefined) {
|
||||
const urip = new AtUri(uri || '')
|
||||
const host = urip.host
|
||||
|
||||
const agent = useAgent()
|
||||
const client = useAppviewClient()
|
||||
const {getUnstableProfile} = useUnstableProfileViewCache()
|
||||
|
||||
return useQuery({
|
||||
...resolvedDidQueryOptions(agent, getUnstableProfile, host),
|
||||
...resolvedDidQueryOptions(client, getUnstableProfile, host),
|
||||
select: did => ({
|
||||
did,
|
||||
uri: AtUri.make(did, urip.collection, urip.rkey).toString(),
|
||||
@@ -50,11 +60,11 @@ export function useResolveUriQuery(uri: string | undefined) {
|
||||
}
|
||||
|
||||
export function useResolveDidQuery(didOrHandle: string | undefined) {
|
||||
const agent = useAgent()
|
||||
const client = useAppviewClient()
|
||||
const {getUnstableProfile} = useUnstableProfileViewCache()
|
||||
|
||||
return useQuery(
|
||||
resolvedDidQueryOptions(agent, getUnstableProfile, didOrHandle),
|
||||
resolvedDidQueryOptions(client, getUnstableProfile, didOrHandle),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import {useCallback, useEffect, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {PressableScale} from '#/lib/custom-animations/PressableScale'
|
||||
import {STALE} from '#/state/queries'
|
||||
import {profilesQueryKey} from '#/state/queries/profile'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {useAppviewClient, useSession} from '#/state/session'
|
||||
import {useSetActiveLanding} from '#/state/shell/landing'
|
||||
import {
|
||||
useLoggedOutView,
|
||||
@@ -23,6 +24,7 @@ import {atoms as a, native, tokens, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon} from '#/components/Button'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {app} from '#/lexicons'
|
||||
import {SplashScreen} from './SplashScreen'
|
||||
|
||||
enum ScreenState {
|
||||
@@ -65,19 +67,18 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
const {accounts} = useSession()
|
||||
const agent = useAgent()
|
||||
const client = useAppviewClient()
|
||||
useEffect(() => {
|
||||
const actors = accounts.map(acc => acc.did)
|
||||
const actors = accounts.map(acc => acc.did as DidString)
|
||||
if (actors.length === 0) return
|
||||
void queryClient.prefetchQuery({
|
||||
queryKey: profilesQueryKey(actors),
|
||||
staleTime: STALE.MINUTES.FIVE,
|
||||
queryFn: async () => {
|
||||
const res = await agent.getProfiles({actors})
|
||||
return res.data
|
||||
return await client.call(app.bsky.actor.getProfiles, {actors})
|
||||
},
|
||||
})
|
||||
}, [accounts, agent, queryClient])
|
||||
}, [accounts, client, queryClient])
|
||||
|
||||
const onPressDismiss = useCallback(() => {
|
||||
if (onDismiss) {
|
||||
|
||||
Reference in New Issue
Block a user