forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {type AppBskyActorSearchActors} from '@atproto/api'
2import {
3 type InfiniteData,
4 keepPreviousData,
5 type QueryClient,
6 type QueryKey,
7 useInfiniteQuery,
8} from '@tanstack/react-query'
9
10import {STALE} from '#/state/queries'
11import {useAgent} from '#/state/session'
12
13export const RQKEY_ROOT = 'actor-search'
14export const RQKEY = (query: string, limit?: number) => [
15 RQKEY_ROOT,
16 query,
17 limit,
18]
19
20export function useActorSearch({
21 query,
22 enabled,
23 maintainData,
24 limit = 25,
25}: {
26 query: string
27 enabled?: boolean
28 maintainData?: boolean
29 limit?: number
30}) {
31 const agent = useAgent()
32 return useInfiniteQuery<
33 AppBskyActorSearchActors.OutputSchema,
34 Error,
35 InfiniteData<AppBskyActorSearchActors.OutputSchema>,
36 QueryKey,
37 string | undefined
38 >({
39 staleTime: STALE.MINUTES.FIVE,
40 queryKey: RQKEY(query, limit),
41 queryFn: async ({pageParam}) => {
42 const res = await agent.searchActors({
43 q: query,
44 limit,
45 cursor: pageParam,
46 })
47 return res.data
48 },
49 enabled: enabled && !!query,
50 initialPageParam: undefined,
51 getNextPageParam: lastPage => lastPage.cursor,
52 placeholderData: maintainData ? keepPreviousData : undefined,
53 select,
54 })
55}
56
57function select(data: InfiniteData<AppBskyActorSearchActors.OutputSchema>) {
58 // enforce uniqueness
59 const dids = new Set()
60
61 return {
62 ...data,
63 pages: data.pages.map(page => ({
64 actors: page.actors.filter(actor => {
65 if (dids.has(actor.did)) {
66 return false
67 }
68 dids.add(actor.did)
69 return true
70 }),
71 })),
72 }
73}
74
75export function* findAllProfilesInQueryData(
76 queryClient: QueryClient,
77 did: string,
78) {
79 const queryDatas = queryClient.getQueriesData<
80 InfiniteData<AppBskyActorSearchActors.OutputSchema>
81 >({
82 queryKey: [RQKEY_ROOT],
83 })
84 for (const [_queryKey, queryData] of queryDatas) {
85 if (!queryData) {
86 continue
87 }
88 for (const actor of queryData.pages.flatMap(page => page.actors)) {
89 if (actor.did === did) {
90 yield actor
91 }
92 }
93 }
94}