Add in new optimistic insert logic

This commit is contained in:
Eric Bailey
2025-05-17 14:19:06 -07:00
parent 5f586cbec0
commit 03b5ef162c
5 changed files with 87 additions and 13 deletions
@@ -0,0 +1,4 @@
import {describe, it} from '@jest/globals'
describe(`insert`, () => {
})
+12 -6
View File
@@ -1,7 +1,7 @@
import {useQuery, useQueryClient} from '@tanstack/react-query'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {getThreadPlaceholder} from '#/state/queries/usePostThread/queryCache'
import {getThreadPlaceholder, createCacheMutator} from '#/state/queries/usePostThread/queryCache'
import {flatten,sort} from '#/state/queries/usePostThread/traversal'
import {
createPostThreadQueryKey,
@@ -30,13 +30,14 @@ export function usePostThread({
const mergeThreadgateHiddenReplies = useMergeThreadgateHiddenReplies()
const enabled = isEnabled !== false && !!uri && !!moderationOpts
const queryKey = createPostThreadQueryKey({
uri,
params,
})
const query = useQuery({
enabled,
queryKey: createPostThreadQueryKey({
uri,
params,
}),
queryKey,
async queryFn() {
const {data} = await agent.app.bsky.unspecced.getPostThreadV2({
uri: uri!,
@@ -82,12 +83,17 @@ export function usePostThread({
},
)
const mutator = createCacheMutator({
queryKey,
queryClient: qc,
})
return {
...query,
data: {
slices: items,
threadgate: query.data?.threadgate,
},
insertReplies: () => {},
insertReplies: mutator.insertReplies,
}
}
+61 -1
View File
@@ -11,13 +11,73 @@ import {findAllPostsInQueryData as findAllPostsInNotifsQueryData} from '#/state/
import {findAllPostsInQueryData as findAllPostsInFeedQueryData} from '#/state/queries/post-feed'
import {findAllPostsInQueryData as findAllPostsInQuoteQueryData} from '#/state/queries/post-quotes'
import {findAllPostsInQueryData as findAllPostsInSearchQueryData} from '#/state/queries/search-posts'
import {postThreadQueryKeyRoot} from '#/state/queries/usePostThread/types'
import {
postThreadQueryKeyRoot,
createPostThreadQueryKey,
} from '#/state/queries/usePostThread/types'
import {
embedViewToThreadPlaceholder,
postViewToThreadPlaceholder,
} from '#/state/queries/usePostThread/views'
import {didOrHandleUriMatches, getEmbeddedPost} from '#/state/queries/util'
export function createCacheMutator({
queryKey,
queryClient,
}: {
queryKey: ReturnType<typeof createPostThreadQueryKey>
queryClient: QueryClient
}) {
return {
insertReplies(
parent: AppBskyUnspeccedDefs.ThreadItemPost,
replies: AppBskyUnspeccedDefs.ThreadItemPost[],
) {
queryClient.setQueryData<AppBskyUnspeccedGetPostThreadV2.OutputSchema>(
queryKey,
queryData => {
if (!queryData) return
const thread = [...queryData.thread]
for (let i = 0; i < thread.length; i++) {
const anchor = thread[i]
if (!AppBskyUnspeccedDefs.isThreadItemPost(anchor)) continue
if (anchor.uri !== parent.uri) continue
/*
* Update parent data
*/
anchor.post = {
...anchor.post,
replyCount: parent.post.replyCount,
}
/*
* Splice in new replies
*/
for (let ri = 0; ri < replies.length; ri++) {
const reply = replies[ri]
reply.depth = anchor.depth + 1 + ri
const insertIndex = i + 1 + ri
thread.splice(insertIndex, 0, {
$type: 'app.bsky.unspecced.defs#threadItemPost',
...reply,
})
}
}
return {
...queryData,
thread,
}
},
)
},
deletePost(post: AppBskyUnspeccedDefs.ThreadItemPost) {},
}
}
export function getThreadPlaceholder(
queryClient: QueryClient,
uri: string,
+4 -4
View File
@@ -407,15 +407,15 @@ export const ComposePost = ({
posts = await retry(5, _e => true, async () => {
const res = await agent.app.bsky.unspecced.getPostThreadV2({
uri: postUri!,
above: 0,
above: 1,
below: thread.posts.length - 1,
branchingFactor: 1,
})
if (res.data.thread.length !== thread.posts.length) {
const parent = res.data.thread.at(0)
if (!AppBskyUnspeccedDefs.isThreadItemPost(parent)) {
throw new Error(`Not ready`)
}
const anchor = res.data.thread.at(0)
if (!AppBskyUnspeccedDefs.isThreadItemPost(anchor)) {
if (res.data.thread.length !== thread.posts.length + 1) {
throw new Error(`Not ready`)
}
return res.data.thread
+6 -2
View File
@@ -161,8 +161,12 @@ export function Inner({uri}: {uri: string | undefined}) {
({post}: {post: AppBskyUnspeccedDefs.ThreadItemPost}) =>
(_: any, posts: AppBskyUnspeccedDefs.ThreadItemPost[]) => {
if (posts.length) {
// TODO get parent and update reply count?
insertReplies(post.uri, posts)
console.log('insert', posts)
const parent = posts.at(0)
const replies = posts.slice(1)
if (parent && replies.length) {
insertReplies(parent, replies)
}
}
}