Fix up traversal metadata

This commit is contained in:
Eric Bailey
2025-05-27 20:50:04 -05:00
parent e5cc0c0ed2
commit 1f73c05195
5 changed files with 58 additions and 27 deletions
@@ -4,7 +4,7 @@ import {useLingui} from '@lingui/react'
import {makeProfileLink} from '#/lib/routes/links'
import {type PostThreadParams, type Slice} from '#/state/queries/usePostThread'
import {TREE_AVI_WIDTH,TREE_INDENT} from '#/screens/PostThread/const'
import {TREE_AVI_WIDTH, TREE_INDENT} from '#/screens/PostThread/const'
import {atoms as a, useTheme} from '#/alf'
import {CirclePlus_Stroke2_Corner0_Rounded as CirclePlus} from '#/components/icons/CirclePlus'
import {Link} from '#/components/Link'
@@ -20,7 +20,7 @@ export function ReadMore({
const t = useTheme()
const {_} = useLingui()
const isTreeView = view === 'tree'
const indentCount = item.indent - 1
const indentCount = Math.max(0, item.indent - 1)
const treeIndents = isTreeView ? (
Array.from(Array(indentCount)).map((_, n: number) => (
+16 -4
View File
@@ -8,7 +8,12 @@ import {
HiddenReplyKind,
type PostThreadParams,
type Slice,
type TraversalMetadata,
} from '#/state/queries/usePostThread/types'
import {
getPostRecord,
getPostTraversalMetadata,
} from '#/state/queries/usePostThread/utils'
import * as views from '#/state/queries/usePostThread/views'
export function flatten(
@@ -168,6 +173,7 @@ export function sort(
const items: Slice[] = []
const hidden: Slice[] = []
const muted: Slice[] = []
const postDataMap = new Map<string, TraversalMetadata | undefined>()
traversal: for (let i = 0; i < thread.length; i++) {
const item = thread[i]
@@ -193,6 +199,8 @@ export function sort(
) {
items.push(views.threadPostBlocked(item))
} else if (AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(item.value)) {
postDataMap.set(item.uri, getPostTraversalMetadata(item))
items.push(
views.threadPost({
uri: item.uri,
@@ -261,14 +269,16 @@ export function sort(
i = branch.end
continue traversal
} else if (AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(item.value)) {
postDataMap.set(item.uri, getPostTraversalMetadata(item))
const oneUp = thread.at(i - 1)
const oneDown = thread.at(i + 1)
const post = views.threadPost({
uri: item.uri,
depth: item.depth,
value: item.value,
parent: thread.find(
p => p.uri === item.value.post.record.reply.parent.uri,
traversalMetadata: postDataMap.get(
getPostRecord(item.value.post)?.reply?.parent?.uri || '',
),
oneUp,
oneDown,
@@ -308,12 +318,14 @@ export function sort(
if (
AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(child.value)
) {
postDataMap.set(child.uri, getPostTraversalMetadata(child))
const childPost = views.threadPost({
uri: child.uri,
depth: child.depth,
value: child.value,
parent: thread.find(
p => p.uri === child.value.post.record.reply.parent.uri,
traversalMetadata: postDataMap.get(
getPostRecord(child.value.post)?.reply?.parent?.uri || '',
),
oneUp: thread[ci - 1],
oneDown: thread[ci + 1],
+5
View File
@@ -91,3 +91,8 @@ export type Slice =
nextAnchor: Extract<Slice, {type: 'threadPost'}>
nextAnchorUri: AtUri
}
export type TraversalMetadata = {
depth: number
hasBranchingReplies: boolean
}
+24 -1
View File
@@ -2,10 +2,11 @@ import {
type AppBskyFeedDefs,
AppBskyFeedPost,
AppBskyFeedThreadgate,
type AppBskyUnspeccedGetPostThreadV2,
AppBskyUnspeccedGetPostThreadV2,
AtUri,
} from '@atproto/api'
import {type TraversalMetadata} from '#/state/queries/usePostThread/types'
import * as bsky from '#/types/bsky'
export function getThreadgateRecord(
@@ -31,3 +32,25 @@ export function getRootPostAtUri(post: AppBskyFeedDefs.PostView) {
}
}
}
export function getPostRecord(post: AppBskyFeedDefs.PostView) {
return post.record as AppBskyFeedPost.Record
}
export function getPostTraversalMetadata(
item: AppBskyUnspeccedGetPostThreadV2.ThreadItem,
): TraversalMetadata | undefined {
if (!AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(item.value)) return
const replyCount = item.value.post.replyCount || 0
const unhydratedReplies = item.value.moreReplies || 0
return {
depth: item.depth,
/**
* If the post has more than a single reply, and the total reply count
* minus the number of replies not present in the response is greater than
* 1, then we must have more than a single branch of replies present in the
* response, which can affect how we render tree view.
*/
hasBranchingReplies: replyCount > 1 && replyCount - unhydratedReplies > 1,
}
}
+11 -20
View File
@@ -8,7 +8,10 @@ import {
type ModerationOpts,
} from '@atproto/api'
import {type Slice} from '#/state/queries/usePostThread/types'
import {
type Slice,
type TraversalMetadata,
} from '#/state/queries/usePostThread/types'
export function threadPostNoUnauthenticated({
uri,
@@ -65,32 +68,18 @@ export function threadPost({
uri,
depth,
value,
parent: up,
oneUp,
moderationOpts,
traversalMetadata,
}: {
uri: string
depth: number
value: $Typed<AppBskyUnspeccedGetPostThreadV2.ThreadItemPost>
parent?: AppBskyUnspeccedGetPostThreadV2.OutputSchema['thread'][number]
oneUp?: AppBskyUnspeccedGetPostThreadV2.OutputSchema['thread'][number]
oneDown?: AppBskyUnspeccedGetPostThreadV2.OutputSchema['thread'][number]
moderationOpts: ModerationOpts
traversalMetadata?: TraversalMetadata
}): Extract<Slice, {type: 'threadPost'}> {
const parent = (up && 'post' in up?.value
? up.value
: undefined) as unknown as AppBskyUnspeccedGetPostThreadV2.ThreadItemPost
const parentReplyCount = parent?.post?.replyCount || 0
const parentAdditionalReplies = parent?.moreReplies || 0
const parentHasBranchingReplies =
parentReplyCount > 1 && parentReplyCount - parentAdditionalReplies > 1
// if (!parentHasBranchingReplies) {
// console.log(value.post.record.text, {
// parentReplyCount,
// parentAdditionalReplies,
// })
// }
return {
type: 'threadPost',
key: uri,
@@ -111,8 +100,10 @@ export function threadPost({
isAnchor: depth === 0,
showParentReplyLine: !!oneUp && oneUp.depth !== 0 && oneUp.depth < depth,
showChildReplyLine: (value.post.replyCount || 0) > 0,
indent: parentHasBranchingReplies ? depth : up?.depth || depth,
parentHasBranchingReplies,
indent: traversalMetadata?.hasBranchingReplies
? depth
: traversalMetadata?.depth || depth,
parentHasBranchingReplies: !!traversalMetadata?.hasBranchingReplies,
},
}
}
@@ -127,7 +118,7 @@ export function readMore({
key: `readMore:${parent.uri}`,
indent: parent.ui.parentHasBranchingReplies
? parent.depth
: parent.depth - 1,
: Math.max(0, parent.depth - 1),
replyCount: parent.value.moreReplies,
nextAnchor: parent,
nextAnchorUri: new AtUri(parent.uri),