Add moreParents handling
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2Zm0 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-.63 3.225a1 1 0 0 1 1.337.068l3 3 .068.076a1 1 0 0 1-1.406 1.406l-.076-.068L13 10.414V16a1 1 0 1 1-2 0v-5.586l-1.293 1.293a1 1 0 1 1-1.414-1.414l3-3 .076-.068Z"/></svg>
|
||||
|
After Width: | Height: | Size: 371 B |
@@ -0,0 +1,5 @@
|
||||
import {createSinglePathSVG} from './TEMPLATE'
|
||||
|
||||
export const ArrowTopCircle_Stroke2_Corner0_Rounded = createSinglePathSVG({
|
||||
path: 'M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2Zm0 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-.63 3.225a1 1 0 0 1 1.337.068l3 3 .068.076a1 1 0 0 1-1.406 1.406l-.076-.068L13 10.414V16a1 1 0 1 1-2 0v-5.586l-1.293 1.293a1 1 0 1 1-1.414-1.414l3-3 .076-.068Z',
|
||||
})
|
||||
@@ -0,0 +1,90 @@
|
||||
import {memo} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {type ThreadItem} from '#/state/queries/usePostThread'
|
||||
import {
|
||||
LINEAR_AVI_WIDTH,
|
||||
OUTER_SPACE,
|
||||
REPLY_LINE_WIDTH,
|
||||
} from '#/screens/PostThread/const'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {ArrowTopCircle_Stroke2_Corner0_Rounded as UpIcon} from '#/components/icons/ArrowTopCircle'
|
||||
import {Link} from '#/components/Link'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
export const ThreadItemReadMoreUp = memo(function ThreadItemReadMoreUp({
|
||||
item,
|
||||
}: {
|
||||
item: Extract<ThreadItem, {type: 'readMoreUp'}>
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
|
||||
return (
|
||||
<Link
|
||||
label={_(msg`Continue thread`)}
|
||||
to={item.href}
|
||||
style={[
|
||||
a.gap_xs,
|
||||
{
|
||||
paddingTop: OUTER_SPACE,
|
||||
paddingHorizontal: OUTER_SPACE,
|
||||
},
|
||||
]}>
|
||||
{({hovered, pressed}) => {
|
||||
const interacted = hovered || pressed
|
||||
return (
|
||||
<View>
|
||||
<View style={[a.flex_row, a.align_center, a.gap_md]}>
|
||||
<View
|
||||
style={[
|
||||
a.align_center,
|
||||
{
|
||||
width: LINEAR_AVI_WIDTH,
|
||||
},
|
||||
]}>
|
||||
<UpIcon
|
||||
fill="currentColor"
|
||||
width={24}
|
||||
style={[
|
||||
t.atoms.text_contrast_low,
|
||||
a.transition_all,
|
||||
interacted && [t.atoms.text_contrast_high],
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
<Text
|
||||
style={[
|
||||
a.text_sm,
|
||||
t.atoms.text_contrast_medium,
|
||||
interacted && [a.underline],
|
||||
]}>
|
||||
<Trans>Continue thread...</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
a.align_center,
|
||||
{
|
||||
width: LINEAR_AVI_WIDTH,
|
||||
},
|
||||
]}>
|
||||
<View
|
||||
style={[
|
||||
a.mt_xs,
|
||||
{
|
||||
height: OUTER_SPACE / 2,
|
||||
width: REPLY_LINE_WIDTH,
|
||||
backgroundColor: t.atoms.border_contrast_low.borderColor,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}}
|
||||
</Link>
|
||||
)
|
||||
})
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
} from '#/screens/PostThread/components/ThreadItemPost'
|
||||
import {ThreadItemPostTombstone} from '#/screens/PostThread/components/ThreadItemPostTombstone'
|
||||
import {ThreadItemReadMore} from '#/screens/PostThread/components/ThreadItemReadMore'
|
||||
import {ThreadItemReadMoreUp} from '#/screens/PostThread/components/ThreadItemReadMoreUp'
|
||||
import {ThreadItemTreePost} from '#/screens/PostThread/components/ThreadItemTreePost'
|
||||
import {useBreakpoints, web} from '#/alf'
|
||||
import * as Layout from '#/components/Layout'
|
||||
@@ -191,8 +192,8 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// ignore parents
|
||||
if (hasDepth && item.depth < 0) continue
|
||||
// ignore any parent items
|
||||
if (item.type === 'readMoreUp' || (hasDepth && item.depth < 0)) continue
|
||||
// can exit early if we've reached the max children count
|
||||
if (childrenCount > maxChildrenCount) break
|
||||
|
||||
@@ -271,6 +272,8 @@ export function Inner({uri}: {uri: string | undefined}) {
|
||||
view={thread.state.view === 'tree' ? 'tree' : 'linear'}
|
||||
/>
|
||||
)
|
||||
} else if (item.type === 'readMoreUp') {
|
||||
return <ThreadItemReadMoreUp item={item} />
|
||||
} else if (item.type === 'threadPostBlocked') {
|
||||
return <ThreadItemPostTombstone type="blocked" />
|
||||
} else if (item.type === 'threadPostNotFound') {
|
||||
|
||||
@@ -353,6 +353,16 @@ export function sortAndAnnotateThreadItems(
|
||||
i++
|
||||
}
|
||||
|
||||
/**
|
||||
* Only occurs for the first item in the thread, which may have
|
||||
* additional parents not included in this request.
|
||||
*/
|
||||
if (item.value.moreParents) {
|
||||
metadata.followsReadMoreUp = true
|
||||
subset.splice(i, 0, views.readMoreUp(metadata))
|
||||
i++
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the final UI state for the thread item.
|
||||
*/
|
||||
@@ -362,6 +372,8 @@ export function sortAndAnnotateThreadItems(
|
||||
}
|
||||
}
|
||||
|
||||
console.log(threadItems)
|
||||
|
||||
return {
|
||||
threadItems,
|
||||
hiddenThreadItems,
|
||||
|
||||
@@ -100,6 +100,11 @@ export type ThreadItem =
|
||||
moreReplies: number
|
||||
skippedIndentIndices: Set<number>
|
||||
}
|
||||
| {
|
||||
type: 'readMoreUp'
|
||||
key: string
|
||||
href: string
|
||||
}
|
||||
| {
|
||||
type: 'skeleton'
|
||||
key: string
|
||||
@@ -117,6 +122,11 @@ export type TraversalMetadata = {
|
||||
* calculated on the server.
|
||||
*/
|
||||
depth: number
|
||||
/**
|
||||
* Indicates if this item is a "read more" link preceding this post that
|
||||
* continues the thread upwards.
|
||||
*/
|
||||
followsReadMoreUp: boolean
|
||||
/**
|
||||
* Indicates if the post is the last reply beneath its parent post.
|
||||
*/
|
||||
|
||||
@@ -81,6 +81,10 @@ export function getTraversalMetadata({
|
||||
* Unknown until after traversal
|
||||
*/
|
||||
precedesChildReadMore: false,
|
||||
/*
|
||||
* Unknown until after traversal
|
||||
*/
|
||||
followsReadMoreUp: false,
|
||||
postData: {
|
||||
uri: item.uri,
|
||||
authorHandle: item.value.post.author.handle,
|
||||
@@ -124,6 +128,7 @@ export function getThreadPostUI({
|
||||
repliesSeenCount,
|
||||
repliesUnhydrated,
|
||||
precedesChildReadMore,
|
||||
followsReadMoreUp,
|
||||
}: TraversalMetadata): Extract<ThreadItem, {type: 'threadPost'}>['ui'] {
|
||||
// TODO might be able to simplify this
|
||||
const isReplyAndHasReplies =
|
||||
@@ -134,7 +139,8 @@ export function getThreadPostUI({
|
||||
return {
|
||||
isAnchor: depth === 0,
|
||||
showParentReplyLine:
|
||||
!!prevItemDepth && prevItemDepth !== 0 && prevItemDepth < depth,
|
||||
followsReadMoreUp ||
|
||||
(!!prevItemDepth && prevItemDepth !== 0 && prevItemDepth < depth),
|
||||
showChildReplyLine: depth < 0 || isReplyAndHasReplies,
|
||||
indent: depth,
|
||||
/*
|
||||
|
||||
@@ -124,6 +124,25 @@ export function readMore({
|
||||
}
|
||||
}
|
||||
|
||||
export function readMoreUp({
|
||||
postData,
|
||||
}: TraversalMetadata): Extract<ThreadItem, {type: 'readMoreUp'}> {
|
||||
const urip = new AtUri(postData.uri)
|
||||
const href = makeProfileLink(
|
||||
{
|
||||
did: urip.host,
|
||||
handle: postData.authorHandle,
|
||||
},
|
||||
'post',
|
||||
urip.rkey,
|
||||
)
|
||||
return {
|
||||
type: 'readMoreUp' as const,
|
||||
key: `readMoreUp:${postData.uri}`,
|
||||
href,
|
||||
}
|
||||
}
|
||||
|
||||
export function skeleton({
|
||||
key,
|
||||
item,
|
||||
|
||||
Reference in New Issue
Block a user