Refactor client-side hidden
This commit is contained in:
@@ -9,11 +9,7 @@ import {ScrollProvider} from '#/lib/ScrollContext'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useThreadPreferences} from '#/state/queries/preferences/useThreadPreferences'
|
||||
import {
|
||||
HiddenReplyKind,
|
||||
type ThreadItem,
|
||||
usePostThread,
|
||||
} from '#/state/queries/usePostThread'
|
||||
import {type ThreadItem, usePostThread} from '#/state/queries/usePostThread'
|
||||
import {type OnPostSuccessData} from '#/state/shell/composer'
|
||||
import {PostThreadComposePrompt} from '#/view/com/post-thread/PostThreadComposePrompt'
|
||||
import {PostThreadShowHiddenReplies} from '#/view/com/post-thread/PostThreadShowHiddenReplies'
|
||||
@@ -53,22 +49,16 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
setTreeViewEnabled,
|
||||
} = useThreadPreferences()
|
||||
|
||||
const [shownHiddenReplyKinds, setShownHiddenReplyKinds] = useState<
|
||||
Set<HiddenReplyKind>
|
||||
>(new Set())
|
||||
|
||||
const {isFetching, error, data, refetch, insertReplies} = usePostThread({
|
||||
enabled: isThreadPreferencesLoaded,
|
||||
params: {
|
||||
anchor: uri,
|
||||
sort: sortReplies,
|
||||
view: treeViewEnabled ? 'tree' : 'linear',
|
||||
prioritizeFollowedUsers,
|
||||
},
|
||||
state: {
|
||||
shownHiddenReplyKinds,
|
||||
},
|
||||
})
|
||||
const {isFetching, error, data, refetch, insertReplies, showHiddenReplies} =
|
||||
usePostThread({
|
||||
enabled: isThreadPreferencesLoaded,
|
||||
params: {
|
||||
anchor: uri,
|
||||
sort: sortReplies,
|
||||
view: treeViewEnabled ? 'tree' : 'linear',
|
||||
prioritizeFollowedUsers,
|
||||
},
|
||||
})
|
||||
|
||||
const optimisticOnPostReply = (data: OnPostSuccessData) => {
|
||||
if (data) {
|
||||
@@ -242,9 +232,7 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
item={item}
|
||||
threadgateRecord={data?.threadgate?.record ?? undefined}
|
||||
overrides={{
|
||||
moderation:
|
||||
shownHiddenReplyKinds.has(HiddenReplyKind.Hidden) &&
|
||||
item.depth > 0,
|
||||
moderation: showHiddenReplies && item.depth > 0,
|
||||
}}
|
||||
onPostSuccess={optimisticOnPostReply}
|
||||
/>
|
||||
@@ -255,9 +243,7 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
item={item}
|
||||
threadgateRecord={data?.threadgate?.record ?? undefined}
|
||||
overrides={{
|
||||
moderation:
|
||||
shownHiddenReplyKinds.has(HiddenReplyKind.Muted) &&
|
||||
item.depth > 0,
|
||||
moderation: showHiddenReplies && item.depth > 0,
|
||||
}}
|
||||
onPostSuccess={optimisticOnPostReply}
|
||||
/>
|
||||
@@ -305,10 +291,8 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
} else if (item.type === 'showHiddenReplies') {
|
||||
return (
|
||||
<PostThreadShowHiddenReplies
|
||||
type={item.kind === 'muted' ? 'muted' : 'hidden'}
|
||||
onPress={() =>
|
||||
setShownHiddenReplyKinds(kinds => new Set([...kinds, item.kind]))
|
||||
}
|
||||
type="hidden"
|
||||
onPress={() => item.onLoad()}
|
||||
/>
|
||||
)
|
||||
} else if (item.type === 'skeleton') {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {useMemo} from 'react'
|
||||
import {useCallback, useMemo, useRef, useState} from 'react'
|
||||
import {useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
import {traverse} from '#/state/queries/usePostThread/traversal'
|
||||
import {
|
||||
createPostThreadQueryKey,
|
||||
HiddenReplyKind,
|
||||
type UsePostThreadProps,
|
||||
} from '#/state/queries/usePostThread/types'
|
||||
import {getThreadgateRecord} from '#/state/queries/usePostThread/utils'
|
||||
@@ -21,7 +20,6 @@ export * from '#/state/queries/usePostThread/types'
|
||||
export function usePostThread({
|
||||
enabled: isEnabled,
|
||||
params,
|
||||
state,
|
||||
}: UsePostThreadProps) {
|
||||
const qc = useQueryClient()
|
||||
const agent = useAgent()
|
||||
@@ -34,6 +32,9 @@ export function usePostThread({
|
||||
params,
|
||||
})
|
||||
|
||||
const hasHiddenReplies = useRef(false)
|
||||
const [showHiddenReplies, setShowHiddenReplies] = useState(false)
|
||||
|
||||
const query = useQuery({
|
||||
enabled,
|
||||
queryKey,
|
||||
@@ -50,10 +51,17 @@ export function usePostThread({
|
||||
},
|
||||
placeholderData() {
|
||||
if (!params.anchor) return
|
||||
|
||||
const placeholder = getThreadPlaceholder(qc, params.anchor)
|
||||
|
||||
if (placeholder) {
|
||||
return {thread: [placeholder], hasHiddenReplies: false}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return empty data here so that `isPlaceholderData` is always true,
|
||||
* which we'll use to insert skeletons.
|
||||
*/
|
||||
return {thread: [], hasHiddenReplies: false}
|
||||
},
|
||||
select(data) {
|
||||
@@ -68,7 +76,13 @@ export function usePostThread({
|
||||
},
|
||||
})
|
||||
|
||||
// TODO map over pages, just like feeds
|
||||
if (query?.data?.hasHiddenReplies) {
|
||||
hasHiddenReplies.current = true
|
||||
}
|
||||
|
||||
const loadHiddenReplies = useCallback(async () => {
|
||||
setShowHiddenReplies(true)
|
||||
}, [setShowHiddenReplies])
|
||||
|
||||
const items = useMemo(() => {
|
||||
return traverse(query.data?.thread || [], {
|
||||
@@ -77,25 +91,21 @@ export function usePostThread({
|
||||
),
|
||||
moderationOpts: moderationOpts!,
|
||||
hasSession,
|
||||
showMuted: state.shownHiddenReplyKinds.has(HiddenReplyKind.Muted),
|
||||
showHidden: state.shownHiddenReplyKinds.has(HiddenReplyKind.Hidden),
|
||||
view: params.view,
|
||||
hasHiddenReplies: hasHiddenReplies.current,
|
||||
showHiddenReplies,
|
||||
loadHiddenReplies,
|
||||
})
|
||||
}, [
|
||||
query.data,
|
||||
mergeThreadgateHiddenReplies,
|
||||
moderationOpts,
|
||||
hasSession,
|
||||
state.shownHiddenReplyKinds,
|
||||
params.view,
|
||||
showHiddenReplies,
|
||||
loadHiddenReplies,
|
||||
])
|
||||
|
||||
const mutator = createCacheMutator({
|
||||
params,
|
||||
queryKey,
|
||||
queryClient: qc,
|
||||
})
|
||||
|
||||
if (query.isPlaceholderData) {
|
||||
const anchor = items.at(0)
|
||||
const skeletonReplies =
|
||||
@@ -128,12 +138,27 @@ export function usePostThread({
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...query,
|
||||
data: {
|
||||
items,
|
||||
threadgate: query.data?.threadgate,
|
||||
},
|
||||
insertReplies: mutator.insertReplies,
|
||||
}
|
||||
const mutator = useMemo(
|
||||
() =>
|
||||
createCacheMutator({
|
||||
params,
|
||||
queryKey,
|
||||
queryClient: qc,
|
||||
}),
|
||||
[qc, params, queryKey],
|
||||
)
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
...query,
|
||||
data: {
|
||||
items,
|
||||
threadgate: query.data?.threadgate,
|
||||
},
|
||||
hasHiddenReplies: hasHiddenReplies.current,
|
||||
showHiddenReplies,
|
||||
insertReplies: mutator.insertReplies,
|
||||
}),
|
||||
[query, items, mutator.insertReplies, showHiddenReplies],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
} from '@atproto/api'
|
||||
|
||||
import {
|
||||
HiddenReplyKind,
|
||||
type PostThreadParams,
|
||||
type ThreadItem,
|
||||
type TraversalMetadata,
|
||||
@@ -24,21 +23,22 @@ export function traverse(
|
||||
threadgateHiddenReplies,
|
||||
moderationOpts,
|
||||
hasSession,
|
||||
showMuted,
|
||||
showHidden,
|
||||
view,
|
||||
hasHiddenReplies,
|
||||
showHiddenReplies,
|
||||
loadHiddenReplies,
|
||||
}: {
|
||||
threadgateHiddenReplies: Set<string>
|
||||
moderationOpts: ModerationOpts
|
||||
hasSession: boolean
|
||||
showMuted: boolean
|
||||
showHidden: boolean
|
||||
view: PostThreadParams['view']
|
||||
hasHiddenReplies: boolean
|
||||
showHiddenReplies: boolean
|
||||
loadHiddenReplies: () => Promise<void>
|
||||
},
|
||||
) {
|
||||
const items: ThreadItem[] = []
|
||||
const hidden: ThreadItem[] = []
|
||||
const muted: ThreadItem[] = []
|
||||
const metadatas = new Map<string, TraversalMetadata>()
|
||||
|
||||
traversal: for (let i = 0; i < thread.length; i++) {
|
||||
@@ -178,16 +178,13 @@ export function traverse(
|
||||
* Moderated in some way, we're going to walk children
|
||||
*/
|
||||
const parent = post
|
||||
const parentMod = postMod
|
||||
const parentIsTopLevelReply = parent.depth === 1
|
||||
const sortArray = parentMod.muted ? muted : hidden
|
||||
|
||||
// get sub tree
|
||||
const branch = getBranch(thread, i, item.depth)
|
||||
|
||||
if (parentIsTopLevelReply) {
|
||||
// push branch anchor into sorted array
|
||||
sortArray.push(parent)
|
||||
hidden.push(parent)
|
||||
// skip branch anchor in branch traversal
|
||||
const startIndex = branch.start + 1
|
||||
|
||||
@@ -238,7 +235,7 @@ export function traverse(
|
||||
) {
|
||||
ci = getBranch(thread, ci, child.depth).end
|
||||
} else {
|
||||
sortArray.push(childPost)
|
||||
hidden.push(childPost)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -259,36 +256,14 @@ export function traverse(
|
||||
}
|
||||
}
|
||||
|
||||
if (hidden.length) {
|
||||
if (showHidden) {
|
||||
if (hidden.length || hasHiddenReplies) {
|
||||
if (showHiddenReplies) {
|
||||
items.push(...hidden)
|
||||
|
||||
if (muted.length) {
|
||||
if (showMuted) {
|
||||
items.push(...muted)
|
||||
} else {
|
||||
items.push({
|
||||
type: 'showHiddenReplies',
|
||||
key: 'showMutedReplies',
|
||||
kind: HiddenReplyKind.Muted,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
items.push({
|
||||
type: 'showHiddenReplies',
|
||||
key: 'showHiddenReplies',
|
||||
kind: HiddenReplyKind.Hidden,
|
||||
})
|
||||
}
|
||||
} else if (muted.length) {
|
||||
if (showMuted) {
|
||||
items.push(...muted)
|
||||
} else {
|
||||
items.push({
|
||||
type: 'showHiddenReplies',
|
||||
key: 'showMutedReplies',
|
||||
kind: HiddenReplyKind.Muted,
|
||||
onLoad: loadHiddenReplies,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,14 +22,6 @@ export type PostThreadParams = Pick<
|
||||
export type UsePostThreadProps = {
|
||||
enabled?: boolean
|
||||
params: PostThreadParams
|
||||
state: {
|
||||
shownHiddenReplyKinds: Set<HiddenReplyKind>
|
||||
}
|
||||
}
|
||||
|
||||
export enum HiddenReplyKind {
|
||||
Hidden = 'hidden',
|
||||
Muted = 'muted',
|
||||
}
|
||||
|
||||
export type ThreadItem =
|
||||
@@ -82,7 +74,7 @@ export type ThreadItem =
|
||||
| {
|
||||
type: 'showHiddenReplies'
|
||||
key: string
|
||||
kind: HiddenReplyKind
|
||||
onLoad: () => Promise<void>
|
||||
}
|
||||
| {
|
||||
type: 'readMore'
|
||||
|
||||
Reference in New Issue
Block a user