Handle read more cases in tree view

This commit is contained in:
Eric Bailey
2025-05-25 14:54:56 -05:00
parent 4c4274ada3
commit 2497099d81
3 changed files with 59 additions and 26 deletions
+38 -23
View File
@@ -1,6 +1,5 @@
import { import {
AppBskyUnspeccedGetPostThreadV2, AppBskyUnspeccedGetPostThreadV2,
AtUri,
type ModerationDecision, type ModerationDecision,
type ModerationOpts, type ModerationOpts,
} from '@atproto/api' } from '@atproto/api'
@@ -21,8 +20,7 @@ export function flatten(
}, },
) { ) {
const flattened: Slice[] = sorted.items const flattened: Slice[] = sorted.items
const parentsWithUnhydratedReplies = []
const unhydratedReplyIntervals = []
for (let i = 0; i < flattened.length; i++) { for (let i = 0; i < flattened.length; i++) {
const item = flattened[i] const item = flattened[i]
@@ -40,33 +38,50 @@ export function flatten(
}) })
} }
const prev = unhydratedReplyIntervals[unhydratedReplyIntervals.length - 1] const maybeParent =
parentsWithUnhydratedReplies[parentsWithUnhydratedReplies.length - 1]
if (item.value.moreReplies > 0) { if (maybeParent) {
unhydratedReplyIntervals.push({ // next item is a sibling or an aunt/uncle
if (item.depth <= maybeParent.depth) {
flattened.splice(
i,
0,
views.readMore({
item, item,
replyCount: item.value.moreReplies, parent: maybeParent,
}) }),
)
parentsWithUnhydratedReplies.pop()
i++ // skip over the read more item
} else if (i === flattened.length - 1) {
// last iteration might have a parent
flattened.push(
views.readMore({
item,
parent: maybeParent,
}),
)
break
}
} }
/* /*
* If direct child of previous item with `hasMoreReplies`, subtract * Lastly, insert next read more if necessary
*/ */
if (prev && item.depth === prev.item.depth + 1) { if (item.value.moreReplies > 0) {
// TODO test if we need this // last iteration might have its own read more
// prev.replyCount = Math.max(0, prev.replyCount - 1) if (i === flattened.length - 1) {
flattened.push(
views.readMore({
item,
parent: item,
}),
)
break
} else {
parentsWithUnhydratedReplies.push(item)
} }
if (prev && item.depth <= prev.item.depth) {
flattened.splice(i, 0, {
type: 'readMore',
key: `readMore:${prev.item.uri}`,
indent: prev.item.depth + (item.depth < prev.item.depth ? -1 : 0),
replyCount: prev.replyCount,
nextAnchor: prev.item,
nextAnchorUri: new AtUri(prev.item.uri),
})
unhydratedReplyIntervals.pop()
} }
} }
} }
+18
View File
@@ -3,6 +3,7 @@ import {
type AppBskyFeedDefs, type AppBskyFeedDefs,
type AppBskyFeedPost, type AppBskyFeedPost,
type AppBskyUnspeccedGetPostThreadV2, type AppBskyUnspeccedGetPostThreadV2,
AtUri,
moderatePost, moderatePost,
type ModerationOpts, type ModerationOpts,
} from '@atproto/api' } from '@atproto/api'
@@ -99,6 +100,23 @@ export function threadPost({
} }
} }
export function readMore({
item,
parent,
}: {
item: Extract<Slice, {type: 'threadPost'}>
parent: Extract<Slice, {type: 'threadPost'}>
}) {
return {
type: 'readMore' as const,
key: `readMore:${parent.uri}`,
indent: parent.depth + (item.depth < parent.depth ? -1 : 0),
replyCount: parent.value.moreReplies,
nextAnchor: parent,
nextAnchorUri: new AtUri(parent.uri),
}
}
export function postViewToThreadPlaceholder( export function postViewToThreadPlaceholder(
post: AppBskyFeedDefs.PostView, post: AppBskyFeedDefs.PostView,
): $Typed< ): $Typed<
+1 -1
View File
@@ -313,7 +313,7 @@ export function Inner({uri}: {uri: string | undefined}) {
t.atoms.text_contrast_medium, t.atoms.text_contrast_medium,
(hovered || pressed) && a.underline, (hovered || pressed) && a.underline,
]}> ]}>
Read {item.replyCount} more replies Read {item.replyCount} more replies ({item.key})
</Text> </Text>
</> </>
) )