diff --git a/src/state/queries/usePostThread/traversal.ts b/src/state/queries/usePostThread/traversal.ts index f89bfc3c85..027ca06d8a 100644 --- a/src/state/queries/usePostThread/traversal.ts +++ b/src/state/queries/usePostThread/traversal.ts @@ -38,49 +38,65 @@ export function flatten( }) } - const maybeParent = + const deepestParent = parentsWithUnhydratedReplies[parentsWithUnhydratedReplies.length - 1] - if (maybeParent) { + if (deepestParent) { // 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 (item.depth <= deepestParent.depth) { + for (let pi = parentsWithUnhydratedReplies.length - 1; pi >= 0; pi--) { + const parent = parentsWithUnhydratedReplies[pi] + if (item.depth <= parent.depth) { + flattened.splice( + i + 1 + (pi - parentsWithUnhydratedReplies.length), + 0, + views.readMore({ + item, + parent: parent, + }), + ) + parentsWithUnhydratedReplies.pop() + i++ + } else { + break + } + } } } - /* - * Lastly, insert next read more if necessary - */ 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) + parentsWithUnhydratedReplies.push(item) + } + + const isLastIteration = i === flattened.length - 1 + + if (isLastIteration) { + const deepestParent = + parentsWithUnhydratedReplies[parentsWithUnhydratedReplies.length - 1] + + i++ + + if (deepestParent) { + // next item is a sibling or an aunt/uncle + if (deepestParent.depth <= item.depth) { + for (let pi = parentsWithUnhydratedReplies.length - 1; pi >= 0; pi--) { + const parent = parentsWithUnhydratedReplies[pi] + if (parent.depth <= item.depth) { + flattened.splice( + i + 1 + (pi - parentsWithUnhydratedReplies.length), + 0, + views.readMore({ + item, + parent: parent, + }), + ) + parentsWithUnhydratedReplies.pop() + i++ + } else { + break + } + } + } } } } diff --git a/src/state/queries/usePostThread/views.ts b/src/state/queries/usePostThread/views.ts index fb7a030501..fcfaf4a643 100644 --- a/src/state/queries/usePostThread/views.ts +++ b/src/state/queries/usePostThread/views.ts @@ -95,7 +95,7 @@ export function threadPost({ ui: { isAnchor: depth === 0, showParentReplyLine: !!oneUp && oneUp.depth !== 0 && oneUp.depth < depth, - showChildReplyLine: !!oneDown && depth !== 0 && oneDown.depth > depth, + showChildReplyLine: (value.post.replyCount || 0) > 0, }, } } diff --git a/src/view/screens/PostThread.tsx b/src/view/screens/PostThread.tsx index 10b3ea872c..f3dccfbd03 100644 --- a/src/view/screens/PostThread.tsx +++ b/src/view/screens/PostThread.tsx @@ -1,6 +1,6 @@ import {useCallback, useMemo, useRef, useState} from 'react' import {useWindowDimensions, View} from 'react-native' -import {msg, Trans} from '@lingui/macro' +import {msg, Trans, Plural} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useFocusEffect} from '@react-navigation/native' @@ -22,6 +22,7 @@ import { HiddenReplyKind, type Slice, usePostThread, + PostThreadParams, } from '#/state/queries/usePostThread' import {useSetMinimalShellMode} from '#/state/shell' import {type OnPostSuccessData} from '#/state/shell/composer' @@ -261,65 +262,7 @@ export function Inner({uri}: {uri: string | undefined}) { ) } else if (item.type === 'readMore') { return ( - - {Array.from(Array(item.indent - 1)).map((_, n: number) => ( - - ))} - - - - - {({hovered, pressed}) => { - return ( - <> - - - Read {item.replyCount} more replies ({item.key}) - - - ) - }} - - + ) } else if (item.type === 'threadPostBlocked') { return ( @@ -556,3 +499,96 @@ function ThreadMenu({ const keyExtractor = (item: Slice) => { return item.key } + +function ReadMore({ + item, + view, +}: { + item: Extract + view: PostThreadParams['view'] +}) { + const t = useTheme() + const {_} = useLingui() + const isTreeView = view === 'tree' + const indentCount = item.indent - 1 + + const treeIndents = isTreeView ? ( + Array.from(Array(indentCount)).map((_, n: number) => ( + + )) + ) : indentCount > 0 ? ( + + ) : null + + return ( + + {treeIndents} + + + + + {({hovered, pressed}) => { + return ( + <> + + + + Read {item.replyCount} more{' '} + + + + + ) + }} + + + ) +}