Rename
This commit is contained in:
@@ -251,8 +251,7 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
item={item}
|
||||
threadgateRecord={thread.data.threadgate?.record ?? undefined}
|
||||
overrides={{
|
||||
moderation:
|
||||
thread.state.hiddenThreadItemsVisible && item.depth > 0,
|
||||
moderation: thread.state.otherItemsVisible && item.depth > 0,
|
||||
}}
|
||||
onPostSuccess={optimisticOnPostReply}
|
||||
/>
|
||||
@@ -263,8 +262,7 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
item={item}
|
||||
threadgateRecord={thread.data.threadgate?.record ?? undefined}
|
||||
overrides={{
|
||||
moderation:
|
||||
thread.state.hiddenThreadItemsVisible && item.depth > 0,
|
||||
moderation: thread.state.otherItemsVisible && item.depth > 0,
|
||||
}}
|
||||
onPostSuccess={optimisticOnPostReply}
|
||||
/>
|
||||
@@ -292,7 +290,7 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
} else if (item.type === 'showHiddenReplies') {
|
||||
} else if (item.type === 'showOtherReplies') {
|
||||
return (
|
||||
<PostThreadShowHiddenReplies type="hidden" onPress={item.onPress} />
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
sortAndAnnotateThreadItems,
|
||||
} from '#/state/queries/usePostThread/traversal'
|
||||
import {
|
||||
createPostThreadHiddenQueryKey,
|
||||
createPostThreadOtherQueryKey,
|
||||
createPostThreadQueryKey,
|
||||
type ThreadItem,
|
||||
type UsePostThreadQueryResult,
|
||||
@@ -47,7 +47,7 @@ export function usePostThread({anchor}: {anchor?: string}) {
|
||||
view,
|
||||
prioritizeFollowedUsers,
|
||||
})
|
||||
const postThreadHiddenQueryKey = createPostThreadHiddenQueryKey({
|
||||
const postThreadOtherQueryKey = createPostThreadOtherQueryKey({
|
||||
anchor,
|
||||
prioritizeFollowedUsers,
|
||||
})
|
||||
@@ -68,15 +68,15 @@ export function usePostThread({anchor}: {anchor?: string}) {
|
||||
)
|
||||
|
||||
/*
|
||||
* Initialize `ctx.meta` to track if there are hidden replies in any of
|
||||
* the fetched pages of results.
|
||||
* Initialize `ctx.meta` to track if we know we have additional replies
|
||||
* we could fetch once we hit the end.
|
||||
*/
|
||||
ctx.meta = ctx.meta || {
|
||||
hasHiddenReplies: false,
|
||||
}
|
||||
|
||||
/*
|
||||
* If we ever see hidden replies, we'll set this to true.
|
||||
* If we know we have additional replies, we'll set this to true.
|
||||
*/
|
||||
if (data.hasHiddenReplies) {
|
||||
ctx.meta.hasHiddenReplies = true
|
||||
@@ -120,12 +120,11 @@ export function usePostThread({anchor}: {anchor?: string}) {
|
||||
() => query.data?.threadgate,
|
||||
[query.data?.threadgate],
|
||||
)
|
||||
const hasServerHiddenThreadItems = useMemo(
|
||||
const hasOtherThreadItems = useMemo(
|
||||
() => !!query.data?.hasHiddenReplies,
|
||||
[query.data?.hasHiddenReplies],
|
||||
)
|
||||
const [hiddenThreadItemsVisible, setHiddenThreadItemsVisible] =
|
||||
useState(false)
|
||||
const [otherItemsVisible, setOtherItemsVisible] = useState(false)
|
||||
|
||||
/**
|
||||
* Creates a mutator for the post thread cache. This is used to insert
|
||||
@@ -136,21 +135,20 @@ export function usePostThread({anchor}: {anchor?: string}) {
|
||||
createCacheMutator({
|
||||
params: {view},
|
||||
postThreadQueryKey,
|
||||
postThreadHiddenQueryKey,
|
||||
postThreadOtherQueryKey,
|
||||
queryClient: qc,
|
||||
}),
|
||||
[qc, view, postThreadQueryKey, postThreadHiddenQueryKey],
|
||||
[qc, view, postThreadQueryKey, postThreadOtherQueryKey],
|
||||
)
|
||||
|
||||
/**
|
||||
* If we have server-hidden items and the user has chosen to view them,
|
||||
* start loading data
|
||||
* If we have additional items available from the server and the user has
|
||||
* chosen to view them, start loading data
|
||||
*/
|
||||
const hiddenQueryEnabled =
|
||||
hasServerHiddenThreadItems && hiddenThreadItemsVisible
|
||||
const hiddenQuery = useQuery({
|
||||
enabled: hiddenQueryEnabled,
|
||||
queryKey: postThreadHiddenQueryKey,
|
||||
const additionalQueryEnabled = hasOtherThreadItems && otherItemsVisible
|
||||
const additionalItemsQuery = useQuery({
|
||||
enabled: additionalQueryEnabled,
|
||||
queryKey: postThreadOtherQueryKey,
|
||||
async queryFn() {
|
||||
const {data} = await wait(
|
||||
400,
|
||||
@@ -162,24 +160,24 @@ export function usePostThread({anchor}: {anchor?: string}) {
|
||||
return data
|
||||
},
|
||||
})
|
||||
const serverHiddenThreadItems: ThreadItem[] = useMemo(() => {
|
||||
if (!hiddenQueryEnabled) return []
|
||||
if (hiddenQuery.isLoading) {
|
||||
const serverOtherThreadItems: ThreadItem[] = useMemo(() => {
|
||||
if (!additionalQueryEnabled) return []
|
||||
if (additionalItemsQuery.isLoading) {
|
||||
return Array.from({length: 2}).map((_, i) =>
|
||||
views.skeleton({
|
||||
key: `hidden-reply-${i}`,
|
||||
key: `other-reply-${i}`,
|
||||
item: 'reply',
|
||||
}),
|
||||
)
|
||||
} else if (hiddenQuery.isError) {
|
||||
} else if (additionalItemsQuery.isError) {
|
||||
// TODO could insert error component
|
||||
return []
|
||||
} else if (hiddenQuery.data?.thread) {
|
||||
} else if (additionalItemsQuery.data?.thread) {
|
||||
const {threadItems} = sortAndAnnotateThreadItems(
|
||||
hiddenQuery.data.thread,
|
||||
additionalItemsQuery.data.thread,
|
||||
{
|
||||
view,
|
||||
skipHiddenReplyHandling: true,
|
||||
skipModerationHandling: true,
|
||||
threadgateHiddenReplies: mergeThreadgateHiddenReplies(
|
||||
threadgate?.record,
|
||||
),
|
||||
@@ -192,40 +190,40 @@ export function usePostThread({anchor}: {anchor?: string}) {
|
||||
}
|
||||
}, [
|
||||
view,
|
||||
hiddenQueryEnabled,
|
||||
hiddenQuery,
|
||||
additionalQueryEnabled,
|
||||
additionalItemsQuery,
|
||||
mergeThreadgateHiddenReplies,
|
||||
moderationOpts,
|
||||
threadgate?.record,
|
||||
])
|
||||
|
||||
/**
|
||||
* Sets the sort order for the thread and resets the hidden items
|
||||
* Sets the sort order for the thread and resets the additional thread items
|
||||
*/
|
||||
const setSort: typeof baseSetSort = useCallback(
|
||||
nextSort => {
|
||||
setHiddenThreadItemsVisible(false)
|
||||
setOtherItemsVisible(false)
|
||||
baseSetSort(nextSort)
|
||||
},
|
||||
[baseSetSort, setHiddenThreadItemsVisible],
|
||||
[baseSetSort, setOtherItemsVisible],
|
||||
)
|
||||
|
||||
/**
|
||||
* Sets the view variant for the thread and resets the hidden items
|
||||
* Sets the view variant for the thread and resets the additional thread items
|
||||
*/
|
||||
const setView: typeof baseSetView = useCallback(
|
||||
nextView => {
|
||||
setHiddenThreadItemsVisible(false)
|
||||
setOtherItemsVisible(false)
|
||||
baseSetView(nextView)
|
||||
},
|
||||
[baseSetView, setHiddenThreadItemsVisible],
|
||||
[baseSetView, setOtherItemsVisible],
|
||||
)
|
||||
|
||||
/*
|
||||
* This is the main thread response, sorted into separate buckets based on
|
||||
* moderation, and annotated with all UI state needed for rendering.
|
||||
*/
|
||||
const {threadItems, hiddenThreadItems} = useMemo(() => {
|
||||
const {threadItems, otherThreadItems} = useMemo(() => {
|
||||
return sortAndAnnotateThreadItems(thread, {
|
||||
view: view,
|
||||
threadgateHiddenReplies: mergeThreadgateHiddenReplies(threadgate?.record),
|
||||
@@ -241,29 +239,29 @@ export function usePostThread({anchor}: {anchor?: string}) {
|
||||
|
||||
/*
|
||||
* Take all three sets of thread items and combine them into a single thread,
|
||||
* along with any other thread items required for rendering e.g. "Show hidden
|
||||
* along with any other thread items required for rendering e.g. "Show more
|
||||
* replies" or the reply composer.
|
||||
*/
|
||||
const items = useMemo(() => {
|
||||
return buildThread({
|
||||
threadItems,
|
||||
hiddenThreadItems,
|
||||
serverHiddenThreadItems,
|
||||
otherThreadItems,
|
||||
serverOtherThreadItems,
|
||||
isLoading: query.isPlaceholderData,
|
||||
hasSession,
|
||||
hasServerHiddenThreadItems,
|
||||
hiddenThreadItemsVisible,
|
||||
showHiddenThreadItems: () => setHiddenThreadItemsVisible(true),
|
||||
hasOtherThreadItems,
|
||||
otherItemsVisible,
|
||||
showOtherItems: () => setOtherItemsVisible(true),
|
||||
})
|
||||
}, [
|
||||
threadItems,
|
||||
hiddenThreadItems,
|
||||
serverHiddenThreadItems,
|
||||
otherThreadItems,
|
||||
serverOtherThreadItems,
|
||||
query.isPlaceholderData,
|
||||
hasSession,
|
||||
hasServerHiddenThreadItems,
|
||||
hiddenThreadItemsVisible,
|
||||
setHiddenThreadItemsVisible,
|
||||
hasOtherThreadItems,
|
||||
otherItemsVisible,
|
||||
setOtherItemsVisible,
|
||||
])
|
||||
|
||||
return useMemo(
|
||||
@@ -280,7 +278,7 @@ export function usePostThread({anchor}: {anchor?: string}) {
|
||||
*/
|
||||
sort,
|
||||
view,
|
||||
hiddenThreadItemsVisible,
|
||||
otherItemsVisible,
|
||||
},
|
||||
data: {
|
||||
items,
|
||||
@@ -302,7 +300,7 @@ export function usePostThread({anchor}: {anchor?: string}) {
|
||||
[
|
||||
query,
|
||||
mutator.insertReplies,
|
||||
hiddenThreadItemsVisible,
|
||||
otherItemsVisible,
|
||||
sort,
|
||||
view,
|
||||
setSort,
|
||||
|
||||
@@ -17,7 +17,7 @@ import {BELOW} from '#/state/queries/usePostThread/const'
|
||||
import {getBranch} from '#/state/queries/usePostThread/traversal'
|
||||
import {
|
||||
type ApiThreadItem,
|
||||
type createPostThreadHiddenQueryKey,
|
||||
type createPostThreadOtherQueryKey,
|
||||
type createPostThreadQueryKey,
|
||||
type PostThreadParams,
|
||||
postThreadQueryKeyRoot,
|
||||
@@ -30,12 +30,12 @@ import {embedViewRecordToPostView} from '#/state/queries/util'
|
||||
export function createCacheMutator({
|
||||
queryClient,
|
||||
postThreadQueryKey,
|
||||
postThreadHiddenQueryKey,
|
||||
postThreadOtherQueryKey,
|
||||
params,
|
||||
}: {
|
||||
queryClient: QueryClient
|
||||
postThreadQueryKey: ReturnType<typeof createPostThreadQueryKey>
|
||||
postThreadHiddenQueryKey: ReturnType<typeof createPostThreadHiddenQueryKey>
|
||||
postThreadOtherQueryKey: ReturnType<typeof createPostThreadOtherQueryKey>
|
||||
params: Pick<PostThreadParams, 'view'>
|
||||
}) {
|
||||
return {
|
||||
@@ -60,10 +60,10 @@ export function createCacheMutator({
|
||||
)
|
||||
|
||||
/*
|
||||
* Hidden threads query mutator.
|
||||
* Additional replies query mutator.
|
||||
*/
|
||||
queryClient.setQueryData<AppBskyUnspeccedGetPostThreadHiddenV2.OutputSchema>(
|
||||
postThreadHiddenQueryKey,
|
||||
postThreadOtherQueryKey,
|
||||
data => {
|
||||
if (!data) return
|
||||
console.log(data)
|
||||
|
||||
@@ -20,23 +20,23 @@ export function sortAndAnnotateThreadItems(
|
||||
threadgateHiddenReplies,
|
||||
moderationOpts,
|
||||
view,
|
||||
skipHiddenReplyHandling,
|
||||
skipModerationHandling,
|
||||
}: {
|
||||
threadgateHiddenReplies: Set<string>
|
||||
moderationOpts: ModerationOpts
|
||||
view: PostThreadParams['view']
|
||||
/**
|
||||
* Set to `true` in cases where we already know the moderation state of the
|
||||
* post e.g. when fetching server-hidden replies. This will prevent
|
||||
* additional sorting or nested-branch truncation, and all replies,
|
||||
* post e.g. when fetching additional replies from the server. This will
|
||||
* prevent additional sorting or nested-branch truncation, and all replies,
|
||||
* regardless of moderation state, will be included in the resulting
|
||||
* `threadItems` array.
|
||||
*/
|
||||
skipHiddenReplyHandling?: boolean
|
||||
skipModerationHandling?: boolean
|
||||
},
|
||||
) {
|
||||
const threadItems: ThreadItem[] = []
|
||||
const hiddenThreadItems: ThreadItem[] = []
|
||||
const otherThreadItems: ThreadItem[] = []
|
||||
const metadatas = new Map<string, TraversalMetadata>()
|
||||
|
||||
traversal: for (let i = 0; i < thread.length; i++) {
|
||||
@@ -140,7 +140,7 @@ export function sortAndAnnotateThreadItems(
|
||||
threadgateHiddenReplies,
|
||||
})
|
||||
|
||||
if (!post.isBlurred || skipHiddenReplyHandling) {
|
||||
if (!post.isBlurred || skipModerationHandling) {
|
||||
/*
|
||||
* Not moderated, need to insert it
|
||||
*/
|
||||
@@ -163,7 +163,7 @@ export function sortAndAnnotateThreadItems(
|
||||
|
||||
if (parentIsTopLevelReply) {
|
||||
// push branch anchor into sorted array
|
||||
hiddenThreadItems.push(parent)
|
||||
otherThreadItems.push(parent)
|
||||
// skip branch anchor in branch traversal
|
||||
const startIndex = branch.start + 1
|
||||
|
||||
@@ -199,14 +199,14 @@ export function sortAndAnnotateThreadItems(
|
||||
})
|
||||
|
||||
/*
|
||||
* If a child is hidden in any way, drop it an its sub-branch
|
||||
* If a child is moderated in any way, drop it an its sub-branch
|
||||
* entirely. To reveal these, the user must navigate to the
|
||||
* parent post directly.
|
||||
*/
|
||||
if (childPost.isBlurred) {
|
||||
ci = getBranch(thread, ci, child.depth).end
|
||||
} else {
|
||||
hiddenThreadItems.push(childPost)
|
||||
otherThreadItems.push(childPost)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -228,10 +228,10 @@ export function sortAndAnnotateThreadItems(
|
||||
}
|
||||
|
||||
/*
|
||||
* Both `threadItems` and `hiddenThreadItems` now need to be traversed again to fully compute
|
||||
* Both `threadItems` and `otherThreadItems` now need to be traversed again to fully compute
|
||||
* UI state based on collected metadata. These arrays will be muted in situ.
|
||||
*/
|
||||
for (const subset of [threadItems, hiddenThreadItems]) {
|
||||
for (const subset of [threadItems, otherThreadItems]) {
|
||||
for (let i = 0; i < subset.length; i++) {
|
||||
const item = subset[i]
|
||||
const prevItem = subset.at(i - 1)
|
||||
@@ -376,28 +376,28 @@ export function sortAndAnnotateThreadItems(
|
||||
|
||||
return {
|
||||
threadItems,
|
||||
hiddenThreadItems,
|
||||
otherThreadItems,
|
||||
}
|
||||
}
|
||||
|
||||
export function buildThread({
|
||||
threadItems,
|
||||
hiddenThreadItems,
|
||||
serverHiddenThreadItems,
|
||||
otherThreadItems,
|
||||
serverOtherThreadItems,
|
||||
isLoading,
|
||||
hasSession,
|
||||
hiddenThreadItemsVisible,
|
||||
hasServerHiddenThreadItems,
|
||||
showHiddenThreadItems,
|
||||
otherItemsVisible,
|
||||
hasOtherThreadItems,
|
||||
showOtherItems,
|
||||
}: {
|
||||
threadItems: ThreadItem[]
|
||||
hiddenThreadItems: ThreadItem[]
|
||||
serverHiddenThreadItems: ThreadItem[]
|
||||
otherThreadItems: ThreadItem[]
|
||||
serverOtherThreadItems: ThreadItem[]
|
||||
isLoading: boolean
|
||||
hasSession: boolean
|
||||
hiddenThreadItemsVisible: boolean
|
||||
hasServerHiddenThreadItems: boolean
|
||||
showHiddenThreadItems: () => void
|
||||
otherItemsVisible: boolean
|
||||
hasOtherThreadItems: boolean
|
||||
showOtherItems: () => void
|
||||
}) {
|
||||
/**
|
||||
* `threadItems` is memoized here, so don't mutate it directly.
|
||||
@@ -466,15 +466,15 @@ export function buildThread({
|
||||
}
|
||||
}
|
||||
|
||||
if (hiddenThreadItems.length || hasServerHiddenThreadItems) {
|
||||
if (hiddenThreadItemsVisible) {
|
||||
items.push(...hiddenThreadItems)
|
||||
items.push(...serverHiddenThreadItems)
|
||||
if (otherThreadItems.length || hasOtherThreadItems) {
|
||||
if (otherItemsVisible) {
|
||||
items.push(...otherThreadItems)
|
||||
items.push(...serverOtherThreadItems)
|
||||
} else {
|
||||
items.push({
|
||||
type: 'showHiddenReplies',
|
||||
key: 'showHiddenReplies',
|
||||
onPress: showHiddenThreadItems,
|
||||
type: 'showOtherReplies',
|
||||
key: 'showOtherReplies',
|
||||
onPress: showOtherItems,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ export const postThreadQueryKeyRoot = 'post-thread-v2' as const
|
||||
export const createPostThreadQueryKey = (props: PostThreadParams) =>
|
||||
[postThreadQueryKeyRoot, props] as const
|
||||
|
||||
export const createPostThreadHiddenQueryKey = (
|
||||
export const createPostThreadOtherQueryKey = (
|
||||
props: Omit<AppBskyUnspeccedGetPostThreadHiddenV2.QueryParams, 'anchor'> & {
|
||||
anchor?: string
|
||||
},
|
||||
) => [postThreadQueryKeyRoot, 'hidden', props] as const
|
||||
) => [postThreadQueryKeyRoot, 'other', props] as const
|
||||
|
||||
export type PostThreadParams = Pick<
|
||||
AppBskyUnspeccedGetPostThreadV2.QueryParams,
|
||||
@@ -88,7 +88,7 @@ export type ThreadItem =
|
||||
key: string
|
||||
}
|
||||
| {
|
||||
type: 'showHiddenReplies'
|
||||
type: 'showOtherReplies'
|
||||
key: string
|
||||
onPress: () => void
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user