Basically working read more
This commit is contained in:
@@ -38,49 +38,65 @@ export function flatten(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const maybeParent =
|
const deepestParent =
|
||||||
parentsWithUnhydratedReplies[parentsWithUnhydratedReplies.length - 1]
|
parentsWithUnhydratedReplies[parentsWithUnhydratedReplies.length - 1]
|
||||||
|
|
||||||
if (maybeParent) {
|
if (deepestParent) {
|
||||||
// next item is a sibling or an aunt/uncle
|
// next item is a sibling or an aunt/uncle
|
||||||
if (item.depth <= maybeParent.depth) {
|
if (item.depth <= deepestParent.depth) {
|
||||||
flattened.splice(
|
for (let pi = parentsWithUnhydratedReplies.length - 1; pi >= 0; pi--) {
|
||||||
i,
|
const parent = parentsWithUnhydratedReplies[pi]
|
||||||
0,
|
if (item.depth <= parent.depth) {
|
||||||
views.readMore({
|
flattened.splice(
|
||||||
item,
|
i + 1 + (pi - parentsWithUnhydratedReplies.length),
|
||||||
parent: maybeParent,
|
0,
|
||||||
}),
|
views.readMore({
|
||||||
)
|
item,
|
||||||
parentsWithUnhydratedReplies.pop()
|
parent: parent,
|
||||||
i++ // skip over the read more item
|
}),
|
||||||
} else if (i === flattened.length - 1) {
|
)
|
||||||
// last iteration might have a parent
|
parentsWithUnhydratedReplies.pop()
|
||||||
flattened.push(
|
i++
|
||||||
views.readMore({
|
} else {
|
||||||
item,
|
break
|
||||||
parent: maybeParent,
|
}
|
||||||
}),
|
}
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Lastly, insert next read more if necessary
|
|
||||||
*/
|
|
||||||
if (item.value.moreReplies > 0) {
|
if (item.value.moreReplies > 0) {
|
||||||
// last iteration might have its own read more
|
parentsWithUnhydratedReplies.push(item)
|
||||||
if (i === flattened.length - 1) {
|
}
|
||||||
flattened.push(
|
|
||||||
views.readMore({
|
const isLastIteration = i === flattened.length - 1
|
||||||
item,
|
|
||||||
parent: item,
|
if (isLastIteration) {
|
||||||
}),
|
const deepestParent =
|
||||||
)
|
parentsWithUnhydratedReplies[parentsWithUnhydratedReplies.length - 1]
|
||||||
break
|
|
||||||
} else {
|
i++
|
||||||
parentsWithUnhydratedReplies.push(item)
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export function threadPost({
|
|||||||
ui: {
|
ui: {
|
||||||
isAnchor: depth === 0,
|
isAnchor: depth === 0,
|
||||||
showParentReplyLine: !!oneUp && oneUp.depth !== 0 && oneUp.depth < depth,
|
showParentReplyLine: !!oneUp && oneUp.depth !== 0 && oneUp.depth < depth,
|
||||||
showChildReplyLine: !!oneDown && depth !== 0 && oneDown.depth > depth,
|
showChildReplyLine: (value.post.replyCount || 0) > 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {useCallback, useMemo, useRef, useState} from 'react'
|
import {useCallback, useMemo, useRef, useState} from 'react'
|
||||||
import {useWindowDimensions, View} from 'react-native'
|
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 {useLingui} from '@lingui/react'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
|
|
||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
HiddenReplyKind,
|
HiddenReplyKind,
|
||||||
type Slice,
|
type Slice,
|
||||||
usePostThread,
|
usePostThread,
|
||||||
|
PostThreadParams,
|
||||||
} from '#/state/queries/usePostThread'
|
} from '#/state/queries/usePostThread'
|
||||||
import {useSetMinimalShellMode} from '#/state/shell'
|
import {useSetMinimalShellMode} from '#/state/shell'
|
||||||
import {type OnPostSuccessData} from '#/state/shell/composer'
|
import {type OnPostSuccessData} from '#/state/shell/composer'
|
||||||
@@ -261,65 +262,7 @@ export function Inner({uri}: {uri: string | undefined}) {
|
|||||||
)
|
)
|
||||||
} else if (item.type === 'readMore') {
|
} else if (item.type === 'readMore') {
|
||||||
return (
|
return (
|
||||||
<View style={[a.flex_row, a.px_sm]}>
|
<ReadMore item={item} view={treeViewEnabled ? 'tree' : 'linear'} />
|
||||||
{Array.from(Array(item.indent - 1)).map((_, n: number) => (
|
|
||||||
<View
|
|
||||||
key={`${item.key}-padding-${n}`}
|
|
||||||
style={[
|
|
||||||
a.ml_sm,
|
|
||||||
t.atoms.border_contrast_low,
|
|
||||||
{
|
|
||||||
borderLeftWidth: 2,
|
|
||||||
paddingLeft: a.pl_sm.paddingLeft - 2, // minus border
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
<View style={[a.ml_sm]}>
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
t.atoms.border_contrast_low,
|
|
||||||
{
|
|
||||||
borderLeftWidth: 2,
|
|
||||||
borderBottomWidth: 2,
|
|
||||||
borderBottomLeftRadius: a.rounded_sm.borderRadius,
|
|
||||||
height: 12,
|
|
||||||
width: a.pl_sm.paddingLeft * 2,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<Link
|
|
||||||
label={_(msg`Read more replies`)}
|
|
||||||
to={makeProfileLink(
|
|
||||||
{
|
|
||||||
did: item.nextAnchorUri.host,
|
|
||||||
handle: item.nextAnchor.value.post.author.handle,
|
|
||||||
},
|
|
||||||
'post',
|
|
||||||
item.nextAnchorUri.rkey,
|
|
||||||
)}
|
|
||||||
style={[a.pt_2xs, a.pb_sm, a.gap_xs]}>
|
|
||||||
{({hovered, pressed}) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<CirclePlus
|
|
||||||
fill={t.atoms.text_contrast_high.color}
|
|
||||||
width={18}
|
|
||||||
/>
|
|
||||||
<Text
|
|
||||||
style={[
|
|
||||||
a.text_sm,
|
|
||||||
t.atoms.text_contrast_medium,
|
|
||||||
(hovered || pressed) && a.underline,
|
|
||||||
]}>
|
|
||||||
Read {item.replyCount} more replies ({item.key})
|
|
||||||
</Text>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</Link>
|
|
||||||
</View>
|
|
||||||
)
|
)
|
||||||
} else if (item.type === 'threadPostBlocked') {
|
} else if (item.type === 'threadPostBlocked') {
|
||||||
return (
|
return (
|
||||||
@@ -556,3 +499,96 @@ function ThreadMenu({
|
|||||||
const keyExtractor = (item: Slice) => {
|
const keyExtractor = (item: Slice) => {
|
||||||
return item.key
|
return item.key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ReadMore({
|
||||||
|
item,
|
||||||
|
view,
|
||||||
|
}: {
|
||||||
|
item: Extract<Slice, {type: 'readMore'}>
|
||||||
|
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) => (
|
||||||
|
<View
|
||||||
|
key={`${item.key}-padding-${n}`}
|
||||||
|
style={[
|
||||||
|
a.ml_sm,
|
||||||
|
t.atoms.border_contrast_low,
|
||||||
|
{
|
||||||
|
borderLeftWidth: 2,
|
||||||
|
paddingLeft: a.pl_sm.paddingLeft - 2, // minus border
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
) : indentCount > 0 ? (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
// avi width minus border, divided by 2
|
||||||
|
{width: (42 - 2) / 2}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
) : null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[a.flex_row, a.px_sm]}>
|
||||||
|
{treeIndents}
|
||||||
|
<View style={[a.ml_sm]}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
t.atoms.border_contrast_low,
|
||||||
|
{
|
||||||
|
borderLeftWidth: 2,
|
||||||
|
borderBottomWidth: 2,
|
||||||
|
borderBottomLeftRadius: a.rounded_sm.borderRadius,
|
||||||
|
height: 12,
|
||||||
|
width: isTreeView ? a.pl_sm.paddingLeft * 2 : (42 / 2 + 10),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Link
|
||||||
|
label={_(msg`Read more replies`)}
|
||||||
|
to={makeProfileLink(
|
||||||
|
{
|
||||||
|
did: item.nextAnchorUri.host,
|
||||||
|
handle: item.nextAnchor.value.post.author.handle,
|
||||||
|
},
|
||||||
|
'post',
|
||||||
|
item.nextAnchorUri.rkey,
|
||||||
|
)}
|
||||||
|
style={[a.pt_2xs, a.pb_sm, a.gap_xs]}>
|
||||||
|
{({hovered, pressed}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<CirclePlus
|
||||||
|
fill={t.atoms.text_contrast_high.color}
|
||||||
|
width={18}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
a.text_sm,
|
||||||
|
t.atoms.text_contrast_medium,
|
||||||
|
(hovered || pressed) && a.underline,
|
||||||
|
]}>
|
||||||
|
<Trans>
|
||||||
|
Read {item.replyCount} more{' '}
|
||||||
|
<Plural
|
||||||
|
one="reply"
|
||||||
|
other="replies"
|
||||||
|
value={item.replyCount}
|
||||||
|
/>
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</Link>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user