From d5c78b9183ac78620f59538fed61c8130ae1c47a Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 21 Aug 2024 22:16:03 -0500 Subject: [PATCH] Prep threadgate shadow hack (#4970) Co-authored-by: Hailey --- src/state/cache/post-shadow.ts | 13 +++++++++ src/state/queries/threadgate/index.ts | 15 ++++++++-- src/state/queries/threadgate/util.ts | 20 +++++++++++++ src/view/com/post-thread/PostThread.tsx | 9 +++--- src/view/com/post-thread/PostThreadItem.tsx | 32 ++++++++++----------- src/view/com/util/post-ctrls/PostCtrls.tsx | 2 +- 6 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/state/cache/post-shadow.ts b/src/state/cache/post-shadow.ts index 65300a8ef1..4d848ccc45 100644 --- a/src/state/cache/post-shadow.ts +++ b/src/state/cache/post-shadow.ts @@ -21,6 +21,7 @@ export interface PostShadow { repostUri: string | undefined isDeleted: boolean embed: AppBskyEmbedRecord.View | AppBskyEmbedRecordWithMedia.View | undefined + threadgateView: AppBskyFeedDefs.ThreadgateView | undefined } export const POST_TOMBSTONE = Symbol('PostTombstone') @@ -104,6 +105,16 @@ function mergeShadow( } } + let threadgateView: typeof post.threadgate + if ('threadgateView' in shadow && !post.threadgate) { + if ( + AppBskyFeedDefs.isThreadgateView(shadow.threadgateView) || + shadow.threadgateView === undefined + ) { + threadgateView = shadow.threadgateView + } + } + return castAsShadow({ ...post, embed: embed || post.embed, @@ -114,6 +125,8 @@ function mergeShadow( like: 'likeUri' in shadow ? shadow.likeUri : post.viewer?.like, repost: 'repostUri' in shadow ? shadow.repostUri : post.viewer?.repost, }, + // always prefer real post data + threadgate: post.threadgate || threadgateView, }) } diff --git a/src/state/queries/threadgate/index.ts b/src/state/queries/threadgate/index.ts index a88197cd5b..faa166e2c7 100644 --- a/src/state/queries/threadgate/index.ts +++ b/src/state/queries/threadgate/index.ts @@ -9,10 +9,12 @@ import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' import {networkRetry, retry} from '#/lib/async/retry' import {until} from '#/lib/async/until' +import {updatePostShadow} from '#/state/cache/post-shadow' import {STALE} from '#/state/queries' import {RQKEY_ROOT as postThreadQueryKeyRoot} from '#/state/queries/post-thread' import {ThreadgateAllowUISetting} from '#/state/queries/threadgate/types' import { + createTempThreadgateView, createThreadgateRecord, mergeThreadgateRecords, threadgateAllowUISettingToAllowRecordValue, @@ -342,17 +344,26 @@ export function useToggleReplyVisibilityMutation() { } }) }, - onSuccess() { + onSuccess(_, {postUri, replyUri}) { + updatePostShadow(queryClient, postUri, { + threadgateView: createTempThreadgateView({ + postUri, + hiddenReplies: [replyUri], + }), + }) queryClient.invalidateQueries({ queryKey: [threadgateRecordQueryKeyRoot], }) }, - onError(_, {replyUri, action}) { + onError(_, {postUri, replyUri, action}) { if (action === 'hide') { hiddenReplies.removeHiddenReplyUri(replyUri) } else if (action === 'show') { hiddenReplies.addHiddenReplyUri(replyUri) } + updatePostShadow(queryClient, postUri, { + threadgateView: undefined, + }) }, }) } diff --git a/src/state/queries/threadgate/util.ts b/src/state/queries/threadgate/util.ts index 09ae0a0c1f..35c33875e1 100644 --- a/src/state/queries/threadgate/util.ts +++ b/src/state/queries/threadgate/util.ts @@ -139,3 +139,23 @@ export function createThreadgateRecord( hiddenReplies: threadgate.hiddenReplies || [], } } + +export function createTempThreadgateView({ + postUri, + hiddenReplies, +}: Pick & { + postUri: string +}): AppBskyFeedDefs.ThreadgateView { + const record: AppBskyFeedThreadgate.Record = { + $type: 'app.bsky.feed.threadgate', + post: postUri, + allow: undefined, + hiddenReplies, + createdAt: new Date().toISOString(), + } + return { + $type: 'app.bsky.feed.defs#threadgateView', + uri: postUri, + record, + } +} diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index bd778fd989..3757d76c6d 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -129,17 +129,18 @@ export function PostThread({uri}: {uri: string | undefined}) { currentAccount && rootPostUri && currentAccount?.did === new AtUri(rootPostUri).host + const initialThreadgateRecord = rootPost?.threadgate?.record as + | AppBskyFeedThreadgate.Record + | undefined const {data: threadgateRecord} = useThreadgateRecordQuery({ /** * If the user is the OP and the root post has a threadgate, we should load * the threadgate record. Otherwise, fallback to initialData, which is taken * from the response from `getPostThread`. */ - enabled: Boolean(isOP && rootPostUri), + enabled: Boolean(isOP && rootPostUri && initialThreadgateRecord), postUri: rootPostUri, - initialData: rootPost?.threadgate?.record as - | AppBskyFeedThreadgate.Record - | undefined, + initialData: initialThreadgateRecord, }) const moderationOpts = useModerationOpts() diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index da187f5d9e..f2cd8e85af 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -399,22 +399,6 @@ let PostThreadItemLoaded = ({ ) : null} - {post.likeCount != null && post.likeCount !== 0 ? ( - - - - {formatCount(post.likeCount)} - {' '} - - - - ) : null} {post.quoteCount != null && post.quoteCount !== 0 ? ( ) : null} + {post.likeCount != null && post.likeCount !== 0 ? ( + + + + {formatCount(post.likeCount)} + {' '} + + + + ) : null} ) : null} diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index 0cfa3fc4d9..a0cef8692d 100644 --- a/src/view/com/util/post-ctrls/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -255,7 +255,7 @@ let PostCtrls = ({