Add in new optimistic insert logic
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
import {describe, it} from '@jest/globals'
|
||||||
|
|
||||||
|
describe(`insert`, () => {
|
||||||
|
})
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import {useQuery, useQueryClient} from '@tanstack/react-query'
|
import {useQuery, useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
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 {flatten,sort} from '#/state/queries/usePostThread/traversal'
|
||||||
import {
|
import {
|
||||||
createPostThreadQueryKey,
|
createPostThreadQueryKey,
|
||||||
@@ -30,13 +30,14 @@ export function usePostThread({
|
|||||||
const mergeThreadgateHiddenReplies = useMergeThreadgateHiddenReplies()
|
const mergeThreadgateHiddenReplies = useMergeThreadgateHiddenReplies()
|
||||||
|
|
||||||
const enabled = isEnabled !== false && !!uri && !!moderationOpts
|
const enabled = isEnabled !== false && !!uri && !!moderationOpts
|
||||||
|
const queryKey = createPostThreadQueryKey({
|
||||||
|
uri,
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
enabled,
|
enabled,
|
||||||
queryKey: createPostThreadQueryKey({
|
queryKey,
|
||||||
uri,
|
|
||||||
params,
|
|
||||||
}),
|
|
||||||
async queryFn() {
|
async queryFn() {
|
||||||
const {data} = await agent.app.bsky.unspecced.getPostThreadV2({
|
const {data} = await agent.app.bsky.unspecced.getPostThreadV2({
|
||||||
uri: uri!,
|
uri: uri!,
|
||||||
@@ -82,12 +83,17 @@ export function usePostThread({
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const mutator = createCacheMutator({
|
||||||
|
queryKey,
|
||||||
|
queryClient: qc,
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...query,
|
...query,
|
||||||
data: {
|
data: {
|
||||||
slices: items,
|
slices: items,
|
||||||
threadgate: query.data?.threadgate,
|
threadgate: query.data?.threadgate,
|
||||||
},
|
},
|
||||||
insertReplies: () => {},
|
insertReplies: mutator.insertReplies,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,73 @@ import {findAllPostsInQueryData as findAllPostsInNotifsQueryData} from '#/state/
|
|||||||
import {findAllPostsInQueryData as findAllPostsInFeedQueryData} from '#/state/queries/post-feed'
|
import {findAllPostsInQueryData as findAllPostsInFeedQueryData} from '#/state/queries/post-feed'
|
||||||
import {findAllPostsInQueryData as findAllPostsInQuoteQueryData} from '#/state/queries/post-quotes'
|
import {findAllPostsInQueryData as findAllPostsInQuoteQueryData} from '#/state/queries/post-quotes'
|
||||||
import {findAllPostsInQueryData as findAllPostsInSearchQueryData} from '#/state/queries/search-posts'
|
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 {
|
import {
|
||||||
embedViewToThreadPlaceholder,
|
embedViewToThreadPlaceholder,
|
||||||
postViewToThreadPlaceholder,
|
postViewToThreadPlaceholder,
|
||||||
} from '#/state/queries/usePostThread/views'
|
} from '#/state/queries/usePostThread/views'
|
||||||
import {didOrHandleUriMatches, getEmbeddedPost} from '#/state/queries/util'
|
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(
|
export function getThreadPlaceholder(
|
||||||
queryClient: QueryClient,
|
queryClient: QueryClient,
|
||||||
uri: string,
|
uri: string,
|
||||||
|
|||||||
@@ -407,15 +407,15 @@ export const ComposePost = ({
|
|||||||
posts = await retry(5, _e => true, async () => {
|
posts = await retry(5, _e => true, async () => {
|
||||||
const res = await agent.app.bsky.unspecced.getPostThreadV2({
|
const res = await agent.app.bsky.unspecced.getPostThreadV2({
|
||||||
uri: postUri!,
|
uri: postUri!,
|
||||||
above: 0,
|
above: 1,
|
||||||
below: thread.posts.length - 1,
|
below: thread.posts.length - 1,
|
||||||
branchingFactor: 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`)
|
throw new Error(`Not ready`)
|
||||||
}
|
}
|
||||||
const anchor = res.data.thread.at(0)
|
if (res.data.thread.length !== thread.posts.length + 1) {
|
||||||
if (!AppBskyUnspeccedDefs.isThreadItemPost(anchor)) {
|
|
||||||
throw new Error(`Not ready`)
|
throw new Error(`Not ready`)
|
||||||
}
|
}
|
||||||
return res.data.thread
|
return res.data.thread
|
||||||
|
|||||||
@@ -161,8 +161,12 @@ export function Inner({uri}: {uri: string | undefined}) {
|
|||||||
({post}: {post: AppBskyUnspeccedDefs.ThreadItemPost}) =>
|
({post}: {post: AppBskyUnspeccedDefs.ThreadItemPost}) =>
|
||||||
(_: any, posts: AppBskyUnspeccedDefs.ThreadItemPost[]) => {
|
(_: any, posts: AppBskyUnspeccedDefs.ThreadItemPost[]) => {
|
||||||
if (posts.length) {
|
if (posts.length) {
|
||||||
// TODO get parent and update reply count?
|
console.log('insert', posts)
|
||||||
insertReplies(post.uri, posts)
|
const parent = posts.at(0)
|
||||||
|
const replies = posts.slice(1)
|
||||||
|
if (parent && replies.length) {
|
||||||
|
insertReplies(parent, replies)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user