diff --git a/src/state/queries/usePostThread/traversal.ts b/src/state/queries/usePostThread/traversal.ts index 6d95db7aa1..537cc2532e 100644 --- a/src/state/queries/usePostThread/traversal.ts +++ b/src/state/queries/usePostThread/traversal.ts @@ -6,14 +6,12 @@ import { import { HiddenReplyKind, - type NTraversalMetadata, type PostThreadParams, type Slice, type TraversalMetadata, } from '#/state/queries/usePostThread/types' import { getPostRecord, - getPostTraversalMetadata, getThreadPostUI, getTraversalMetadata, } from '#/state/queries/usePostThread/utils' @@ -205,15 +203,29 @@ export function sort( const items: Slice[] = [] const hidden: Slice[] = [] const muted: Slice[] = [] - const postDataMap = new Map() - - const metadatas = new Map() + const metadatas = new Map() // @ts-ignore window.__data = metadatas // for debugging traversal: for (let i = 0; i < thread.length; i++) { const item = thread[i] + let parentMetadata: TraversalMetadata | undefined + let metadata: TraversalMetadata | undefined + + if (AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(item.value)) { + parentMetadata = metadatas.get( + getPostRecord(item.value.post).reply?.parent?.uri || '', + ) + metadata = getTraversalMetadata({ + item, + parentMetadata, + prevItem: thread.at(i - 1), + nextItem: thread.at(i + 1), + }) + metadatas.set(item.uri, metadata) + metadatas.set(metadata.text, metadata) // TODO debugging + } if (item.depth < 0) { /* @@ -240,17 +252,12 @@ export function sort( uri: item.uri, depth: item.depth, value: item.value, - oneUp: thread[i - 1], - oneDown: thread[i + 1], moderationOpts, }) - postDataMap.set(item.uri, getPostTraversalMetadata(post)) items.push(post) parentTraversal: for (let pi = i - 1; pi >= 0; pi--) { - const parentOneDown = thread[pi + 1] const parent = thread[pi] - const parentOneUp = thread[pi - 1] if ( AppBskyUnspeccedGetPostThreadV2.isThreadItemNoUnauthenticated( @@ -277,8 +284,6 @@ export function sort( uri: parent.uri, depth: parent.depth, value: parent.value, - oneUp: parentOneUp, - oneDown: parentOneDown, moderationOpts, }), ) @@ -304,37 +309,20 @@ export function sort( i = branch.end continue traversal } else if (AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(item.value)) { - const parentMetadata = metadatas.get( - getPostRecord(item.value.post).reply?.parent?.uri || '', - ) - const oneUp = thread.at(i - 1) - const oneDown = thread.at(i + 1) - const metadata = getTraversalMetadata({ - item, - parentMetadata, - prevItem: oneUp, - nextItem: oneDown, - }) if (parentMetadata) { parentMetadata.seenReplies += 1 - metadata.isLastSibling = - parentMetadata.replies === parentMetadata.seenReplies + if (metadata) { + metadata.isLastSibling = + parentMetadata.replies === parentMetadata.seenReplies + } } - metadatas.set(item.uri, metadata) - metadatas.set(metadata.text, metadata) // TODO debugging const post = views.threadPost({ uri: item.uri, depth: item.depth, value: item.value, - traversalMetadata: postDataMap.get( - getPostRecord(item.value.post)?.reply?.parent?.uri || '', - ), - oneUp, - oneDown, moderationOpts, }) - postDataMap.set(item.uri, getPostTraversalMetadata(post)) const postMod = getModerationState(post.moderation) const postIsHiddenByThreadgate = threadgateHiddenReplies.has(item.uri) const postIsModerated = @@ -372,12 +360,10 @@ export function sort( const childParentMetadata = metadatas.get( getPostRecord(child.value.post).reply?.parent?.uri || '', ) - const prevItem = thread[ci - 1] - const nextItem = thread[ci + 1] const childMetadata = getTraversalMetadata({ item: child, - prevItem, - nextItem, + prevItem: thread[ci - 1], + nextItem: thread[ci + 1], parentMetadata: childParentMetadata, }) if (childParentMetadata) { @@ -393,14 +379,8 @@ export function sort( uri: child.uri, depth: child.depth, value: child.value, - traversalMetadata: postDataMap.get( - getPostRecord(child.value.post)?.reply?.parent?.uri || '', - ), - oneUp: prevItem, - oneDown: nextItem, moderationOpts, }) - postDataMap.set(child.uri, getPostTraversalMetadata(childPost)) const childPostMod = getModerationState(childPost.moderation) const childPostIsHiddenByThreadgate = threadgateHiddenReplies.has(child.uri) diff --git a/src/state/queries/usePostThread/types.ts b/src/state/queries/usePostThread/types.ts index 3e64d78eef..8d509ce43a 100644 --- a/src/state/queries/usePostThread/types.ts +++ b/src/state/queries/usePostThread/types.ts @@ -52,6 +52,7 @@ export type Slice = indent: number parentHasBranchingReplies: boolean isDeadEnd: boolean + skippedIndents: Set /** * Populated during the final traversal of the thread. Denotes whether * there is a "Read more" link for the parent immediately following @@ -64,8 +65,6 @@ export type Slice = * this item. */ precedesChildReadMore?: boolean - skippedIndents: Set - [key: string]: any } } | { @@ -108,11 +107,6 @@ export type Slice = } export type TraversalMetadata = { - indent: number - hasBranchingReplies: boolean -} - -export type NTraversalMetadata = { depth: number indent: number replies: number @@ -120,7 +114,7 @@ export type NTraversalMetadata = { seenReplies: number hasBranchingReplies: boolean isLastSibling: boolean - parentMetadata?: NTraversalMetadata + parentMetadata?: TraversalMetadata prevItemDepth?: number nextItemDepth?: number skippedIndents: Set diff --git a/src/state/queries/usePostThread/utils.ts b/src/state/queries/usePostThread/utils.ts index 592472bac4..509c340bf2 100644 --- a/src/state/queries/usePostThread/utils.ts +++ b/src/state/queries/usePostThread/utils.ts @@ -7,7 +7,6 @@ import { } from '@atproto/api' import { - type NTraversalMetadata, type Slice, type TraversalMetadata, } from '#/state/queries/usePostThread/types' @@ -41,24 +40,6 @@ export function getPostRecord(post: AppBskyFeedDefs.PostView) { return post.record as AppBskyFeedPost.Record } -export function getPostTraversalMetadata( - item: Extract, -): TraversalMetadata | undefined { - if (!AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(item.value)) return - const replyCount = item.value.post.replyCount || 0 - const unhydratedReplies = item.value.moreReplies || 0 - return { - indent: item.ui.indent, - /** - * 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, - } -} - export function getTraversalMetadata({ item, prevItem, @@ -68,13 +49,19 @@ export function getTraversalMetadata({ item: AppBskyUnspeccedGetPostThreadV2.ThreadItem prevItem?: AppBskyUnspeccedGetPostThreadV2.ThreadItem nextItem?: AppBskyUnspeccedGetPostThreadV2.ThreadItem - parentMetadata?: NTraversalMetadata -}): NTraversalMetadata { + parentMetadata?: TraversalMetadata +}): TraversalMetadata { if (!AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(item.value)) { throw new Error(`Expected thread item to be a post`) } const replies = item.value.post.replyCount || 0 const unhydratedReplies = item.value.moreReplies || 0 + /** + * 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. + */ const hasBranchingReplies = replies > 1 && replies - unhydratedReplies > 1 return { @@ -106,7 +93,7 @@ export function getThreadPostUI({ prevItemDepth, nextItemDepth, skippedIndents, -}: NTraversalMetadata) { +}: TraversalMetadata): Extract['ui'] { return { isAnchor: depth === 0, showParentReplyLine: diff --git a/src/state/queries/usePostThread/views.ts b/src/state/queries/usePostThread/views.ts index e763fe38f4..8619332e24 100644 --- a/src/state/queries/usePostThread/views.ts +++ b/src/state/queries/usePostThread/views.ts @@ -8,10 +8,7 @@ import { type ModerationOpts, } from '@atproto/api' -import { - type Slice, - type TraversalMetadata, -} from '#/state/queries/usePostThread/types' +import {type Slice} from '#/state/queries/usePostThread/types' export function threadPostNoUnauthenticated({ uri, @@ -68,28 +65,13 @@ export function threadPost({ uri, depth, value, - oneUp, - oneDown, moderationOpts, - traversalMetadata, }: { uri: string depth: number value: $Typed - oneUp?: AppBskyUnspeccedGetPostThreadV2.OutputSchema['thread'][number] - oneDown?: AppBskyUnspeccedGetPostThreadV2.OutputSchema['thread'][number] moderationOpts: ModerationOpts - traversalMetadata?: TraversalMetadata }): Extract { - const parentHasBranchingReplies = !!traversalMetadata?.hasBranchingReplies - /* - * Indent differs from depth in cases where the tree has no branches, and so - * we can maintain the more shallow depth of the parent. - */ - const indent = parentHasBranchingReplies - ? depth - : traversalMetadata?.indent || depth - return { type: 'threadPost', key: uri, @@ -106,19 +88,8 @@ export function threadPost({ }, }, moderation: moderatePost(value.post, moderationOpts), - ui: { - isAnchor: depth === 0, - showParentReplyLine: !!oneUp && oneUp.depth !== 0 && oneUp.depth < depth, - showChildReplyLine: (value.post.replyCount || 0) > 0, - indent, - parentHasBranchingReplies, - /* - * If there are no slices below this one, or the next slice is less - * indented than the computed indent for this post. - */ - isDeadEnd: !oneDown || oneDown?.depth < indent, - skippedIndents: new Set(), - }, + // @ts-ignore populated by the traversal + ui: {}, } }