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'
|
} from '#/screens/PostThread/components/ThreadItemPost'
|
||||||
import {ThreadItemPostTombstone} from '#/screens/PostThread/components/ThreadItemPostTombstone'
|
import {ThreadItemPostTombstone} from '#/screens/PostThread/components/ThreadItemPostTombstone'
|
||||||
import {ThreadItemReadMore} from '#/screens/PostThread/components/ThreadItemReadMore'
|
import {ThreadItemReadMore} from '#/screens/PostThread/components/ThreadItemReadMore'
|
||||||
|
import {ThreadItemReadMoreUp} from '#/screens/PostThread/components/ThreadItemReadMoreUp'
|
||||||
import {ThreadItemTreePost} from '#/screens/PostThread/components/ThreadItemTreePost'
|
import {ThreadItemTreePost} from '#/screens/PostThread/components/ThreadItemTreePost'
|
||||||
import {useBreakpoints, web} from '#/alf'
|
import {useBreakpoints, web} from '#/alf'
|
||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
@@ -191,8 +192,8 @@ export function Inner({uri}: {uri: string | undefined}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ignore parents
|
// ignore any parent items
|
||||||
if (hasDepth && item.depth < 0) continue
|
if (item.type === 'readMoreUp' || (hasDepth && item.depth < 0)) continue
|
||||||
// can exit early if we've reached the max children count
|
// can exit early if we've reached the max children count
|
||||||
if (childrenCount > maxChildrenCount) break
|
if (childrenCount > maxChildrenCount) break
|
||||||
|
|
||||||
@@ -271,6 +272,8 @@ export function Inner({uri}: {uri: string | undefined}) {
|
|||||||
view={thread.state.view === 'tree' ? 'tree' : 'linear'}
|
view={thread.state.view === 'tree' ? 'tree' : 'linear'}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
} else if (item.type === 'readMoreUp') {
|
||||||
|
return <ThreadItemReadMoreUp item={item} />
|
||||||
} else if (item.type === 'threadPostBlocked') {
|
} else if (item.type === 'threadPostBlocked') {
|
||||||
return <ThreadItemPostTombstone type="blocked" />
|
return <ThreadItemPostTombstone type="blocked" />
|
||||||
} else if (item.type === 'threadPostNotFound') {
|
} else if (item.type === 'threadPostNotFound') {
|
||||||
|
|||||||
@@ -353,6 +353,16 @@ export function sortAndAnnotateThreadItems(
|
|||||||
i++
|
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.
|
* Calculate the final UI state for the thread item.
|
||||||
*/
|
*/
|
||||||
@@ -362,6 +372,8 @@ export function sortAndAnnotateThreadItems(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(threadItems)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
threadItems,
|
threadItems,
|
||||||
hiddenThreadItems,
|
hiddenThreadItems,
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ export type ThreadItem =
|
|||||||
moreReplies: number
|
moreReplies: number
|
||||||
skippedIndentIndices: Set<number>
|
skippedIndentIndices: Set<number>
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: 'readMoreUp'
|
||||||
|
key: string
|
||||||
|
href: string
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: 'skeleton'
|
type: 'skeleton'
|
||||||
key: string
|
key: string
|
||||||
@@ -117,6 +122,11 @@ export type TraversalMetadata = {
|
|||||||
* calculated on the server.
|
* calculated on the server.
|
||||||
*/
|
*/
|
||||||
depth: number
|
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.
|
* Indicates if the post is the last reply beneath its parent post.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -81,6 +81,10 @@ export function getTraversalMetadata({
|
|||||||
* Unknown until after traversal
|
* Unknown until after traversal
|
||||||
*/
|
*/
|
||||||
precedesChildReadMore: false,
|
precedesChildReadMore: false,
|
||||||
|
/*
|
||||||
|
* Unknown until after traversal
|
||||||
|
*/
|
||||||
|
followsReadMoreUp: false,
|
||||||
postData: {
|
postData: {
|
||||||
uri: item.uri,
|
uri: item.uri,
|
||||||
authorHandle: item.value.post.author.handle,
|
authorHandle: item.value.post.author.handle,
|
||||||
@@ -124,6 +128,7 @@ export function getThreadPostUI({
|
|||||||
repliesSeenCount,
|
repliesSeenCount,
|
||||||
repliesUnhydrated,
|
repliesUnhydrated,
|
||||||
precedesChildReadMore,
|
precedesChildReadMore,
|
||||||
|
followsReadMoreUp,
|
||||||
}: TraversalMetadata): Extract<ThreadItem, {type: 'threadPost'}>['ui'] {
|
}: TraversalMetadata): Extract<ThreadItem, {type: 'threadPost'}>['ui'] {
|
||||||
// TODO might be able to simplify this
|
// TODO might be able to simplify this
|
||||||
const isReplyAndHasReplies =
|
const isReplyAndHasReplies =
|
||||||
@@ -134,7 +139,8 @@ export function getThreadPostUI({
|
|||||||
return {
|
return {
|
||||||
isAnchor: depth === 0,
|
isAnchor: depth === 0,
|
||||||
showParentReplyLine:
|
showParentReplyLine:
|
||||||
!!prevItemDepth && prevItemDepth !== 0 && prevItemDepth < depth,
|
followsReadMoreUp ||
|
||||||
|
(!!prevItemDepth && prevItemDepth !== 0 && prevItemDepth < depth),
|
||||||
showChildReplyLine: depth < 0 || isReplyAndHasReplies,
|
showChildReplyLine: depth < 0 || isReplyAndHasReplies,
|
||||||
indent: depth,
|
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({
|
export function skeleton({
|
||||||
key,
|
key,
|
||||||
item,
|
item,
|
||||||
|
|||||||
Reference in New Issue
Block a user