Clean up query a bit

This commit is contained in:
Eric Bailey
2025-05-31 14:24:15 -05:00
parent 45538dc0d8
commit 023755fc83
+46 -21
View File
@@ -1,4 +1,4 @@
import {useCallback, useMemo, useRef, useState} from 'react' import {useCallback, useMemo, useState} from 'react'
import {useQuery, useQueryClient} from '@tanstack/react-query' import {useQuery, useQueryClient} from '@tanstack/react-query'
import {wait} from '#/lib/async/wait' import {wait} from '#/lib/async/wait'
@@ -39,7 +39,7 @@ export function usePostThread({
enabled, enabled,
queryKey, queryKey,
gcTime: 0, gcTime: 0,
async queryFn() { async queryFn(ctx) {
const {data} = await wait( const {data} = await wait(
400, 400,
agent.app.bsky.unspecced.getPostThreadV2({ agent.app.bsky.unspecced.getPostThreadV2({
@@ -50,22 +50,37 @@ export function usePostThread({
prioritizeFollowedUsers: params.prioritizeFollowedUsers, prioritizeFollowedUsers: params.prioritizeFollowedUsers,
}), }),
) )
return data
},
placeholderData() {
if (!params.anchor) return
const placeholder = getThreadPlaceholder(qc, params.anchor) /*
* Initialize `ctx.meta` to track if there are hidden replies in any of
if (placeholder) { * the fetched pages of results.
return {thread: [placeholder], hasHiddenReplies: false} */
ctx.meta = ctx.meta || {
hasHiddenReplies: false,
} }
/* /*
* Return empty data here so that `isPlaceholderData` is always true, * If we ever see hidden replies, we'll set this to true.
* which we'll use to insert skeletons.
*/ */
return {thread: [], hasHiddenReplies: false} if (data.hasHiddenReplies) {
ctx.meta.hasHiddenReplies = true
}
return {
...data,
hasHiddenReplies: !!ctx.meta.hasHiddenReplies,
}
},
placeholderData() {
if (!params.anchor) return
const placeholder = getThreadPlaceholder(qc, params.anchor)
/*
* Always return something here, even empty data, so that
* `isPlaceholderData` is always true, which we'll use to insert
* skeletons.
*/
const thread = placeholder ? [placeholder] : []
return {thread, threadgate: undefined, hasHiddenReplies: false}
}, },
select(data) { select(data) {
const threadgate = getThreadgateRecord(data.threadgate) const threadgate = getThreadgateRecord(data.threadgate)
@@ -79,15 +94,19 @@ export function usePostThread({
}, },
}) })
const hasHiddenReplies = useRef(false) const hasHiddenReplies = !!query.data?.hasHiddenReplies
if (query?.data?.hasHiddenReplies) {
hasHiddenReplies.current = true
}
const [showHiddenReplies, setShowHiddenReplies] = useState(false) const [showHiddenReplies, setShowHiddenReplies] = useState(false)
const [hiddenReplies, setHiddenReplies] = useState<ThreadItem[]>([]) const [hiddenReplies, setHiddenReplies] = useState<ThreadItem[]>([])
/**
* Loads hidden replies for this thread. Any replies that are moderated from
* the initial visible response(s) are shown immediately. Remote data is
* fetched and inserted when it's available.
*/
const loadHiddenReplies = useCallback(async () => { const loadHiddenReplies = useCallback(async () => {
// immediately show any moderated replies already in memory
setShowHiddenReplies(true) setShowHiddenReplies(true)
// add skeletons for the replies that will be loaded
setHiddenReplies( setHiddenReplies(
Array.from({length: 2}).map((_, i) => ({ Array.from({length: 2}).map((_, i) => ({
type: 'skeleton', type: 'skeleton',
@@ -95,10 +114,12 @@ export function usePostThread({
item: 'reply', item: 'reply',
})), })),
) )
const queryParams = { const queryParams = {
anchor: params.anchor!, anchor: params.anchor!,
prioritizeFollowedUsers: params.prioritizeFollowedUsers, prioritizeFollowedUsers: params.prioritizeFollowedUsers,
} }
const data = await wait( const data = await wait(
400, 400,
qc.fetchQuery({ qc.fetchQuery({
@@ -111,6 +132,7 @@ export function usePostThread({
}, },
}), }),
) )
const items = traverse(data || [], { const items = traverse(data || [], {
threadgateHiddenReplies: mergeThreadgateHiddenReplies( threadgateHiddenReplies: mergeThreadgateHiddenReplies(
query.data?.threadgate?.record, query.data?.threadgate?.record,
@@ -118,11 +140,13 @@ export function usePostThread({
moderationOpts: moderationOpts!, moderationOpts: moderationOpts!,
hasSession, hasSession,
view: params.view, view: params.view,
hasHiddenReplies: hasHiddenReplies.current, hasHiddenReplies,
showHiddenReplies, showHiddenReplies,
skipHiddenReplyHandling: true, skipHiddenReplyHandling: true,
loadHiddenReplies, loadHiddenReplies,
}) })
// insert the hidden replies into the state
setHiddenReplies(items) setHiddenReplies(items)
}, [ }, [
agent, agent,
@@ -132,6 +156,7 @@ export function usePostThread({
moderationOpts, moderationOpts,
qc, qc,
query.data?.threadgate?.record, query.data?.threadgate?.record,
hasHiddenReplies,
showHiddenReplies, showHiddenReplies,
setShowHiddenReplies, setShowHiddenReplies,
]) ])
@@ -144,7 +169,7 @@ export function usePostThread({
moderationOpts: moderationOpts!, moderationOpts: moderationOpts!,
hasSession, hasSession,
view: params.view, view: params.view,
hasHiddenReplies: hasHiddenReplies.current, hasHiddenReplies,
showHiddenReplies, showHiddenReplies,
loadHiddenReplies, loadHiddenReplies,
}) })
@@ -156,6 +181,7 @@ export function usePostThread({
moderationOpts, moderationOpts,
hasSession, hasSession,
params.view, params.view,
hasHiddenReplies,
showHiddenReplies, showHiddenReplies,
loadHiddenReplies, loadHiddenReplies,
hiddenReplies, hiddenReplies,
@@ -210,7 +236,6 @@ export function usePostThread({
items, items,
threadgate: query.data?.threadgate, threadgate: query.data?.threadgate,
}, },
hasHiddenReplies: hasHiddenReplies.current,
showHiddenReplies, showHiddenReplies,
insertReplies: mutator.insertReplies, insertReplies: mutator.insertReplies,
}), }),