about summary refs log tree commit diff
path: root/src/state/queries
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-08-21 21:26:25 +0100
committerGitHub <noreply@github.com>2024-08-21 15:26:25 -0500
commit56ab5e177fa2b24d0e5d9d969aa37532b96128da (patch)
tree2fa3db0ef9e46474aac00d5a593c5e5d592da9e3 /src/state/queries
parentddb0b80017c2b5bc158b8ff9da222abd5a8bf025 (diff)
downloadvoidsky-56ab5e177fa2b24d0e5d9d969aa37532b96128da.tar.zst
Show quote posts (#4865)
* show quote posts

* fix filter

* fix keyExtractor

* move likedby and repostedby to new file structure

* use modern list component

* remove relative imports

* update quotes count after quoting

* call `onPost` after updating quote count

* Revert "update quotes count after quoting"

This reverts commit 1f1887730a210c57c1e5a0eb0f47c42c42cf1b4b.

* implement

* update like count in quotes list

* only add `onPostReply` where needed

* Filter quotes with detached embeds

* Bump SDK

* Don't show error for no results

---------

Co-authored-by: Samuel Newman <10959775+mozzius@users.noreply.github.com>
Co-authored-by: Hailey <me@haileyok.com>
Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/state/queries')
-rw-r--r--src/state/queries/post-quotes.ts124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/state/queries/post-quotes.ts b/src/state/queries/post-quotes.ts
new file mode 100644
index 000000000..be51eaab0
--- /dev/null
+++ b/src/state/queries/post-quotes.ts
@@ -0,0 +1,124 @@
+import {
+  AppBskyActorDefs,
+  AppBskyEmbedRecord,
+  AppBskyFeedDefs,
+  AppBskyFeedGetQuotes,
+  AtUri,
+} from '@atproto/api'
+import {
+  InfiniteData,
+  QueryClient,
+  QueryKey,
+  useInfiniteQuery,
+} from '@tanstack/react-query'
+
+import {useAgent} from '#/state/session'
+import {
+  didOrHandleUriMatches,
+  embedViewRecordToPostView,
+  getEmbeddedPost,
+} from './util'
+
+const PAGE_SIZE = 30
+type RQPageParam = string | undefined
+
+const RQKEY_ROOT = 'post-quotes'
+export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri]
+
+export function usePostQuotesQuery(resolvedUri: string | undefined) {
+  const agent = useAgent()
+  return useInfiniteQuery<
+    AppBskyFeedGetQuotes.OutputSchema,
+    Error,
+    InfiniteData<AppBskyFeedGetQuotes.OutputSchema>,
+    QueryKey,
+    RQPageParam
+  >({
+    queryKey: RQKEY(resolvedUri || ''),
+    async queryFn({pageParam}: {pageParam: RQPageParam}) {
+      const res = await agent.api.app.bsky.feed.getQuotes({
+        uri: resolvedUri || '',
+        limit: PAGE_SIZE,
+        cursor: pageParam,
+      })
+      return res.data
+    },
+    initialPageParam: undefined,
+    getNextPageParam: lastPage => lastPage.cursor,
+    enabled: !!resolvedUri,
+    select: data => {
+      return {
+        ...data,
+        pages: data.pages.map(page => {
+          return {
+            ...page,
+            posts: page.posts.filter(post => {
+              if (post.embed && AppBskyEmbedRecord.isView(post.embed)) {
+                if (AppBskyEmbedRecord.isViewDetached(post.embed.record)) {
+                  return false
+                }
+              }
+              return true
+            }),
+          }
+        }),
+      }
+    },
+  })
+}
+
+export function* findAllProfilesInQueryData(
+  queryClient: QueryClient,
+  did: string,
+): Generator<AppBskyActorDefs.ProfileView, void> {
+  const queryDatas = queryClient.getQueriesData<
+    InfiniteData<AppBskyFeedGetQuotes.OutputSchema>
+  >({
+    queryKey: [RQKEY_ROOT],
+  })
+  for (const [_queryKey, queryData] of queryDatas) {
+    if (!queryData?.pages) {
+      continue
+    }
+    for (const page of queryData?.pages) {
+      for (const item of page.posts) {
+        if (item.author.did === did) {
+          yield item.author
+        }
+        const quotedPost = getEmbeddedPost(item.embed)
+        if (quotedPost?.author.did === did) {
+          yield quotedPost.author
+        }
+      }
+    }
+  }
+}
+
+export function* findAllPostsInQueryData(
+  queryClient: QueryClient,
+  uri: string,
+): Generator<AppBskyFeedDefs.PostView, undefined> {
+  const queryDatas = queryClient.getQueriesData<
+    InfiniteData<AppBskyFeedGetQuotes.OutputSchema>
+  >({
+    queryKey: [RQKEY_ROOT],
+  })
+  const atUri = new AtUri(uri)
+  for (const [_queryKey, queryData] of queryDatas) {
+    if (!queryData?.pages) {
+      continue
+    }
+    for (const page of queryData?.pages) {
+      for (const post of page.posts) {
+        if (didOrHandleUriMatches(atUri, post)) {
+          yield post
+        }
+
+        const quotedPost = getEmbeddedPost(post.embed)
+        if (quotedPost && didOrHandleUriMatches(atUri, quotedPost)) {
+          yield embedViewRecordToPostView(quotedPost)
+        }
+      }
+    }
+  }
+}