about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2024-08-19 11:20:42 -0500
committerGitHub <noreply@github.com>2024-08-19 11:20:42 -0500
commit3976d6738b30e36c563ae3271768334edede0d5d (patch)
tree1fbee0fb7a385b1730d792beca5f88e708945fe8 /src
parent2939ee7df751eef4c3e673e321c6b900847d43d9 (diff)
downloadvoidsky-3976d6738b30e36c563ae3271768334edede0d5d.tar.zst
Fix orphaned feed slices, handle blocks (#4944)
* Fix orphaned feed slices, handle blocks

* Revert to filerting out orphan threads

* Support NotFoundPost views too

* Just kidding, use ReplyRef.root as source of grandparent data

* Fixes
Diffstat (limited to 'src')
-rw-r--r--src/lib/api/feed-manip.ts31
-rw-r--r--src/state/queries/post-feed.ts2
-rw-r--r--src/view/com/posts/FeedItem.tsx19
-rw-r--r--src/view/com/posts/FeedSlice.tsx4
4 files changed, 48 insertions, 8 deletions
diff --git a/src/lib/api/feed-manip.ts b/src/lib/api/feed-manip.ts
index 61de795a1..c2b80ca04 100644
--- a/src/lib/api/feed-manip.ts
+++ b/src/lib/api/feed-manip.ts
@@ -23,6 +23,7 @@ type FeedSliceItem = {
   record: AppBskyFeedPost.Record
   parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined
   isParentBlocked: boolean
+  isParentNotFound: boolean
 }
 
 type AuthorContext = {
@@ -68,6 +69,7 @@ export class FeedViewPostsSlice {
     }
     const parent = reply?.parent
     const isParentBlocked = AppBskyFeedDefs.isBlockedPost(parent)
+    const isParentNotFound = AppBskyFeedDefs.isNotFoundPost(parent)
     let parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined
     if (AppBskyFeedDefs.isPostView(parent)) {
       parentAuthor = parent.author
@@ -77,6 +79,7 @@ export class FeedViewPostsSlice {
       record: post.record,
       parentAuthor,
       isParentBlocked,
+      isParentNotFound,
     })
     if (!reply || reason) {
       return
@@ -89,23 +92,40 @@ export class FeedViewPostsSlice {
       this.isOrphan = true
       return
     }
+    const root = reply.root
+    const rootIsView =
+      AppBskyFeedDefs.isPostView(root) ||
+      AppBskyFeedDefs.isBlockedPost(root) ||
+      AppBskyFeedDefs.isNotFoundPost(root)
+    /*
+     * If the parent is also the root, we just so happen to have the data we
+     * need to compute if the parent's parent (grandparent) is blocked. This
+     * doesn't always happen, of course, but we can take advantage of it when
+     * it does.
+     */
+    const grandparent =
+      rootIsView && parent.record.reply?.parent.uri === root.uri
+        ? root
+        : undefined
     const grandparentAuthor = reply.grandparentAuthor
     const isGrandparentBlocked = Boolean(
-      grandparentAuthor?.viewer?.blockedBy ||
-        grandparentAuthor?.viewer?.blocking ||
-        grandparentAuthor?.viewer?.blockingByList,
+      grandparent && AppBskyFeedDefs.isBlockedPost(grandparent),
+    )
+    const isGrandparentNotFound = Boolean(
+      grandparent && AppBskyFeedDefs.isNotFoundPost(grandparent),
     )
     this.items.unshift({
       post: parent,
       record: parent.record,
       parentAuthor: grandparentAuthor,
       isParentBlocked: isGrandparentBlocked,
+      isParentNotFound: isGrandparentNotFound,
     })
     if (isGrandparentBlocked) {
       this.isOrphan = true
-      // Keep going, it might still have a root.
+      // Keep going, it might still have a root, and we need this for thread
+      // de-deduping
     }
-    const root = reply.root
     if (
       !AppBskyFeedDefs.isPostView(root) ||
       !AppBskyFeedPost.isRecord(root.record) ||
@@ -121,6 +141,7 @@ export class FeedViewPostsSlice {
       post: root,
       record: root.record,
       isParentBlocked: false,
+      isParentNotFound: false,
       parentAuthor: undefined,
     })
     if (parent.record.reply?.parent.uri !== root.uri) {
diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts
index 724043e58..ee3e2c14d 100644
--- a/src/state/queries/post-feed.ts
+++ b/src/state/queries/post-feed.ts
@@ -80,6 +80,7 @@ export interface FeedPostSliceItem {
   moderation: ModerationDecision
   parentAuthor?: AppBskyActorDefs.ProfileViewBasic
   isParentBlocked?: boolean
+  isParentNotFound?: boolean
 }
 
 export interface FeedPostSlice {
@@ -326,6 +327,7 @@ export function usePostFeedQuery(
                         moderation: moderations[i],
                         parentAuthor: item.parentAuthor,
                         isParentBlocked: item.isParentBlocked,
+                        isParentNotFound: item.isParentNotFound,
                       }
                       return feedPostSliceItem
                     }),
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index 0071e2401..0fef4c5a8 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -63,6 +63,7 @@ interface FeedItemProps {
   feedContext: string | undefined
   hideTopBorder?: boolean
   isParentBlocked?: boolean
+  isParentNotFound?: boolean
 }
 
 export function FeedItem({
@@ -78,6 +79,7 @@ export function FeedItem({
   isThreadParent,
   hideTopBorder,
   isParentBlocked,
+  isParentNotFound,
 }: FeedItemProps & {post: AppBskyFeedDefs.PostView}): React.ReactNode {
   const postShadowed = usePostShadow(post)
   const richText = useMemo(
@@ -109,6 +111,7 @@ export function FeedItem({
         isThreadParent={isThreadParent}
         hideTopBorder={hideTopBorder}
         isParentBlocked={isParentBlocked}
+        isParentNotFound={isParentNotFound}
       />
     )
   }
@@ -129,6 +132,7 @@ let FeedItemInner = ({
   isThreadParent,
   hideTopBorder,
   isParentBlocked,
+  isParentNotFound,
 }: FeedItemProps & {
   richText: RichTextAPI
   post: Shadow<AppBskyFeedDefs.PostView>
@@ -344,9 +348,14 @@ let FeedItemInner = ({
             postHref={href}
             onOpenAuthor={onOpenAuthor}
           />
-          {showReplyTo && (parentAuthor || isParentBlocked) && (
-            <ReplyToLabel blocked={isParentBlocked} profile={parentAuthor} />
-          )}
+          {showReplyTo &&
+            (parentAuthor || isParentBlocked || isParentNotFound) && (
+              <ReplyToLabel
+                blocked={isParentBlocked}
+                notFound={isParentNotFound}
+                profile={parentAuthor}
+              />
+            )}
           <LabelsOnMyPost post={post} />
           <PostContent
             moderation={moderation}
@@ -438,9 +447,11 @@ PostContent = memo(PostContent)
 function ReplyToLabel({
   profile,
   blocked,
+  notFound,
 }: {
   profile: AppBskyActorDefs.ProfileViewBasic | undefined
   blocked?: boolean
+  notFound?: boolean
 }) {
   const pal = usePalette('default')
   const {currentAccount} = useSession()
@@ -448,6 +459,8 @@ function ReplyToLabel({
   let label
   if (blocked) {
     label = <Trans context="description">Reply to a blocked post</Trans>
+  } else if (notFound) {
+    label = <Trans context="description">Reply to an unknown post</Trans>
   } else if (profile != null) {
     const isMe = profile.did === currentAccount?.did
     if (isMe) {
diff --git a/src/view/com/posts/FeedSlice.tsx b/src/view/com/posts/FeedSlice.tsx
index fcd1ec3b1..9676eff1f 100644
--- a/src/view/com/posts/FeedSlice.tsx
+++ b/src/view/com/posts/FeedSlice.tsx
@@ -36,6 +36,7 @@ let FeedSlice = ({
           isThreadChild={isThreadChildAt(slice.items, 0)}
           hideTopBorder={hideTopBorder}
           isParentBlocked={slice.items[0].isParentBlocked}
+          isParentNotFound={slice.items[0].isParentNotFound}
         />
         <ViewFullThread uri={slice.items[0].uri} />
         <FeedItem
@@ -53,6 +54,7 @@ let FeedSlice = ({
           isThreadParent={isThreadParentAt(slice.items, beforeLast)}
           isThreadChild={isThreadChildAt(slice.items, beforeLast)}
           isParentBlocked={slice.items[beforeLast].isParentBlocked}
+          isParentNotFound={slice.items[beforeLast].isParentNotFound}
         />
         <FeedItem
           key={slice.items[last]._reactKey}
@@ -66,6 +68,7 @@ let FeedSlice = ({
           isThreadParent={isThreadParentAt(slice.items, last)}
           isThreadChild={isThreadChildAt(slice.items, last)}
           isParentBlocked={slice.items[last].isParentBlocked}
+          isParentNotFound={slice.items[last].isParentNotFound}
           isThreadLastChild
         />
       </>
@@ -90,6 +93,7 @@ let FeedSlice = ({
             isThreadChildAt(slice.items, i) && slice.items.length === i + 1
           }
           isParentBlocked={slice.items[i].isParentBlocked}
+          isParentNotFound={slice.items[i].isParentNotFound}
           hideTopBorder={hideTopBorder && i === 0}
         />
       ))}