Bluesky app fork with some witchin' additions 馃挮
at main 124 lines 3.2 kB view raw
1import { 2 type AppBskyActorDefs, 3 AppBskyEmbedRecord, 4 type AppBskyFeedDefs, 5 type AppBskyFeedGetQuotes, 6 AtUri, 7} from '@atproto/api' 8import { 9 type InfiniteData, 10 type QueryClient, 11 type QueryKey, 12 useInfiniteQuery, 13} from '@tanstack/react-query' 14 15import {useAgent} from '#/state/session' 16import { 17 didOrHandleUriMatches, 18 embedViewRecordToPostView, 19 getEmbeddedPost, 20} from './util' 21 22const PAGE_SIZE = 30 23type RQPageParam = string | undefined 24 25const RQKEY_ROOT = 'post-quotes' 26export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri] 27 28export function usePostQuotesQuery(resolvedUri: string | undefined) { 29 const agent = useAgent() 30 return useInfiniteQuery< 31 AppBskyFeedGetQuotes.OutputSchema, 32 Error, 33 InfiniteData<AppBskyFeedGetQuotes.OutputSchema>, 34 QueryKey, 35 RQPageParam 36 >({ 37 queryKey: RQKEY(resolvedUri || ''), 38 async queryFn({pageParam}: {pageParam: RQPageParam}) { 39 const res = await agent.api.app.bsky.feed.getQuotes({ 40 uri: resolvedUri || '', 41 limit: PAGE_SIZE, 42 cursor: pageParam, 43 }) 44 return res.data 45 }, 46 initialPageParam: undefined, 47 getNextPageParam: lastPage => lastPage.cursor, 48 enabled: !!resolvedUri, 49 select: data => { 50 return { 51 ...data, 52 pages: data.pages.map(page => { 53 return { 54 ...page, 55 posts: page.posts.filter(post => { 56 if (post.embed && AppBskyEmbedRecord.isView(post.embed)) { 57 if (AppBskyEmbedRecord.isViewDetached(post.embed.record)) { 58 return false 59 } 60 } 61 return true 62 }), 63 } 64 }), 65 } 66 }, 67 }) 68} 69 70export function* findAllProfilesInQueryData( 71 queryClient: QueryClient, 72 did: string, 73): Generator<AppBskyActorDefs.ProfileViewBasic, void> { 74 const queryDatas = queryClient.getQueriesData< 75 InfiniteData<AppBskyFeedGetQuotes.OutputSchema> 76 >({ 77 queryKey: [RQKEY_ROOT], 78 }) 79 for (const [_queryKey, queryData] of queryDatas) { 80 if (!queryData?.pages) { 81 continue 82 } 83 for (const page of queryData?.pages) { 84 for (const item of page.posts) { 85 if (item.author.did === did) { 86 yield item.author 87 } 88 const quotedPost = getEmbeddedPost(item.embed) 89 if (quotedPost?.author.did === did) { 90 yield quotedPost.author 91 } 92 } 93 } 94 } 95} 96 97export function* findAllPostsInQueryData( 98 queryClient: QueryClient, 99 uri: string, 100): Generator<AppBskyFeedDefs.PostView, undefined> { 101 const queryDatas = queryClient.getQueriesData< 102 InfiniteData<AppBskyFeedGetQuotes.OutputSchema> 103 >({ 104 queryKey: [RQKEY_ROOT], 105 }) 106 const atUri = new AtUri(uri) 107 for (const [_queryKey, queryData] of queryDatas) { 108 if (!queryData?.pages) { 109 continue 110 } 111 for (const page of queryData?.pages) { 112 for (const post of page.posts) { 113 if (didOrHandleUriMatches(atUri, post)) { 114 yield post 115 } 116 117 const quotedPost = getEmbeddedPost(post.embed) 118 if (quotedPost && didOrHandleUriMatches(atUri, quotedPost)) { 119 yield embedViewRecordToPostView(quotedPost) 120 } 121 } 122 } 123 } 124}