From 380c4dbf24eed0ef92dbccf98c247f3eecac2f5f Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 2 Aug 2024 16:20:31 -0500 Subject: [PATCH] Integrate live threadgate query --- src/components/WhoCanReply.tsx | 4 +++ src/state/queries/threadgate.ts | 44 ++++++++++++++++++++++++- src/view/com/post-thread/PostThread.tsx | 14 +++++++- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/components/WhoCanReply.tsx b/src/components/WhoCanReply.tsx index 1ffb4da39d..d6b9effb4e 100644 --- a/src/components/WhoCanReply.tsx +++ b/src/components/WhoCanReply.tsx @@ -18,6 +18,7 @@ import {makeListLink, makeProfileLink} from '#/lib/routes/links' import {logger} from '#/logger' import {isNative} from '#/platform/detection' import {RQKEY_ROOT as POST_THREAD_RQKEY_ROOT} from '#/state/queries/post-thread' +import {threadgateRecordQueryKeyRoot} from '#/state/queries/threadgate' import { ThreadgateSetting, threadgateViewToSettings, @@ -110,6 +111,9 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) { queryClient.invalidateQueries({ queryKey: [POST_THREAD_RQKEY_ROOT], }) + queryClient.invalidateQueries({ + queryKey: [threadgateRecordQueryKeyRoot], + }) } catch (err) { Toast.show( _( diff --git a/src/state/queries/threadgate.ts b/src/state/queries/threadgate.ts index 8b6aeba6c1..a04ec183a7 100644 --- a/src/state/queries/threadgate.ts +++ b/src/state/queries/threadgate.ts @@ -1,4 +1,7 @@ -import {AppBskyFeedDefs, AppBskyFeedThreadgate} from '@atproto/api' +import {AppBskyFeedDefs, AppBskyFeedThreadgate, AtUri} from '@atproto/api' +import {useQuery} from '@tanstack/react-query' + +import {useAgent} from '#/state/session' export type ThreadgateSetting = | {type: 'nobody'} @@ -36,3 +39,42 @@ export function threadgateViewToSettings( .filter(n => !!n) return settings } + +export const threadgateRecordQueryKeyRoot = 'threadgate-record' +export const createThreadgateRecordQueryKey = (uri: string) => [ + threadgateRecordQueryKeyRoot, + uri, +] + +export function useThreadgateRecordQuery({ + postUri, + initialData, +}: { + postUri?: string + initialData?: AppBskyFeedThreadgate.Record +} = {}) { + const agent = useAgent() + + return useQuery({ + enabled: !!postUri, + queryKey: createThreadgateRecordQueryKey(postUri || ''), + placeholderData: initialData, + async queryFn() { + const urip = new AtUri(postUri!) + + if (!urip.host.startsWith('did:')) { + const res = await agent.resolveHandle({ + handle: urip.host, + }) + urip.host = res.data.did + } + + const {value} = await agent.api.app.bsky.feed.threadgate.get({ + repo: urip.host, + rkey: urip.rkey, + }) + + return value + }, + }) +} diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index a6c1a46487..573a479fd6 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -1,7 +1,7 @@ import React, {useEffect, useRef} from 'react' import {useWindowDimensions, View} from 'react-native' import {runOnJS} from 'react-native-reanimated' -import {AppBskyFeedDefs} from '@atproto/api' +import {AppBskyFeedDefs, AppBskyFeedThreadgate} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -20,6 +20,7 @@ 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 {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' import {useSetTitle} from 'lib/hooks/useSetTitle' @@ -117,6 +118,11 @@ export function PostThread({ const rootPost = thread?.type === 'post' ? thread.post : undefined const rootPostRecord = thread?.type === 'post' ? thread.record : undefined + const {data: threadgateRecord} = useThreadgateRecordQuery({ + postUri: uri, + initialData: rootPost?.threadgate?.record as AppBskyFeedThreadgate.Record, + }) + const moderationOpts = useModerationOpts() const isNoPwi = React.useMemo(() => { const mod = @@ -172,6 +178,7 @@ export function PostThread({ treeView, threadModerationCache, hiddenRepliesState !== HiddenRepliesState.Hide, + threadgateRecord, ) }, [ thread, @@ -180,6 +187,7 @@ export function PostThread({ treeView, threadModerationCache, hiddenRepliesState, + threadgateRecord, ]) const error = React.useMemo(() => { @@ -494,6 +502,7 @@ function createThreadSkeleton( treeView: boolean, modCache: ThreadModerationCache, showHiddenReplies: boolean, + threadgateRecord: AppBskyFeedThreadgate.Record | undefined, ): ThreadSkeletonParts | null { if (!node) return null @@ -507,6 +516,7 @@ function createThreadSkeleton( treeView, modCache, showHiddenReplies, + threadgateRecord, ), ), } @@ -543,6 +553,7 @@ function* flattenThreadReplies( treeView: boolean, modCache: ThreadModerationCache, showHiddenReplies: boolean, + threadgateRecord: AppBskyFeedThreadgate.Record | undefined, ): Generator { if (node.type === 'post') { // dont show pwi-opted-out posts to logged out users @@ -576,6 +587,7 @@ function* flattenThreadReplies( treeView, modCache, showHiddenReplies, + threadgateRecord, ) if (hiddenReply > hiddenReplies) { hiddenReplies = hiddenReply