From 712cd3fde55cca0444086e4512322832875d4836 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 5 Dec 2023 18:17:03 -0800 Subject: [PATCH] Perf: Include quote posts in the post-thread placeholder (#2104) --- src/state/queries/notifications/feed.ts | 5 +++ src/state/queries/post-feed.ts | 5 +++ src/state/queries/post-thread.ts | 39 +++++++++++++++++++- src/state/queries/util.ts | 48 +++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/state/queries/notifications/feed.ts b/src/state/queries/notifications/feed.ts index 16025f85..4d4c850c 100644 --- a/src/state/queries/notifications/feed.ts +++ b/src/state/queries/notifications/feed.ts @@ -30,6 +30,7 @@ import {fetchPage} from './util' import {FeedPage} from './types' import {useMutedThreads} from '#/state/muted-threads' import {STALE} from '..' +import {embedViewRecordToPostView, getEmbeddedPost} from '../util' export type {NotificationType, FeedNotification, FeedPage} from './types' @@ -119,6 +120,10 @@ export function* findAllPostsInQueryData( if (item.subject?.uri === uri) { yield item.subject } + const quotedPost = getEmbeddedPost(item.subject.embed) + if (quotedPost?.uri === uri) { + yield embedViewRecordToPostView(quotedPost) + } } } } diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 7cdda577..de18865e 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -23,6 +23,7 @@ import {getAgent} from '#/state/session' import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const' import {getModerationOpts} from '#/state/queries/preferences/moderation' import {KnownError} from '#/view/com/posts/FeedErrorMessage' +import {embedViewRecordToPostView, getEmbeddedPost} from './util' type ActorDid = string type AuthorFilter = @@ -263,6 +264,10 @@ export function* findAllPostsInQueryData( if (item.post.uri === uri) { yield item.post } + const quotedPost = getEmbeddedPost(item.post.embed) + if (quotedPost?.uri === uri) { + yield embedViewRecordToPostView(quotedPost) + } if ( AppBskyFeedDefs.isPostView(item.reply?.parent) && item.reply?.parent?.uri === uri diff --git a/src/state/queries/post-thread.ts b/src/state/queries/post-thread.ts index cde45723..cedbbc9d 100644 --- a/src/state/queries/post-thread.ts +++ b/src/state/queries/post-thread.ts @@ -2,6 +2,7 @@ import { AppBskyFeedDefs, AppBskyFeedPost, AppBskyFeedGetPostThread, + AppBskyEmbedRecord, } from '@atproto/api' import {useQuery, useQueryClient, QueryClient} from '@tanstack/react-query' @@ -10,6 +11,7 @@ import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {findPostInQueryData as findPostInFeedQueryData} from './post-feed' import {findPostInQueryData as findPostInNotifsQueryData} from './notifications/feed' import {precacheThreadPosts as precacheResolvedUris} from './resolve-uri' +import {getEmbeddedPost} from './util' export const RQKEY = (uri: string) => ['post-thread', uri] type ThreadViewNode = AppBskyFeedGetPostThread.OutputSchema['thread'] @@ -237,6 +239,10 @@ export function* findAllPostsInQueryData( if (item.uri === uri) { yield item } + const quotedPost = getEmbeddedPost(item.post.embed) + if (quotedPost?.uri === uri) { + yield embedViewRecordToPlaceholderThread(quotedPost) + } } } } @@ -301,7 +307,38 @@ function postViewToPlaceholderThread( showChildReplyLine: false, showParentReplyLine: false, isParentLoading: !!(post.record as AppBskyFeedPost.Record).reply, - isChildLoading: !!post.replyCount, + isChildLoading: true, // assume yes (show the spinner) just in case + }, + } +} + +function embedViewRecordToPlaceholderThread( + record: AppBskyEmbedRecord.ViewRecord, +): ThreadNode { + return { + type: 'post', + _reactKey: record.uri, + uri: record.uri, + post: { + uri: record.uri, + cid: record.cid, + author: record.author, + record: record.value, + indexedAt: record.indexedAt, + labels: record.labels, + }, + record: record.value as AppBskyFeedPost.Record, // validated in getEmbeddedPost + parent: undefined, + replies: undefined, + viewer: undefined, // not available + ctx: { + depth: 0, + isHighlightedPost: true, + hasMore: false, + showChildReplyLine: false, + showParentReplyLine: false, + isParentLoading: !!(record.value as AppBskyFeedPost.Record).reply, + isChildLoading: true, // not available, so assume yes (to show the spinner) }, } } diff --git a/src/state/queries/util.ts b/src/state/queries/util.ts index ed91a8f2..b259b192 100644 --- a/src/state/queries/util.ts +++ b/src/state/queries/util.ts @@ -1,4 +1,10 @@ import {QueryClient, QueryKey, InfiniteData} from '@tanstack/react-query' +import { + AppBskyEmbedRecord, + AppBskyEmbedRecordWithMedia, + AppBskyFeedDefs, + AppBskyFeedPost, +} from '@atproto/api' export function truncateAndInvalidate( queryClient: QueryClient, @@ -15,3 +21,45 @@ export function truncateAndInvalidate( }) queryClient.invalidateQueries({queryKey}) } + +export function getEmbeddedPost( + v: unknown, +): AppBskyEmbedRecord.ViewRecord | undefined { + if ( + AppBskyEmbedRecord.isView(v) && + AppBskyEmbedRecord.validateView(v).success + ) { + if ( + AppBskyEmbedRecord.isViewRecord(v.record) && + AppBskyFeedPost.isRecord(v.record.value) && + AppBskyFeedPost.validateRecord(v.record.value).success + ) { + return v.record + } + } + if ( + AppBskyEmbedRecordWithMedia.isView(v) && + AppBskyEmbedRecordWithMedia.validateView(v).success + ) { + if ( + AppBskyEmbedRecord.isViewRecord(v.record.record) && + AppBskyFeedPost.isRecord(v.record.record.value) && + AppBskyFeedPost.validateRecord(v.record.record.value).success + ) { + return v.record.record + } + } +} + +export function embedViewRecordToPostView( + v: AppBskyEmbedRecord.ViewRecord, +): AppBskyFeedDefs.PostView { + return { + uri: v.uri, + cid: v.cid, + author: v.author, + record: v.value, + indexedAt: v.indexedAt, + labels: v.labels, + } +}