Bluesky app fork with some witchin' additions 💫

Prep threadgate shadow hack (#4970)

Co-authored-by: Hailey <me@haileyok.com>

authored by

Eric Bailey
Hailey
and committed by
GitHub
d5c78b91 61f0be70

+68 -23
+13
src/state/cache/post-shadow.ts
··· 21 21 repostUri: string | undefined 22 22 isDeleted: boolean 23 23 embed: AppBskyEmbedRecord.View | AppBskyEmbedRecordWithMedia.View | undefined 24 + threadgateView: AppBskyFeedDefs.ThreadgateView | undefined 24 25 } 25 26 26 27 export const POST_TOMBSTONE = Symbol('PostTombstone') ··· 104 105 } 105 106 } 106 107 108 + let threadgateView: typeof post.threadgate 109 + if ('threadgateView' in shadow && !post.threadgate) { 110 + if ( 111 + AppBskyFeedDefs.isThreadgateView(shadow.threadgateView) || 112 + shadow.threadgateView === undefined 113 + ) { 114 + threadgateView = shadow.threadgateView 115 + } 116 + } 117 + 107 118 return castAsShadow({ 108 119 ...post, 109 120 embed: embed || post.embed, ··· 114 125 like: 'likeUri' in shadow ? shadow.likeUri : post.viewer?.like, 115 126 repost: 'repostUri' in shadow ? shadow.repostUri : post.viewer?.repost, 116 127 }, 128 + // always prefer real post data 129 + threadgate: post.threadgate || threadgateView, 117 130 }) 118 131 } 119 132
+13 -2
src/state/queries/threadgate/index.ts
··· 9 9 10 10 import {networkRetry, retry} from '#/lib/async/retry' 11 11 import {until} from '#/lib/async/until' 12 + import {updatePostShadow} from '#/state/cache/post-shadow' 12 13 import {STALE} from '#/state/queries' 13 14 import {RQKEY_ROOT as postThreadQueryKeyRoot} from '#/state/queries/post-thread' 14 15 import {ThreadgateAllowUISetting} from '#/state/queries/threadgate/types' 15 16 import { 17 + createTempThreadgateView, 16 18 createThreadgateRecord, 17 19 mergeThreadgateRecords, 18 20 threadgateAllowUISettingToAllowRecordValue, ··· 342 344 } 343 345 }) 344 346 }, 345 - onSuccess() { 347 + onSuccess(_, {postUri, replyUri}) { 348 + updatePostShadow(queryClient, postUri, { 349 + threadgateView: createTempThreadgateView({ 350 + postUri, 351 + hiddenReplies: [replyUri], 352 + }), 353 + }) 346 354 queryClient.invalidateQueries({ 347 355 queryKey: [threadgateRecordQueryKeyRoot], 348 356 }) 349 357 }, 350 - onError(_, {replyUri, action}) { 358 + onError(_, {postUri, replyUri, action}) { 351 359 if (action === 'hide') { 352 360 hiddenReplies.removeHiddenReplyUri(replyUri) 353 361 } else if (action === 'show') { 354 362 hiddenReplies.addHiddenReplyUri(replyUri) 355 363 } 364 + updatePostShadow(queryClient, postUri, { 365 + threadgateView: undefined, 366 + }) 356 367 }, 357 368 }) 358 369 }
+20
src/state/queries/threadgate/util.ts
··· 139 139 hiddenReplies: threadgate.hiddenReplies || [], 140 140 } 141 141 } 142 + 143 + export function createTempThreadgateView({ 144 + postUri, 145 + hiddenReplies, 146 + }: Pick<AppBskyFeedThreadgate.Record, 'hiddenReplies'> & { 147 + postUri: string 148 + }): AppBskyFeedDefs.ThreadgateView { 149 + const record: AppBskyFeedThreadgate.Record = { 150 + $type: 'app.bsky.feed.threadgate', 151 + post: postUri, 152 + allow: undefined, 153 + hiddenReplies, 154 + createdAt: new Date().toISOString(), 155 + } 156 + return { 157 + $type: 'app.bsky.feed.defs#threadgateView', 158 + uri: postUri, 159 + record, 160 + } 161 + }
+5 -4
src/view/com/post-thread/PostThread.tsx
··· 129 129 currentAccount && 130 130 rootPostUri && 131 131 currentAccount?.did === new AtUri(rootPostUri).host 132 + const initialThreadgateRecord = rootPost?.threadgate?.record as 133 + | AppBskyFeedThreadgate.Record 134 + | undefined 132 135 const {data: threadgateRecord} = useThreadgateRecordQuery({ 133 136 /** 134 137 * If the user is the OP and the root post has a threadgate, we should load 135 138 * the threadgate record. Otherwise, fallback to initialData, which is taken 136 139 * from the response from `getPostThread`. 137 140 */ 138 - enabled: Boolean(isOP && rootPostUri), 141 + enabled: Boolean(isOP && rootPostUri && initialThreadgateRecord), 139 142 postUri: rootPostUri, 140 - initialData: rootPost?.threadgate?.record as 141 - | AppBskyFeedThreadgate.Record 142 - | undefined, 143 + initialData: initialThreadgateRecord, 143 144 }) 144 145 145 146 const moderationOpts = useModerationOpts()
+16 -16
src/view/com/post-thread/PostThreadItem.tsx
··· 399 399 </Text> 400 400 </Link> 401 401 ) : null} 402 - {post.likeCount != null && post.likeCount !== 0 ? ( 403 - <Link 404 - style={styles.expandedInfoItem} 405 - href={likesHref} 406 - title={likesTitle}> 407 - <Text 408 - testID="likeCount-expanded" 409 - type="lg" 410 - style={pal.textLight}> 411 - <Text type="xl-bold" style={pal.text}> 412 - {formatCount(post.likeCount)} 413 - </Text>{' '} 414 - <Plural value={post.likeCount} one="like" other="likes" /> 415 - </Text> 416 - </Link> 417 - ) : null} 418 402 {post.quoteCount != null && post.quoteCount !== 0 ? ( 419 403 <Link 420 404 style={styles.expandedInfoItem} ··· 432 416 one="quote" 433 417 other="quotes" 434 418 /> 419 + </Text> 420 + </Link> 421 + ) : null} 422 + {post.likeCount != null && post.likeCount !== 0 ? ( 423 + <Link 424 + style={styles.expandedInfoItem} 425 + href={likesHref} 426 + title={likesTitle}> 427 + <Text 428 + testID="likeCount-expanded" 429 + type="lg" 430 + style={pal.textLight}> 431 + <Text type="xl-bold" style={pal.text}> 432 + {formatCount(post.likeCount)} 433 + </Text>{' '} 434 + <Plural value={post.likeCount} one="like" other="likes" /> 435 435 </Text> 436 436 </Link> 437 437 ) : null}
+1 -1
src/view/com/util/post-ctrls/PostCtrls.tsx
··· 255 255 <View style={big ? a.align_center : [a.flex_1, a.align_start]}> 256 256 <RepostButton 257 257 isReposted={!!post.viewer?.repost} 258 - repostCount={post.repostCount} 258 + repostCount={(post.repostCount ?? 0) + (post.quoteCount ?? 0)} 259 259 onRepost={onRepost} 260 260 onQuote={onQuote} 261 261 big={big}