Fix hidden reply handling, seen count, before/after calc

This commit is contained in:
Eric Bailey
2025-05-30 09:38:17 -05:00
parent dc43040d7a
commit cc4da37bab
4 changed files with 88 additions and 56 deletions
+1 -1
View File
@@ -237,7 +237,7 @@ export function Inner({uri}: {uri: string | undefined}) {
threadgateRecord={data?.threadgate?.record ?? undefined}
overrides={{
moderation:
shownHiddenReplyKinds.has(HiddenReplyKind.Muted) &&
shownHiddenReplyKinds.has(HiddenReplyKind.Hidden) &&
item.depth > 0,
}}
onPostSuccess={optimisticOnPostReply}
+67 -45
View File
@@ -145,8 +145,9 @@ export function traverse(
/*
* Set this value before incrementing the parent's repliesSeenCount
*/
metadata!.repliesIndex = parentMetadata.repliesSeenCount
parentMetadata.repliesSeenCount += 1
metadata!.repliesIndex = parentMetadata.repliesIndexCount
// Increment the parent's repliesIndexCount
parentMetadata.repliesIndexCount += 1
}
const post = views.threadPost({
@@ -165,6 +166,13 @@ export function traverse(
* Not moderated, probably need to insert it
*/
items.push(post)
/*
* Update seen reply count of parent
*/
if (parentMetadata) {
parentMetadata.repliesSeenCount += 1
}
} else {
/*
* Moderated in some way, we're going to walk children
@@ -201,11 +209,11 @@ export function traverse(
storeTraversalMetadata(metadatas, childMetadata)
if (childParentMetadata) {
/*
* Set this value before incrementing the parent's repliesSeenCount
* Set this value before incrementing the parent's repliesIndexCount
*/
childMetadata!.repliesIndex =
childParentMetadata.repliesSeenCount
childParentMetadata.repliesSeenCount += 1
childParentMetadata.repliesIndexCount
childParentMetadata.repliesIndexCount += 1
}
const childPost = views.threadPost({
@@ -251,8 +259,44 @@ export function traverse(
}
}
if (hidden.length) {
if (showHidden) {
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,
})
}
}
for (let i = 0; i < items.length; i++) {
const item = items[i]
const prevItem = items.at(i - 1)
const nextItem = items.at(i + 1)
if (item.type === 'threadPost') {
if (
@@ -272,19 +316,23 @@ export function traverse(
if (metadata) {
if (metadata.parentMetadata) {
/*
* Copy in the parent's skipped indents
* Track what's before/after now that we've applied moderation
*/
metadata.skippedIndentIndices = new Set([
...metadata.parentMetadata.skippedIndentIndices,
])
if (prevItem?.type === 'threadPost')
metadata.prevItemDepth = prevItem?.depth
if (nextItem?.type === 'threadPost')
metadata.nextItemDepth = nextItem?.depth
/*
* We can now officially calculate `isLastSibling` based on the actual data that
* we've seen.
* We can now officially calculate `isLastSibling` and `isLastChild`
* based on the actual data that we've seen.
*/
metadata.isLastSibling =
metadata.repliesIndex ===
metadata.parentMetadata.repliesSeenCount - 1
metadata.isLastChild =
metadata.nextItemDepth === undefined ||
metadata.nextItemDepth <= metadata.depth
/*
* If this is the last sibling, it's implicitly part of the last
@@ -322,6 +370,13 @@ export function traverse(
metadata.parentMetadata.upcomingParentReadMore
}
/*
* Copy in the parent's skipped indents
*/
metadata.skippedIndentIndices = new Set([
...metadata.parentMetadata.skippedIndentIndices,
])
/**
* If this is the last sibling, and the parent has no unhydrated
* replies, then we know we can skip an indent line.
@@ -379,40 +434,6 @@ export function traverse(
}
}
if (hidden.length) {
if (showHidden) {
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,
})
}
}
return items
}
@@ -463,5 +484,6 @@ export function getModerationState(moderation: ModerationDecision) {
return {
blurred,
muted,
modui,
}
}
+12 -2
View File
@@ -150,11 +150,21 @@ export type TraversalMetadata = {
*/
repliesUnhydrated: 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
* The number of replies that have been seen so far in the traversal.
* Excludes replies that are moderated in some way, since those are not
* "seen" on first load. Use `repliesIndexCount` for the total number of
* replies that were hydrated in the response.
*
* After traverssal, we can use this to calculate if we actually got all the
* replies we expected, or if some were blocked, etc.
*/
repliesSeenCount: number
/**
* The total number of replies to this post hydrated in this response. Used
* for populating the `repliesIndex` of the post by referencing this value on
* the parent.
*/
repliesIndexCount: number
/**
* The index-0-based index of this reply in the parent post's replies.
*/
+8 -8
View File
@@ -59,12 +59,9 @@ export function getTraversalMetadata({
const metadata = {
depth: item.depth,
/*
* 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.
* Unknown until after traversal
*/
isLastChild: nextItem?.depth === undefined || nextItem?.depth <= item.depth,
isLastChild: false,
/*
* Unknown until after traversal
*/
@@ -89,6 +86,7 @@ export function getTraversalMetadata({
repliesCount,
repliesUnhydrated,
repliesSeenCount: 0,
repliesIndexCount: 0,
repliesIndex: 0,
skippedIndentIndices: new Set<number>(),
}
@@ -138,10 +136,12 @@ export function getThreadPostUI({
showChildReplyLine: depth < 0 || isReplyAndHasReplies,
indent: depth,
/*
* If there are no slices below this one, or the next slice is less
* indented than the computed indent for this post.
* 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, //nextItemDepth === undefined || nextItemDepth < depth,
isLastChild,
skippedIndentIndices,
precedesChildReadMore: precedesChildReadMore ?? false,
}