Bluesky app fork with some witchin' additions 馃挮
fork

Configure Feed

Select the types of activity you want to include in your feed.

at readme-update 133 lines 3.4 kB view raw
1import { 2 type AppBskyActorDefs, 3 type AppBskyGraphDefs, 4 type AppBskyGraphGetList, 5 type BskyAgent, 6} from '@atproto/api' 7import { 8 type InfiniteData, 9 type QueryClient, 10 type QueryKey, 11 useInfiniteQuery, 12 useQuery, 13} from '@tanstack/react-query' 14 15import {STALE} from '#/state/queries' 16import {useAgent} from '#/state/session' 17 18const PAGE_SIZE = 30 19type RQPageParam = string | undefined 20 21const RQKEY_ROOT = 'list-members' 22const RQKEY_ROOT_ALL = 'list-members-all' 23export const RQKEY = (uri: string) => [RQKEY_ROOT, uri] 24export const RQKEY_ALL = (uri: string) => [RQKEY_ROOT_ALL, uri] 25 26export function useListMembersQuery(uri?: string, limit: number = PAGE_SIZE) { 27 const agent = useAgent() 28 return useInfiniteQuery< 29 AppBskyGraphGetList.OutputSchema, 30 Error, 31 InfiniteData<AppBskyGraphGetList.OutputSchema>, 32 QueryKey, 33 RQPageParam 34 >({ 35 staleTime: STALE.MINUTES.ONE, 36 queryKey: RQKEY(uri ?? ''), 37 async queryFn({pageParam}: {pageParam: RQPageParam}) { 38 const res = await agent.app.bsky.graph.getList({ 39 list: uri!, // the enabled flag will prevent this from running until uri is set 40 limit, 41 cursor: pageParam, 42 }) 43 return res.data 44 }, 45 initialPageParam: undefined, 46 getNextPageParam: lastPage => lastPage.cursor, 47 enabled: Boolean(uri), 48 }) 49} 50 51export function useAllListMembersQuery(uri?: string) { 52 const agent = useAgent() 53 return useQuery({ 54 staleTime: STALE.MINUTES.ONE, 55 queryKey: RQKEY_ALL(uri ?? ''), 56 queryFn: async () => { 57 return getAllListMembers(agent, uri!) 58 }, 59 enabled: Boolean(uri), 60 }) 61} 62 63export async function getAllListMembers(agent: BskyAgent, uri: string) { 64 let hasMore = true 65 let cursor: string | undefined 66 const listItems: AppBskyGraphDefs.ListItemView[] = [] 67 // We want to cap this at 6 pages, just for anything weird happening with the api 68 let i = 0 69 while (hasMore && i < 6) { 70 const res = await agent.app.bsky.graph.getList({ 71 list: uri, 72 limit: 50, 73 cursor, 74 }) 75 listItems.push(...res.data.items) 76 hasMore = Boolean(res.data.cursor) 77 cursor = res.data.cursor 78 i++ 79 } 80 return listItems 81} 82 83export async function invalidateListMembersQuery({ 84 queryClient, 85 uri, 86}: { 87 queryClient: QueryClient 88 uri: string 89}) { 90 await queryClient.invalidateQueries({queryKey: RQKEY(uri)}) 91} 92 93export function* findAllProfilesInQueryData( 94 queryClient: QueryClient, 95 did: string, 96): Generator<AppBskyActorDefs.ProfileView, void> { 97 const queryDatas = queryClient.getQueriesData< 98 InfiniteData<AppBskyGraphGetList.OutputSchema> 99 >({ 100 queryKey: [RQKEY_ROOT], 101 }) 102 for (const [_queryKey, queryData] of queryDatas) { 103 if (!queryData?.pages) { 104 continue 105 } 106 for (const page of queryData?.pages) { 107 if (page.list.creator.did === did) { 108 yield page.list.creator 109 } 110 for (const item of page.items) { 111 if (item.subject.did === did) { 112 yield item.subject 113 } 114 } 115 } 116 } 117 118 const allQueryData = queryClient.getQueriesData< 119 AppBskyGraphDefs.ListItemView[] 120 >({ 121 queryKey: [RQKEY_ROOT_ALL], 122 }) 123 for (const [_queryKey, queryData] of allQueryData) { 124 if (!queryData) { 125 continue 126 } 127 for (const item of queryData) { 128 if (item.subject.did === did) { 129 yield item.subject 130 } 131 } 132 } 133}