import {memo, useMemo} from 'react' import {View} from 'react-native' import {RichText as RichTextAPI} from '@bsky/sdk/richtext' import {Trans} from '@lingui/react/macro' import {userStyle} from '#/lib/userstyles' import { POST_TOMBSTONE, type Shadow, usePostShadow, } from '#/state/cache/post-shadow' import {type OnPostSuccessData} from '#/state/shell/composer' import {ReaderSeam} from '#/screens/PostThread/components/ReaderSeam' import {ReaderBracket} from '#/screens/PostThread/components/ReaderSeamControls' import {ThreadItemReadMore} from '#/screens/PostThread/components/ThreadItemReadMore' import { OUTER_SPACE, READER_LINE_INDENT, READER_SEAM_HEIGHT, } from '#/screens/PostThread/const' import {type ReaderSegmentItem} from '#/screens/PostThread/reader' import {atoms as a, tokens, useTheme} from '#/alf' import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from '#/components/icons/Trash' import {GalleryBleed} from '#/components/images/Gallery' import {LabelsOnMyPost} from '#/components/moderation/LabelsOnMe' import {PostAlerts} from '#/components/moderation/PostAlerts' import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' import {TranslatedPost} from '#/components/Post/Translated' import {PostTags} from '#/components/PostTags' import {RichText} from '#/components/RichText' import {Text} from '#/components/Typography' import {type app} from '#/lexicons' export type ThreadItemReaderSegmentProps = { item: ReaderSegmentItem sort: string onToggleSeam: (uri: string) => void onPostSuccess?: (data: OnPostSuccessData) => void threadgateRecord?: app.bsky.feed.threadgate.Main } /** * A continuation post in reader view. Renders the post body beside the bracket * gutter, with no avatar or meta row, so consecutive segments read as one * continuous post, followed by its seam toggle inside the same bracket. */ export function ThreadItemReaderSegment({ item, sort, onToggleSeam, onPostSuccess, threadgateRecord, }: ThreadItemReaderSegmentProps) { const postShadow = usePostShadow(item.item.value.post) if (postShadow === POST_TOMBSTONE) { return } return ( ) } function ThreadItemReaderSegmentDeleted() { const t = useTheme() return ( Post has been deleted ) } const ThreadItemReaderSegmentInner = memo( function ThreadItemReaderSegmentInner({ item, postShadow, sort, onToggleSeam, onPostSuccess, threadgateRecord, }: ThreadItemReaderSegmentProps & { postShadow: Shadow }) { const post = postShadow const seam = item.seam const record = item.item.value.post.record const moderation = item.item.moderation const trailingReadMore = item.trailingReadMore const richText = useMemo( () => new RichTextAPI({ text: record.text, facets: record.facets, }), [record], ) return ( {seam.expanded && ( <> )} {richText?.text ? ( {/* Intentionally not line-limited: reader view is for uninterrupted reading */} ) : undefined} {post.embed && ( )} onToggleSeam(item.uri)} onPostSuccess={onPostSuccess} threadgateRecord={threadgateRecord} /> {trailingReadMore && ( <> )} {/* Bracket rendered last so it paints over the outline border. - Collapsed mid-chain: bottom cap at hairline - Collapsed thread end: hairline, accounting for the modest spacer - Expanded: close above the trailing spacer - Trailing read-more: close above the continuation button */} ) }, )