Checkpoint: think we're good, needs more cleanup
This commit is contained in:
@@ -220,7 +220,7 @@ let PostThreadItemLoaded = ({
|
|||||||
!item.ui.showParentReplyLine && a.pt_lg,
|
!item.ui.showParentReplyLine && a.pt_lg,
|
||||||
!item.ui.showChildReplyLine && a.pb_sm,
|
!item.ui.showChildReplyLine && a.pb_sm,
|
||||||
],
|
],
|
||||||
item.ui.isDeadEnd &&
|
item.ui.isLastChild &&
|
||||||
!item.ui.precedesParentReadMore &&
|
!item.ui.precedesParentReadMore &&
|
||||||
!item.ui.precedesChildReadMore && [a.pb_sm],
|
!item.ui.precedesChildReadMore && [a.pb_sm],
|
||||||
]}>
|
]}>
|
||||||
|
|||||||
@@ -212,24 +212,11 @@ export function sort(
|
|||||||
continue traversal
|
continue traversal
|
||||||
} else if (AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(item.value)) {
|
} else if (AppBskyUnspeccedGetPostThreadV2.isThreadItemPost(item.value)) {
|
||||||
if (parentMetadata) {
|
if (parentMetadata) {
|
||||||
if (metadata) {
|
/*
|
||||||
metadata.replyIndex = parentMetadata.seenReplies
|
* Set this value before incrementing the parent's seenReplies
|
||||||
}
|
*/
|
||||||
|
metadata!.replyIndex = parentMetadata.seenReplies
|
||||||
parentMetadata.seenReplies += 1
|
parentMetadata.seenReplies += 1
|
||||||
|
|
||||||
if (metadata) {
|
|
||||||
metadata.isLastSibling =
|
|
||||||
parentMetadata.replies - parentMetadata.unhydratedReplies ===
|
|
||||||
parentMetadata.seenReplies
|
|
||||||
|
|
||||||
if (
|
|
||||||
parentMetadata.unhydratedReplies > 0 &&
|
|
||||||
metadata.isLastSibling
|
|
||||||
) {
|
|
||||||
metadata.upcomingParentReadMore = parentMetadata
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const post = views.threadPost({
|
const post = views.threadPost({
|
||||||
@@ -282,18 +269,11 @@ export function sort(
|
|||||||
parentMetadata: childParentMetadata,
|
parentMetadata: childParentMetadata,
|
||||||
})
|
})
|
||||||
if (childParentMetadata) {
|
if (childParentMetadata) {
|
||||||
|
/*
|
||||||
|
* Set this value before incrementing the parent's seenReplies
|
||||||
|
*/
|
||||||
|
childMetadata!.replyIndex = childParentMetadata.seenReplies
|
||||||
childParentMetadata.seenReplies += 1
|
childParentMetadata.seenReplies += 1
|
||||||
childMetadata.isLastSibling =
|
|
||||||
childParentMetadata.replies -
|
|
||||||
childParentMetadata.unhydratedReplies ===
|
|
||||||
childParentMetadata.seenReplies
|
|
||||||
|
|
||||||
if (
|
|
||||||
childParentMetadata.unhydratedReplies > 0 &&
|
|
||||||
childMetadata.isLastSibling
|
|
||||||
) {
|
|
||||||
childMetadata.upcomingParentReadMore = childParentMetadata
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
metadatas.set(item.uri, childMetadata)
|
metadatas.set(item.uri, childMetadata)
|
||||||
metadatas.set(childMetadata.text, childMetadata) // TODO debugging
|
metadatas.set(childMetadata.text, childMetadata) // TODO debugging
|
||||||
@@ -346,30 +326,94 @@ export function sort(
|
|||||||
|
|
||||||
if (item.type === 'threadPost') {
|
if (item.type === 'threadPost') {
|
||||||
const metadata = metadatas.get(item.uri)
|
const metadata = metadatas.get(item.uri)
|
||||||
|
|
||||||
if (metadata) {
|
if (metadata) {
|
||||||
if (metadata.parentMetadata) {
|
if (metadata.parentMetadata) {
|
||||||
|
/*
|
||||||
|
* Copy in the parent's skipped indents
|
||||||
|
*/
|
||||||
metadata.skippedIndents = new Set([
|
metadata.skippedIndents = new Set([
|
||||||
...metadata.parentMetadata.skippedIndents,
|
...metadata.parentMetadata.skippedIndents,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can now officially calculate `isLastSibling` based on the actual data that
|
||||||
|
* we've seen.
|
||||||
|
*/
|
||||||
|
metadata.isLastSibling =
|
||||||
|
metadata.replyIndex === metadata.parentMetadata.seenReplies - 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is the last sibling, it's implicitly part of the last
|
||||||
|
* branch of this sub-tree.
|
||||||
|
*/
|
||||||
|
if (metadata.isLastSibling) {
|
||||||
|
metadata.isPartOfLastBranchAtDepth = metadata.depth
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the parent is part of the last branch of the sub-tree, so is the child.
|
||||||
|
*/
|
||||||
|
if (metadata.parentMetadata.isPartOfLastBranchAtDepth) {
|
||||||
|
metadata.isPartOfLastBranchAtDepth = metadata.parentMetadata.isPartOfLastBranchAtDepth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is the last sibling, and the parent has unhydrated replies,
|
||||||
|
* at some point down the line we will need to show a "read more".
|
||||||
|
*/
|
||||||
if (
|
if (
|
||||||
metadata.isLastSibling &&
|
metadata.parentMetadata.unhydratedReplies > 0 &&
|
||||||
metadata.parentMetadata.unhydratedReplies <= 0
|
metadata.isLastSibling
|
||||||
) {
|
) {
|
||||||
|
metadata.upcomingParentReadMore = metadata.parentMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy in the parent's upcoming read more, if it exists. Once we
|
||||||
|
* reach the bottom, we'll insert a "read more"
|
||||||
|
*/
|
||||||
|
if (metadata.parentMetadata.upcomingParentReadMore) {
|
||||||
|
metadata.upcomingParentReadMore =
|
||||||
|
metadata.parentMetadata.upcomingParentReadMore
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this is the last sibling, and the parent has no unhydrated
|
||||||
|
* replies, then we know we can skip an indent line.
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
metadata.parentMetadata.unhydratedReplies <= 0 &&
|
||||||
|
metadata.isLastSibling
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* Depth is 2 more than the 0-index of the indent calculation
|
||||||
|
* bc of how we render these. So instead of handling that in the
|
||||||
|
* component, we just adjust that back to 0-index here.
|
||||||
|
*/
|
||||||
metadata.skippedIndents.add(item.depth - 2)
|
metadata.skippedIndents.add(item.depth - 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
/*
|
||||||
metadata.unhydratedReplies > 0 &&
|
* If this post has unhydrated replies, and it is the last child, then
|
||||||
(metadata.nextItemDepth === undefined ||
|
* it itself needs a "read more"
|
||||||
metadata.nextItemDepth <= item.depth)
|
*/
|
||||||
) {
|
if (metadata.unhydratedReplies > 0 && metadata.isLastChild) {
|
||||||
items.splice(i + 1, 0, views.readMore(metadata))
|
items.splice(i + 1, 0, views.readMore(metadata))
|
||||||
i++
|
i++ // skip next iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadata.upcomingParentReadMore && metadata.isDeadEnd) {
|
/*
|
||||||
|
* If there's an upcoming parent read more, this branch is part of the
|
||||||
|
* last branch of the sub-tree, and the item itself is the last child,
|
||||||
|
* insert the parent "read more".
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
metadata.upcomingParentReadMore &&
|
||||||
|
metadata.isPartOfLastBranchAtDepth === metadata.upcomingParentReadMore.depth &&
|
||||||
|
metadata.isLastChild
|
||||||
|
) {
|
||||||
items.splice(
|
items.splice(
|
||||||
i + 1,
|
i + 1,
|
||||||
0,
|
0,
|
||||||
@@ -378,6 +422,9 @@ export function sort(
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the final UI state for the thread item.
|
||||||
|
*/
|
||||||
item.ui = getThreadPostUI(metadata)
|
item.ui = getThreadPostUI(metadata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export type Slice =
|
|||||||
showChildReplyLine: boolean
|
showChildReplyLine: boolean
|
||||||
indent: number
|
indent: number
|
||||||
parentHasBranchingReplies: boolean
|
parentHasBranchingReplies: boolean
|
||||||
isDeadEnd: boolean
|
isLastChild: boolean
|
||||||
skippedIndents: Set<number>
|
skippedIndents: Set<number>
|
||||||
/**
|
/**
|
||||||
* Populated during the final traversal of the thread. Denotes whether
|
* Populated during the final traversal of the thread. Denotes whether
|
||||||
@@ -110,11 +110,34 @@ export type TraversalMetadata = {
|
|||||||
depth: number
|
depth: number
|
||||||
replies: number
|
replies: number
|
||||||
unhydratedReplies: number
|
unhydratedReplies: number
|
||||||
|
/**
|
||||||
|
* The number of replies that have been seen so far in the traversal. After
|
||||||
|
* traverssal, we can use this to calculate if we actually got all the
|
||||||
|
* replies we expected, or if some were blocked, etc.
|
||||||
|
*/
|
||||||
seenReplies: number
|
seenReplies: number
|
||||||
|
/**
|
||||||
|
* The index-0-based index of this reply in the parent post's replies.
|
||||||
|
*/
|
||||||
|
replyIndex: number
|
||||||
hasBranchingReplies: boolean
|
hasBranchingReplies: boolean
|
||||||
isLastSibling: boolean
|
isLastSibling: boolean
|
||||||
|
/**
|
||||||
|
* Indicates the post is the end-of-the-line for a given branch of replies.
|
||||||
|
*/
|
||||||
|
isLastChild: boolean
|
||||||
|
/**
|
||||||
|
* This is a live reference to the parent metadata object. Mutations to this
|
||||||
|
* are available for later use in children.
|
||||||
|
*/
|
||||||
parentMetadata?: TraversalMetadata
|
parentMetadata?: TraversalMetadata
|
||||||
|
/**
|
||||||
|
* The depth of the slice immediately preceding this one, if it exists.
|
||||||
|
*/
|
||||||
prevItemDepth?: number
|
prevItemDepth?: number
|
||||||
|
/**
|
||||||
|
* The depth of the slice immediately following this one, if it exists.
|
||||||
|
*/
|
||||||
nextItemDepth?: number
|
nextItemDepth?: number
|
||||||
skippedIndents: Set<number>
|
skippedIndents: Set<number>
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
|
|||||||
@@ -71,19 +71,30 @@ export function getTraversalMetadata({
|
|||||||
replies,
|
replies,
|
||||||
unhydratedReplies,
|
unhydratedReplies,
|
||||||
seenReplies: 0,
|
seenReplies: 0,
|
||||||
|
replyIndex: 0,
|
||||||
hasBranchingReplies,
|
hasBranchingReplies,
|
||||||
parentMetadata,
|
parentMetadata,
|
||||||
isLastSibling: false,
|
isTopLevelReply: item.depth === 1,
|
||||||
skippedIndents: new Set(),
|
skippedIndents: new Set(),
|
||||||
prevItemDepth: prevItem?.depth,
|
prevItemDepth: prevItem?.depth,
|
||||||
nextItemDepth: nextItem?.depth,
|
nextItemDepth: nextItem?.depth,
|
||||||
/*
|
/*
|
||||||
* If there are no slices below this one, or the next slice is less
|
* If it's a top level reply, bc we render each top-level branch as a
|
||||||
* indented than the computed indent for this post.
|
* separate tree, it's implicitly part of the last branch. For subsequent
|
||||||
|
* replies, we'll override this after traversal.
|
||||||
*/
|
*/
|
||||||
isDeadEnd: nextItem?.depth === undefined || nextItem?.depth < item.depth,
|
isPartOfLastBranchAtDepth: item.depth === 1 ? 1 : undefined,
|
||||||
|
/*
|
||||||
upcomingParentReadMore: parentMetadata?.upcomingParentReadMore || undefined,
|
* If there are no slices below this one, or the next slice has a depth <=
|
||||||
|
* than the depth of this post, it's the last child of the reply tree. It
|
||||||
|
* is not necessarily the last leaf in the parent branch, since it could
|
||||||
|
* have another sibling.
|
||||||
|
*/
|
||||||
|
isLastChild: nextItem?.depth === undefined || nextItem?.depth <= item.depth,
|
||||||
|
/*
|
||||||
|
* Unknown until after traversal
|
||||||
|
*/
|
||||||
|
isLastSibling: false,
|
||||||
|
|
||||||
// TODO non-spec
|
// TODO non-spec
|
||||||
text: getPostRecord(item.value.post).text,
|
text: getPostRecord(item.value.post).text,
|
||||||
@@ -95,7 +106,7 @@ export function getThreadPostUI({
|
|||||||
replies,
|
replies,
|
||||||
parentMetadata,
|
parentMetadata,
|
||||||
prevItemDepth,
|
prevItemDepth,
|
||||||
isDeadEnd,
|
isLastChild,
|
||||||
skippedIndents,
|
skippedIndents,
|
||||||
seenReplies,
|
seenReplies,
|
||||||
unhydratedReplies,
|
unhydratedReplies,
|
||||||
@@ -112,7 +123,7 @@ export function getThreadPostUI({
|
|||||||
* If there are no slices below this one, or the next slice is less
|
* If there are no slices below this one, or the next slice is less
|
||||||
* indented than the computed indent for this post.
|
* indented than the computed indent for this post.
|
||||||
*/
|
*/
|
||||||
isDeadEnd, //nextItemDepth === undefined || nextItemDepth < depth,
|
isLastChild, //nextItemDepth === undefined || nextItemDepth < depth,
|
||||||
skippedIndents,
|
skippedIndents,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user