Checkpoint new traversal
This commit is contained in:
@@ -193,19 +193,14 @@ let PostThreadItemLoaded = ({
|
||||
],
|
||||
]}>
|
||||
{Array.from(Array(indents)).map((_, n: number) => {
|
||||
const isLastIteration = n === indents - 1
|
||||
const isSkipped = item.ui.skippedIndents.has(n)
|
||||
return (
|
||||
<View
|
||||
key={`${post.uri}-padding-${n}`}
|
||||
style={[
|
||||
t.atoms.border_contrast_low,
|
||||
{
|
||||
borderRightWidth:
|
||||
isLastIteration &&
|
||||
item.ui.isDeadEnd &&
|
||||
!item.ui.precedesParentReadMore
|
||||
? 0
|
||||
: REPLY_LINE_WIDTH,
|
||||
borderRightWidth: isSkipped ? 0 : REPLY_LINE_WIDTH,
|
||||
width: TREE_INDENT + TREE_AVI_WIDTH / 2,
|
||||
left: 1,
|
||||
},
|
||||
@@ -229,7 +224,7 @@ let PostThreadItemLoaded = ({
|
||||
!item.ui.precedesParentReadMore &&
|
||||
!item.ui.precedesChildReadMore && [a.pb_sm],
|
||||
]}>
|
||||
{item.ui.indent > 1 && item.ui.parentHasBranchingReplies && (
|
||||
{item.ui.indent > 1 && (
|
||||
<View
|
||||
style={[
|
||||
a.absolute,
|
||||
|
||||
@@ -41,7 +41,7 @@ export function usePostThread({
|
||||
const {data} = await agent.app.bsky.unspecced.getPostThreadV2({
|
||||
anchor: params.anchor!,
|
||||
branchingFactor: params.view === 'linear' ? 1 : 3, // 100 TODO
|
||||
below: 3,
|
||||
below: 6,
|
||||
sort: params.sort,
|
||||
prioritizeFollowedUsers: params.prioritizeFollowedUsers,
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
|
||||
import {
|
||||
HiddenReplyKind,
|
||||
type NTraversalMetadata,
|
||||
type PostThreadParams,
|
||||
type Slice,
|
||||
type TraversalMetadata,
|
||||
@@ -13,6 +14,8 @@ import {
|
||||
import {
|
||||
getPostRecord,
|
||||
getPostTraversalMetadata,
|
||||
getThreadPostUI,
|
||||
getTraversalMetadata,
|
||||
} from '#/state/queries/usePostThread/utils'
|
||||
import * as views from '#/state/queries/usePostThread/views'
|
||||
|
||||
@@ -147,7 +150,6 @@ export function flatten(
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(flattened)
|
||||
|
||||
/*
|
||||
* Insert hidden items and buttons to show them
|
||||
@@ -205,6 +207,11 @@ export function sort(
|
||||
const muted: Slice[] = []
|
||||
const postDataMap = new Map<string, TraversalMetadata | undefined>()
|
||||
|
||||
const metadatas = new Map<string, NTraversalMetadata>()
|
||||
|
||||
// @ts-ignore
|
||||
window.__data = metadatas // for debugging
|
||||
|
||||
traversal: for (let i = 0; i < thread.length; i++) {
|
||||
const item = thread[i]
|
||||
|
||||
@@ -297,8 +304,25 @@ 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
|
||||
}
|
||||
metadatas.set(item.uri, metadata)
|
||||
metadatas.set(metadata.text, metadata) // TODO debugging
|
||||
|
||||
const post = views.threadPost({
|
||||
uri: item.uri,
|
||||
depth: item.depth,
|
||||
@@ -345,6 +369,26 @@ export function sort(
|
||||
if (
|
||||
AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(child.value)
|
||||
) {
|
||||
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,
|
||||
parentMetadata: childParentMetadata,
|
||||
})
|
||||
if (childParentMetadata) {
|
||||
childParentMetadata.seenReplies += 1
|
||||
childMetadata.isLastSibling =
|
||||
childParentMetadata.replies ===
|
||||
childParentMetadata.seenReplies
|
||||
}
|
||||
metadatas.set(item.uri, childMetadata)
|
||||
metadatas.set(childMetadata.text, childMetadata) // TODO debugging
|
||||
|
||||
const childPost = views.threadPost({
|
||||
uri: child.uri,
|
||||
depth: child.depth,
|
||||
@@ -352,8 +396,8 @@ export function sort(
|
||||
traversalMetadata: postDataMap.get(
|
||||
getPostRecord(child.value.post)?.reply?.parent?.uri || '',
|
||||
),
|
||||
oneUp: thread[ci - 1],
|
||||
oneDown: thread[ci + 1],
|
||||
oneUp: prevItem,
|
||||
oneDown: nextItem,
|
||||
moderationOpts,
|
||||
})
|
||||
postDataMap.set(child.uri, getPostTraversalMetadata(childPost))
|
||||
@@ -394,6 +438,26 @@ export function sort(
|
||||
}
|
||||
}
|
||||
|
||||
for (const item of items) {
|
||||
if (item.type === 'threadPost') {
|
||||
const metadata = metadatas.get(item.uri)
|
||||
if (metadata) {
|
||||
if (metadata.parentMetadata) {
|
||||
metadata.skippedIndents = new Set([
|
||||
...metadata.parentMetadata.skippedIndents,
|
||||
])
|
||||
}
|
||||
if (metadata.isLastSibling) {
|
||||
metadata.skippedIndents.add(item.depth - 2)
|
||||
}
|
||||
|
||||
item.ui = getThreadPostUI(metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(metadatas)
|
||||
|
||||
return {
|
||||
items,
|
||||
hidden,
|
||||
|
||||
@@ -64,6 +64,8 @@ export type Slice =
|
||||
* this item.
|
||||
*/
|
||||
precedesChildReadMore?: boolean
|
||||
skippedIndents: Set<number>
|
||||
[key: string]: any
|
||||
}
|
||||
}
|
||||
| {
|
||||
@@ -109,3 +111,18 @@ export type TraversalMetadata = {
|
||||
indent: number
|
||||
hasBranchingReplies: boolean
|
||||
}
|
||||
|
||||
export type NTraversalMetadata = {
|
||||
depth: number
|
||||
indent: number
|
||||
replies: number
|
||||
unhydratedReplies: number
|
||||
seenReplies: number
|
||||
hasBranchingReplies: boolean
|
||||
isLastSibling: boolean
|
||||
parentMetadata?: NTraversalMetadata
|
||||
prevItemDepth?: number
|
||||
nextItemDepth?: number
|
||||
skippedIndents: Set<number>
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from '@atproto/api'
|
||||
|
||||
import {
|
||||
type NTraversalMetadata,
|
||||
type Slice,
|
||||
type TraversalMetadata,
|
||||
} from '#/state/queries/usePostThread/types'
|
||||
@@ -57,3 +58,67 @@ export function getPostTraversalMetadata(
|
||||
hasBranchingReplies: replyCount > 1 && replyCount - unhydratedReplies > 1,
|
||||
}
|
||||
}
|
||||
|
||||
export function getTraversalMetadata({
|
||||
item,
|
||||
prevItem,
|
||||
nextItem,
|
||||
parentMetadata,
|
||||
}: {
|
||||
item: AppBskyUnspeccedGetPostThreadV2.ThreadItem
|
||||
prevItem?: AppBskyUnspeccedGetPostThreadV2.ThreadItem
|
||||
nextItem?: AppBskyUnspeccedGetPostThreadV2.ThreadItem
|
||||
parentMetadata?: NTraversalMetadata
|
||||
}): NTraversalMetadata {
|
||||
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
|
||||
const hasBranchingReplies = replies > 1 && replies - unhydratedReplies > 1
|
||||
|
||||
return {
|
||||
depth: item.depth,
|
||||
// TODO maybe not used
|
||||
indent: parentMetadata?.hasBranchingReplies
|
||||
? item.depth
|
||||
: parentMetadata?.indent || item.depth,
|
||||
replies,
|
||||
unhydratedReplies,
|
||||
seenReplies: 0,
|
||||
hasBranchingReplies,
|
||||
parentMetadata,
|
||||
isLastSibling: false,
|
||||
skippedIndents: new Set(),
|
||||
prevItemDepth: prevItem?.depth,
|
||||
nextItemDepth: nextItem?.depth,
|
||||
|
||||
// TODO non-spec
|
||||
text: getPostRecord(item.value.post).text,
|
||||
}
|
||||
}
|
||||
|
||||
export function getThreadPostUI({
|
||||
depth,
|
||||
indent,
|
||||
replies,
|
||||
parentMetadata,
|
||||
prevItemDepth,
|
||||
nextItemDepth,
|
||||
skippedIndents,
|
||||
}: NTraversalMetadata) {
|
||||
return {
|
||||
isAnchor: depth === 0,
|
||||
showParentReplyLine:
|
||||
!!prevItemDepth && prevItemDepth !== 0 && prevItemDepth < depth,
|
||||
showChildReplyLine: replies > 0,
|
||||
indent: depth,
|
||||
parentHasBranchingReplies: !!parentMetadata?.hasBranchingReplies,
|
||||
/*
|
||||
* If there are no slices below this one, or the next slice is less
|
||||
* indented than the computed indent for this post.
|
||||
*/
|
||||
isDeadEnd: nextItemDepth === undefined || nextItemDepth < indent,
|
||||
skippedIndents,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,7 @@ export function threadPost({
|
||||
* indented than the computed indent for this post.
|
||||
*/
|
||||
isDeadEnd: !oneDown || oneDown?.depth < indent,
|
||||
skippedIndents: new Set(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -152,11 +153,9 @@ export function postViewToThreadPlaceholder(
|
||||
value: {
|
||||
$type: 'app.bsky.unspecced.getPostThreadV2#threadItemPost',
|
||||
post,
|
||||
hiddenByThreadgate: false,
|
||||
opThread: false,
|
||||
moreParents: false,
|
||||
moreReplies: 0,
|
||||
mutedByViewer: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user