Optimistic WIP
This commit is contained in:
@@ -106,6 +106,7 @@ export function useGetPostThreadV2({
|
|||||||
async queryFn() {
|
async queryFn() {
|
||||||
const {data} = await agent.app.bsky.feed.getPostThreadV2({
|
const {data} = await agent.app.bsky.feed.getPostThreadV2({
|
||||||
uri: uri!,
|
uri: uri!,
|
||||||
|
branchingFactor: params.view === 'linear' ? 1 : 10,
|
||||||
below: 10,
|
below: 10,
|
||||||
sorting: mapSortOptionsToSortID(params.sort),
|
sorting: mapSortOptionsToSortID(params.sort),
|
||||||
})
|
})
|
||||||
@@ -284,14 +285,15 @@ export function useThread(
|
|||||||
) {
|
) {
|
||||||
const isTreeView = params.view === 'tree'
|
const isTreeView = params.view === 'tree'
|
||||||
const [shadowSlices, setShadowSlices] = useState<
|
const [shadowSlices, setShadowSlices] = useState<
|
||||||
Map<string, AppBskyFeedDefs.ThreadItemPost[][]>
|
Record<string, AppBskyFeedDefs.ThreadItemPost[][]>
|
||||||
>(new Map())
|
>({})
|
||||||
const insertReplies = useCallback((belowUri: string, posts: AppBskyFeedDefs.ThreadItemPost[]) => {
|
const insertReplies = useCallback((belowUri: string, posts: AppBskyFeedDefs.ThreadItemPost[]) => {
|
||||||
setShadowSlices(prev => {
|
setShadowSlices(p => {
|
||||||
if (prev.has(belowUri)) {
|
const prev = {...p}
|
||||||
prev.set(belowUri, [...prev.get(belowUri)!, posts])
|
if (belowUri in prev) {
|
||||||
|
prev[belowUri] = [posts, ...(prev[belowUri] || {})]
|
||||||
} else {
|
} else {
|
||||||
prev.set(belowUri, [posts])
|
prev[belowUri] = [posts]
|
||||||
}
|
}
|
||||||
return prev
|
return prev
|
||||||
})
|
})
|
||||||
@@ -344,15 +346,14 @@ export function useThread(
|
|||||||
return sorted.slices
|
return sorted.slices
|
||||||
}, [sorted, shownHiddenReplyKinds])
|
}, [sorted, shownHiddenReplyKinds])
|
||||||
|
|
||||||
|
// TODO should probably done in query cache so deletes flow through the same way
|
||||||
const optimistic = useMemo(() => {
|
const optimistic = useMemo(() => {
|
||||||
if (!shadowSlices.size) return flattened
|
|
||||||
|
|
||||||
for (let i = 0; i < flattened.length; i++) {
|
for (let i = 0; i < flattened.length; i++) {
|
||||||
const item = flattened[i]
|
const item = flattened[i]
|
||||||
if (item.type !== 'threadSlice') continue
|
if (item.type !== 'threadSlice') continue
|
||||||
if (!shadowSlices.has(item.slice.uri)) continue
|
if (!(item.slice.uri in shadowSlices)) continue
|
||||||
|
|
||||||
const replyThreads = shadowSlices.get(item.slice.uri)
|
const replyThreads = shadowSlices[item.slice.uri]
|
||||||
|
|
||||||
// TODO linear view will work
|
// TODO linear view will work
|
||||||
if (!isTreeView) continue
|
if (!isTreeView) continue
|
||||||
@@ -361,19 +362,34 @@ export function useThread(
|
|||||||
for (let ri = 0; ri < thread.length; ri++) {
|
for (let ri = 0; ri < thread.length; ri++) {
|
||||||
const post = thread[ri]
|
const post = thread[ri]
|
||||||
post.depth = item.slice.depth + 1 + ri
|
post.depth = item.slice.depth + 1 + ri
|
||||||
flattened.splice(i + 1 + ri, 0, views.post({
|
const view = views.post({
|
||||||
item: post,
|
item: post,
|
||||||
oneUp: undefined,
|
oneUp: undefined,
|
||||||
oneDown: undefined,
|
oneDown: undefined,
|
||||||
moderationOpts,
|
moderationOpts,
|
||||||
}))
|
})
|
||||||
|
const insertIndex = i + 1 + ri
|
||||||
|
flattened.splice(
|
||||||
|
insertIndex,
|
||||||
|
// if same post, replace in situ
|
||||||
|
flattened[insertIndex]?.key === view.key ? 1 : 0,
|
||||||
|
view
|
||||||
|
)
|
||||||
|
// console.log('insert', {
|
||||||
|
// post: post.post.record?.text,
|
||||||
|
// depth: item.slice.depth + 1 + ri,
|
||||||
|
// ri,
|
||||||
|
// spliceIndex: i + 1 + ri,
|
||||||
|
// })
|
||||||
|
// console.log(flattened.map(f => f.slice?.post?.record?.text))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO may not need since inserts will be looped and ignored
|
||||||
i = i + thread.length
|
i = i + thread.length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return flattened
|
return [...flattened]
|
||||||
}, [flattened, shadowSlices, isTreeView])
|
}, [flattened, shadowSlices, isTreeView])
|
||||||
|
|
||||||
const items = useMemo(() => {
|
const items = useMemo(() => {
|
||||||
|
|||||||
@@ -412,6 +412,10 @@ export const ComposePost = ({
|
|||||||
if (res.data.thread.length !== thread.posts.length) {
|
if (res.data.thread.length !== thread.posts.length) {
|
||||||
throw new Error(`Not ready`)
|
throw new Error(`Not ready`)
|
||||||
}
|
}
|
||||||
|
const anchor = res.data.thread.at(0)
|
||||||
|
if (!AppBskyFeedDefs.isThreadItemPost(anchor)) {
|
||||||
|
throw new Error(`Not ready`)
|
||||||
|
}
|
||||||
return res.data.thread
|
return res.data.thread
|
||||||
}, 1e3)
|
}, 1e3)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ export function Inner({uri}: {uri: string | undefined}) {
|
|||||||
post: AppBskyFeedDefs.ThreadItemPost,
|
post: AppBskyFeedDefs.ThreadItemPost,
|
||||||
}) => (_: any, posts: AppBskyFeedDefs.ThreadItemPost[]) => {
|
}) => (_: any, posts: AppBskyFeedDefs.ThreadItemPost[]) => {
|
||||||
if (posts.length) {
|
if (posts.length) {
|
||||||
|
// TODO get parent and update reply count?
|
||||||
insertReplies(post.uri, posts)
|
insertReplies(post.uri, posts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user