about summary refs log tree commit diff
path: root/src/view/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com')
-rw-r--r--src/view/com/post-thread/PostThread.tsx41
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx19
-rw-r--r--src/view/com/posts/FeedItem.tsx43
-rw-r--r--src/view/com/util/forms/PostDropdownBtn.tsx12
4 files changed, 39 insertions, 76 deletions
diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx
index b3196f9ba..d5740f870 100644
--- a/src/view/com/post-thread/PostThread.tsx
+++ b/src/view/com/post-thread/PostThread.tsx
@@ -3,12 +3,7 @@ import {StyleSheet, useWindowDimensions, View} from 'react-native'
 import {runOnJS} from 'react-native-reanimated'
 import Animated from 'react-native-reanimated'
 import {useSafeAreaInsets} from 'react-native-safe-area-context'
-import {
-  AppBskyFeedDefs,
-  AppBskyFeedPost,
-  AppBskyFeedThreadgate,
-  AtUri,
-} from '@atproto/api'
+import {AppBskyFeedDefs, AppBskyFeedThreadgate} from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
@@ -28,9 +23,9 @@ import {
   usePostThreadQuery,
 } from '#/state/queries/post-thread'
 import {usePreferencesQuery} from '#/state/queries/preferences'
-import {useThreadgateRecordQuery} from '#/state/queries/threadgate'
 import {useSession} from '#/state/session'
 import {useComposerControls} from '#/state/shell'
+import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
 import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
 import {useMinimalShellFabTransform} from 'lib/hooks/useMinimalShellTransform'
 import {useSetTitle} from 'lib/hooks/useSetTitle'
@@ -108,7 +103,7 @@ export function PostThread({uri}: {uri: string | undefined}) {
     isError: isThreadError,
     error: threadError,
     refetch,
-    data: thread,
+    data: {thread, threadgate} = {},
   } = usePostThreadQuery(uri)
 
   const treeView = React.useMemo(
@@ -119,26 +114,11 @@ export function PostThread({uri}: {uri: string | undefined}) {
   )
   const rootPost = thread?.type === 'post' ? thread.post : undefined
   const rootPostRecord = thread?.type === 'post' ? thread.record : undefined
-  const replyRef =
-    rootPostRecord && AppBskyFeedPost.isRecord(rootPostRecord)
-      ? rootPostRecord.reply
-      : undefined
-  const rootPostUri = replyRef ? replyRef.root.uri : rootPost?.uri
-
-  const isOP =
-    currentAccount &&
-    rootPostUri &&
-    currentAccount?.did === new AtUri(rootPostUri).host
-  const initialThreadgateRecord = rootPost?.threadgate?.record as
+  const threadgateRecord = threadgate?.record as
     | AppBskyFeedThreadgate.Record
     | undefined
-  const {data: threadgateRecord} = useThreadgateRecordQuery({
-    /**
-     * If the user is the OP and we have a root post, fetch the threadgate.
-     */
-    enabled: Boolean(isOP && rootPostUri),
-    postUri: rootPostUri,
-    initialData: initialThreadgateRecord,
+  const threadgateHiddenReplies = useMergedThreadgateHiddenReplies({
+    threadgateRecord,
   })
 
   const moderationOpts = useModerationOpts()
@@ -194,9 +174,6 @@ export function PostThread({uri}: {uri: string | undefined}) {
   const skeleton = React.useMemo(() => {
     const threadViewPrefs = preferences?.threadViewPrefs
     if (!threadViewPrefs || !thread) return null
-    const threadgateRecordHiddenReplies = new Set<string>(
-      threadgateRecord?.hiddenReplies || [],
-    )
 
     return createThreadSkeleton(
       sortThread(
@@ -205,13 +182,13 @@ export function PostThread({uri}: {uri: string | undefined}) {
         threadModerationCache,
         currentDid,
         justPostedUris,
-        threadgateRecordHiddenReplies,
+        threadgateHiddenReplies,
       ),
       currentDid,
       treeView,
       threadModerationCache,
       hiddenRepliesState !== HiddenRepliesState.Hide,
-      threadgateRecordHiddenReplies,
+      threadgateHiddenReplies,
     )
   }, [
     thread,
@@ -221,7 +198,7 @@ export function PostThread({uri}: {uri: string | undefined}) {
     threadModerationCache,
     hiddenRepliesState,
     justPostedUris,
-    threadgateRecord,
+    threadgateHiddenReplies,
   ])
 
   const error = React.useMemo(() => {
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index f2cd8e85a..f2a8be598 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -17,6 +17,7 @@ import {useLanguagePrefs} from '#/state/preferences'
 import {useOpenLink} from '#/state/preferences/in-app-browser'
 import {ThreadPost} from '#/state/queries/post-thread'
 import {useComposerControls} from '#/state/shell/composer'
+import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
 import {MAX_POST_LINES} from 'lib/constants'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
@@ -206,24 +207,22 @@ let PostThreadItemLoaded = ({
     return makeProfileLink(post.author, 'post', urip.rkey, 'reposted-by')
   }, [post.uri, post.author])
   const repostsTitle = _(msg`Reposts of this post`)
+  const threadgateHiddenReplies = useMergedThreadgateHiddenReplies({
+    threadgateRecord,
+  })
   const additionalPostAlerts: AppModerationCause[] = React.useMemo(() => {
-    const isPostHiddenByThreadgate = threadgateRecord?.hiddenReplies?.includes(
-      post.uri,
-    )
-    const isControlledByViewer =
-      threadgateRecord &&
-      new AtUri(threadgateRecord.post).host === currentAccount?.did
-    if (!isControlledByViewer) return []
-    return threadgateRecord && isPostHiddenByThreadgate
+    const isPostHiddenByThreadgate = threadgateHiddenReplies.has(post.uri)
+    const isControlledByViewer = new AtUri(rootUri).host === currentAccount?.did
+    return isControlledByViewer && isPostHiddenByThreadgate
       ? [
           {
             type: 'reply-hidden',
-            source: {type: 'user', did: new AtUri(threadgateRecord.post).host},
+            source: {type: 'user', did: currentAccount?.did},
             priority: 6,
           },
         ]
       : []
-  }, [post, threadgateRecord, currentAccount?.did])
+  }, [post, currentAccount?.did, threadgateHiddenReplies, rootUri])
   const quotesHref = React.useMemo(() => {
     const urip = new AtUri(post.uri)
     return makeProfileLink(post.author, 'post', urip.rkey, 'quotes')
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index e90e8b885..a5714fafe 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -22,7 +22,7 @@ import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow'
 import {useFeedFeedbackContext} from '#/state/feed-feedback'
 import {useSession} from '#/state/session'
 import {useComposerControls} from '#/state/shell/composer'
-import {useThreadgateHiddenReplyUris} from '#/state/threadgate-hidden-replies'
+import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
 import {isReasonFeedSource, ReasonFeedSource} from 'lib/api/feed/types'
 import {MAX_POST_LINES} from 'lib/constants'
 import {usePalette} from 'lib/hooks/usePalette'
@@ -227,6 +227,10 @@ let FeedItemInner = ({
     AppBskyFeedDefs.isReasonRepost(reason) &&
     reason.by.did === currentAccount?.did
 
+  /**
+   * If `post[0]` in this slice is the actual root post (not an orphan thread),
+   * then we may have a threadgate record to reference
+   */
   const threadgateRecord = AppBskyFeedThreadgate.isRecord(
     rootPost.threadgate?.record,
   )
@@ -422,41 +426,26 @@ let PostContent = ({
   const [limitLines, setLimitLines] = useState(
     () => countLines(richText.text) >= MAX_POST_LINES,
   )
-  const {uris: hiddenReplyUris, recentlyUnhiddenUris} =
-    useThreadgateHiddenReplyUris()
+  const threadgateHiddenReplies = useMergedThreadgateHiddenReplies({
+    threadgateRecord,
+  })
   const additionalPostAlerts: AppModerationCause[] = React.useMemo(() => {
-    const isPostHiddenByHiddenReplyCache = hiddenReplyUris.has(post.uri)
-    const isPostHiddenByThreadgate =
-      !recentlyUnhiddenUris.has(post.uri) &&
-      !!threadgateRecord?.hiddenReplies?.includes(post.uri)
-    const isHidden = isPostHiddenByHiddenReplyCache || isPostHiddenByThreadgate
+    const isPostHiddenByThreadgate = threadgateHiddenReplies.has(post.uri)
+    const rootPostUri = AppBskyFeedPost.isRecord(post.record)
+      ? post.record?.reply?.root?.uri || post.uri
+      : undefined
     const isControlledByViewer =
-      isPostHiddenByHiddenReplyCache ||
-      (threadgateRecord &&
-        new AtUri(threadgateRecord.post).host === currentAccount?.did)
-    if (!isControlledByViewer) return []
-    const alertSource =
-      threadgateRecord && isPostHiddenByThreadgate
-        ? new AtUri(threadgateRecord.post).host
-        : isPostHiddenByHiddenReplyCache
-        ? currentAccount?.did
-        : undefined
-    return isHidden && alertSource
+      rootPostUri && new AtUri(rootPostUri).host === currentAccount?.did
+    return isControlledByViewer && isPostHiddenByThreadgate
       ? [
           {
             type: 'reply-hidden',
-            source: {type: 'user', did: alertSource},
+            source: {type: 'user', did: currentAccount?.did},
             priority: 6,
           },
         ]
       : []
-  }, [
-    post,
-    hiddenReplyUris,
-    recentlyUnhiddenUris,
-    threadgateRecord,
-    currentAccount?.did,
-  ])
+  }, [post, currentAccount?.did, threadgateHiddenReplies])
 
   const onPressShowMore = React.useCallback(() => {
     setLimitLines(false)
diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx
index b293b0dff..03b6dd233 100644
--- a/src/view/com/util/forms/PostDropdownBtn.tsx
+++ b/src/view/com/util/forms/PostDropdownBtn.tsx
@@ -37,7 +37,7 @@ import {useToggleQuoteDetachmentMutation} from '#/state/queries/postgate'
 import {getMaybeDetachedQuoteEmbed} from '#/state/queries/postgate/util'
 import {useToggleReplyVisibilityMutation} from '#/state/queries/threadgate'
 import {useSession} from '#/state/session'
-import {useThreadgateHiddenReplyUris} from '#/state/threadgate-hidden-replies'
+import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
 import {getCurrentRoute} from 'lib/routes/helpers'
 import {shareUrl} from 'lib/sharing'
 import {toShareUrl} from 'lib/strings/url-helpers'
@@ -124,8 +124,6 @@ let PostDropdownBtn = ({
   const hideReplyConfirmControl = useDialogControl()
   const {mutateAsync: toggleReplyVisibility} =
     useToggleReplyVisibilityMutation()
-  const {uris: hiddenReplies, recentlyUnhiddenUris} =
-    useThreadgateHiddenReplyUris()
 
   const postUri = post.uri
   const postCid = post.cid
@@ -147,10 +145,10 @@ let PostDropdownBtn = ({
   const isPostHidden = hiddenPosts && hiddenPosts.includes(postUri)
   const isAuthor = postAuthor.did === currentAccount?.did
   const isRootPostAuthor = new AtUri(rootUri).host === currentAccount?.did
-  const isReplyHiddenByThreadgate =
-    hiddenReplies.has(postUri) ||
-    (!recentlyUnhiddenUris.has(postUri) &&
-      threadgateRecord?.hiddenReplies?.includes(postUri))
+  const threadgateHiddenReplies = useMergedThreadgateHiddenReplies({
+    threadgateRecord,
+  })
+  const isReplyHiddenByThreadgate = threadgateHiddenReplies.has(postUri)
 
   const {mutateAsync: toggleQuoteDetachment, isPending} =
     useToggleQuoteDetachmentMutation()