Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
at main 108 lines 3.1 kB view raw
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})