Handle read more cases in tree view
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
AppBskyUnspeccedGetPostThreadV2,
|
||||
AtUri,
|
||||
type ModerationDecision,
|
||||
type ModerationOpts,
|
||||
} from '@atproto/api'
|
||||
@@ -21,8 +20,7 @@ export function flatten(
|
||||
},
|
||||
) {
|
||||
const flattened: Slice[] = sorted.items
|
||||
|
||||
const unhydratedReplyIntervals = []
|
||||
const parentsWithUnhydratedReplies = []
|
||||
|
||||
for (let i = 0; i < flattened.length; 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) {
|
||||
unhydratedReplyIntervals.push({
|
||||
item,
|
||||
replyCount: item.value.moreReplies,
|
||||
})
|
||||
if (maybeParent) {
|
||||
// next item is a sibling or an aunt/uncle
|
||||
if (item.depth <= maybeParent.depth) {
|
||||
flattened.splice(
|
||||
i,
|
||||
0,
|
||||
views.readMore({
|
||||
item,
|
||||
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) {
|
||||
// TODO test if we need this
|
||||
// prev.replyCount = Math.max(0, prev.replyCount - 1)
|
||||
}
|
||||
|
||||
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()
|
||||
if (item.value.moreReplies > 0) {
|
||||
// last iteration might have its own read more
|
||||
if (i === flattened.length - 1) {
|
||||
flattened.push(
|
||||
views.readMore({
|
||||
item,
|
||||
parent: item,
|
||||
}),
|
||||
)
|
||||
break
|
||||
} else {
|
||||
parentsWithUnhydratedReplies.push(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyFeedPost,
|
||||
type AppBskyUnspeccedGetPostThreadV2,
|
||||
AtUri,
|
||||
moderatePost,
|
||||
type ModerationOpts,
|
||||
} 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(
|
||||
post: AppBskyFeedDefs.PostView,
|
||||
): $Typed<
|
||||
|
||||
@@ -313,7 +313,7 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
t.atoms.text_contrast_medium,
|
||||
(hovered || pressed) && a.underline,
|
||||
]}>
|
||||
Read {item.replyCount} more replies
|
||||
Read {item.replyCount} more replies ({item.key})
|
||||
</Text>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user