Bluesky app fork with some witchin' additions 馃挮
witchsky.app
bluesky
fork
client
1import {memo} from 'react'
2import {View} from 'react-native'
3import {msg} from '@lingui/core/macro'
4import {useLingui} from '@lingui/react'
5import {Plural, Trans} from '@lingui/react/macro'
6
7import {
8 type PostThreadParams,
9 type ThreadItem,
10} from '#/state/queries/usePostThread'
11import {
12 LINEAR_AVI_WIDTH,
13 REPLY_LINE_WIDTH,
14 TREE_AVI_WIDTH,
15 TREE_INDENT,
16} from '#/screens/PostThread/const'
17import {atoms as a, useTheme} from '#/alf'
18import {CirclePlus_Stroke2_Corner0_Rounded as CirclePlus} from '#/components/icons/CirclePlus'
19import {Link} from '#/components/Link'
20import {Text} from '#/components/Typography'
21
22export const ThreadItemReadMore = memo(function ThreadItemReadMore({
23 item,
24 view,
25}: {
26 item: Extract<ThreadItem, {type: 'readMore'}>
27 view: PostThreadParams['view']
28}) {
29 const t = useTheme()
30 const {_} = useLingui()
31 const isTreeView = view === 'tree'
32 const indent = Math.max(0, item.depth - 1)
33
34 const spacers = isTreeView
35 ? Array.from(Array(indent)).map((_, n: number) => {
36 const isSkipped = item.skippedIndentIndices.has(n)
37 return (
38 <View
39 key={`${item.key}-padding-${n}`}
40 style={[
41 t.atoms.border_contrast_low,
42 {
43 borderRightWidth: isSkipped ? 0 : REPLY_LINE_WIDTH,
44 width: TREE_INDENT + TREE_AVI_WIDTH / 2,
45 left: 1,
46 },
47 ]}
48 />
49 )
50 })
51 : null
52
53 return (
54 <View style={[a.flex_row]}>
55 {spacers}
56 <View
57 style={[
58 t.atoms.border_contrast_low,
59 {
60 marginLeft: isTreeView
61 ? TREE_INDENT + TREE_AVI_WIDTH / 2 - 1
62 : (LINEAR_AVI_WIDTH - REPLY_LINE_WIDTH) / 2 + 16,
63 borderLeftWidth: 2,
64 borderBottomWidth: 2,
65 borderBottomLeftRadius: a.rounded_sm.borderRadius,
66 height: 18, // magic, Link below is 38px tall
67 width: isTreeView ? TREE_INDENT : LINEAR_AVI_WIDTH / 2 + 10,
68 },
69 ]}
70 />
71 <Link
72 label={_(msg`Read more replies`)}
73 to={item.href}
74 style={[a.pt_sm, a.pb_md, a.gap_xs]}>
75 {({hovered, pressed}) => {
76 const interacted = hovered || pressed
77 return (
78 <>
79 <CirclePlus
80 fill={
81 interacted
82 ? t.atoms.text_contrast_high.color
83 : t.atoms.text_contrast_low.color
84 }
85 width={18}
86 />
87 <Text
88 style={[
89 a.text_sm,
90 t.atoms.text_contrast_medium,
91 interacted && a.underline,
92 ]}>
93 <Trans>
94 Read{' '}
95 <Plural
96 one="# more reply"
97 other="# more replies"
98 value={item.moreReplies}
99 />
100 </Trans>
101 </Text>
102 </>
103 )
104 }}
105 </Link>
106 </View>
107 )
108})