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} threadgateRecord={data?.threadgate?.record ?? undefined}
overrides={{ overrides={{
moderation: moderation:
shownHiddenReplyKinds.has(HiddenReplyKind.Muted) && shownHiddenReplyKinds.has(HiddenReplyKind.Hidden) &&
item.depth > 0, item.depth > 0,
}} }}
onPostSuccess={optimisticOnPostReply} onPostSuccess={optimisticOnPostReply}
+67 -45
View File
@@ -145,8 +145,9 @@ export function traverse(
/* /*
* Set this value before incrementing the parent's repliesSeenCount * Set this value before incrementing the parent's repliesSeenCount
*/ */
metadata!.repliesIndex = parentMetadata.repliesSeenCount metadata!.repliesIndex = parentMetadata.repliesIndexCount
parentMetadata.repliesSeenCount += 1 // Increment the parent's repliesIndexCount
parentMetadata.repliesIndexCount += 1
} }
const post = views.threadPost({ const post = views.threadPost({
@@ -165,6 +166,13 @@ export function traverse(
* Not moderated, probably need to insert it * Not moderated, probably need to insert it
*/ */
items.push(post) items.push(post)
/*
* Update seen reply count of parent
*/
if (parentMetadata) {
parentMetadata.repliesSeenCount += 1
}
} else { } else {
/* /*
* Moderated in some way, we're going to walk children * Moderated in some way, we're going to walk children
@@ -201,11 +209,11 @@ export function traverse(
storeTraversalMetadata(metadatas, childMetadata) storeTraversalMetadata(metadatas, childMetadata)
if (childParentMetadata) { if (childParentMetadata) {
/* /*
* Set this value before incrementing the parent's repliesSeenCount * Set this value before incrementing the parent's repliesIndexCount
*/ */
childMetadata!.repliesIndex = childMetadata!.repliesIndex =
childParentMetadata.repliesSeenCount childParentMetadata.repliesIndexCount
childParentMetadata.repliesSeenCount += 1 childParentMetadata.repliesIndexCount += 1
} }
const childPost = views.threadPost({ 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++) { for (let i = 0; i < items.length; i++) {
const item = items[i] const item = items[i]
const prevItem = items.at(i - 1)
const nextItem = items.at(i + 1)
if (item.type === 'threadPost') { if (item.type === 'threadPost') {
if ( if (
@@ -272,19 +316,23 @@ export function traverse(
if (metadata) { if (metadata) {
if (metadata.parentMetadata) { 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([ if (prevItem?.type === 'threadPost')
...metadata.parentMetadata.skippedIndentIndices, 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 can now officially calculate `isLastSibling` and `isLastChild`
* we've seen. * based on the actual data that we've seen.
*/ */
metadata.isLastSibling = metadata.isLastSibling =
metadata.repliesIndex === metadata.repliesIndex ===
metadata.parentMetadata.repliesSeenCount - 1 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 * If this is the last sibling, it's implicitly part of the last
@@ -322,6 +370,13 @@ export function traverse(
metadata.parentMetadata.upcomingParentReadMore 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 * If this is the last sibling, and the parent has no unhydrated
* replies, then we know we can skip an indent line. * 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 return items
} }
@@ -463,5 +484,6 @@ export function getModerationState(moderation: ModerationDecision) {
return { return {
blurred, blurred,
muted, muted,
modui,
} }
} }
+12 -2
View File
@@ -150,11 +150,21 @@ export type TraversalMetadata = {
*/ */
repliesUnhydrated: number repliesUnhydrated: number
/** /**
* The number of replies that have been seen so far in the traversal. After * The number of replies that have been seen so far in the traversal.
* traverssal, we can use this to calculate if we actually got all the * 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. * replies we expected, or if some were blocked, etc.
*/ */
repliesSeenCount: number 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. * 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 = { const metadata = {
depth: item.depth, depth: item.depth,
/* /*
* If there are no slices below this one, or the next slice has a depth <= * Unknown until after traversal
* 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, isLastChild: false,
/* /*
* Unknown until after traversal * Unknown until after traversal
*/ */
@@ -89,6 +86,7 @@ export function getTraversalMetadata({
repliesCount, repliesCount,
repliesUnhydrated, repliesUnhydrated,
repliesSeenCount: 0, repliesSeenCount: 0,
repliesIndexCount: 0,
repliesIndex: 0, repliesIndex: 0,
skippedIndentIndices: new Set<number>(), skippedIndentIndices: new Set<number>(),
} }
@@ -138,10 +136,12 @@ export function getThreadPostUI({
showChildReplyLine: depth < 0 || isReplyAndHasReplies, showChildReplyLine: depth < 0 || isReplyAndHasReplies,
indent: depth, indent: depth,
/* /*
* 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 has a depth <=
* indented than the computed indent for this post. * 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, skippedIndentIndices,
precedesChildReadMore: precedesChildReadMore ?? false, precedesChildReadMore: precedesChildReadMore ?? false,
} }