Perf: Include quote posts in the post-thread placeholder (#2104)

zio/stable
Paul Frazee 2023-12-05 18:17:03 -08:00 committed by GitHub
parent accb25ccf2
commit 712cd3fde5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 1 deletions

View File

@ -30,6 +30,7 @@ import {fetchPage} from './util'
import {FeedPage} from './types' import {FeedPage} from './types'
import {useMutedThreads} from '#/state/muted-threads' import {useMutedThreads} from '#/state/muted-threads'
import {STALE} from '..' import {STALE} from '..'
import {embedViewRecordToPostView, getEmbeddedPost} from '../util'
export type {NotificationType, FeedNotification, FeedPage} from './types' export type {NotificationType, FeedNotification, FeedPage} from './types'
@ -119,6 +120,10 @@ export function* findAllPostsInQueryData(
if (item.subject?.uri === uri) { if (item.subject?.uri === uri) {
yield item.subject yield item.subject
} }
const quotedPost = getEmbeddedPost(item.subject.embed)
if (quotedPost?.uri === uri) {
yield embedViewRecordToPostView(quotedPost)
}
} }
} }
} }

View File

@ -23,6 +23,7 @@ import {getAgent} from '#/state/session'
import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const' import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const'
import {getModerationOpts} from '#/state/queries/preferences/moderation' import {getModerationOpts} from '#/state/queries/preferences/moderation'
import {KnownError} from '#/view/com/posts/FeedErrorMessage' import {KnownError} from '#/view/com/posts/FeedErrorMessage'
import {embedViewRecordToPostView, getEmbeddedPost} from './util'
type ActorDid = string type ActorDid = string
type AuthorFilter = type AuthorFilter =
@ -263,6 +264,10 @@ export function* findAllPostsInQueryData(
if (item.post.uri === uri) { if (item.post.uri === uri) {
yield item.post yield item.post
} }
const quotedPost = getEmbeddedPost(item.post.embed)
if (quotedPost?.uri === uri) {
yield embedViewRecordToPostView(quotedPost)
}
if ( if (
AppBskyFeedDefs.isPostView(item.reply?.parent) && AppBskyFeedDefs.isPostView(item.reply?.parent) &&
item.reply?.parent?.uri === uri item.reply?.parent?.uri === uri

View File

@ -2,6 +2,7 @@ import {
AppBskyFeedDefs, AppBskyFeedDefs,
AppBskyFeedPost, AppBskyFeedPost,
AppBskyFeedGetPostThread, AppBskyFeedGetPostThread,
AppBskyEmbedRecord,
} from '@atproto/api' } from '@atproto/api'
import {useQuery, useQueryClient, QueryClient} from '@tanstack/react-query' 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 findPostInFeedQueryData} from './post-feed'
import {findPostInQueryData as findPostInNotifsQueryData} from './notifications/feed' import {findPostInQueryData as findPostInNotifsQueryData} from './notifications/feed'
import {precacheThreadPosts as precacheResolvedUris} from './resolve-uri' import {precacheThreadPosts as precacheResolvedUris} from './resolve-uri'
import {getEmbeddedPost} from './util'
export const RQKEY = (uri: string) => ['post-thread', uri] export const RQKEY = (uri: string) => ['post-thread', uri]
type ThreadViewNode = AppBskyFeedGetPostThread.OutputSchema['thread'] type ThreadViewNode = AppBskyFeedGetPostThread.OutputSchema['thread']
@ -237,6 +239,10 @@ export function* findAllPostsInQueryData(
if (item.uri === uri) { if (item.uri === uri) {
yield item yield item
} }
const quotedPost = getEmbeddedPost(item.post.embed)
if (quotedPost?.uri === uri) {
yield embedViewRecordToPlaceholderThread(quotedPost)
}
} }
} }
} }
@ -301,7 +307,38 @@ function postViewToPlaceholderThread(
showChildReplyLine: false, showChildReplyLine: false,
showParentReplyLine: false, showParentReplyLine: false,
isParentLoading: !!(post.record as AppBskyFeedPost.Record).reply, 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)
}, },
} }
} }

View File

@ -1,4 +1,10 @@
import {QueryClient, QueryKey, InfiniteData} from '@tanstack/react-query' import {QueryClient, QueryKey, InfiniteData} from '@tanstack/react-query'
import {
AppBskyEmbedRecord,
AppBskyEmbedRecordWithMedia,
AppBskyFeedDefs,
AppBskyFeedPost,
} from '@atproto/api'
export function truncateAndInvalidate<T = any>( export function truncateAndInvalidate<T = any>(
queryClient: QueryClient, queryClient: QueryClient,
@ -15,3 +21,45 @@ export function truncateAndInvalidate<T = any>(
}) })
queryClient.invalidateQueries({queryKey}) 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,
}
}