mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React from 'react'
2import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
3import {AtUri, AppBskyGraphDefs, RichText} from '@atproto/api'
4import {Link} from '../util/Link'
5import {Text} from '../util/text/Text'
6import {RichText as RichTextCom} from '#/components/RichText'
7import {UserAvatar} from '../util/UserAvatar'
8import {s} from 'lib/styles'
9import {usePalette} from 'lib/hooks/usePalette'
10import {useSession} from '#/state/session'
11import {sanitizeDisplayName} from 'lib/strings/display-names'
12import {sanitizeHandle} from 'lib/strings/handles'
13import {makeProfileLink} from 'lib/routes/links'
14import {Trans} from '@lingui/macro'
15import {atoms as a} from '#/alf'
16
17export const ListCard = ({
18 testID,
19 list,
20 noBg,
21 noBorder,
22 renderButton,
23 style,
24}: {
25 testID?: string
26 list: AppBskyGraphDefs.ListView
27 noBg?: boolean
28 noBorder?: boolean
29 renderButton?: () => JSX.Element
30 style?: StyleProp<ViewStyle>
31}) => {
32 const pal = usePalette('default')
33 const {currentAccount} = useSession()
34
35 const rkey = React.useMemo(() => {
36 try {
37 const urip = new AtUri(list.uri)
38 return urip.rkey
39 } catch {
40 return ''
41 }
42 }, [list])
43
44 const descriptionRichText = React.useMemo(() => {
45 if (list.description) {
46 return new RichText({
47 text: list.description,
48 facets: list.descriptionFacets,
49 })
50 }
51 return undefined
52 }, [list])
53
54 return (
55 <Link
56 testID={testID}
57 style={[
58 styles.outer,
59 pal.border,
60 noBorder && styles.outerNoBorder,
61 !noBg && pal.view,
62 style,
63 ]}
64 href={makeProfileLink(list.creator, 'lists', rkey)}
65 title={list.name}
66 asAnchor
67 anchorNoUnderline>
68 <View style={styles.layout}>
69 <View style={styles.layoutAvi}>
70 <UserAvatar type="list" size={40} avatar={list.avatar} />
71 </View>
72 <View style={styles.layoutContent}>
73 <Text
74 type="lg"
75 style={[s.bold, pal.text]}
76 numberOfLines={1}
77 lineHeight={1.2}>
78 {sanitizeDisplayName(list.name)}
79 </Text>
80 <Text type="md" style={[pal.textLight]} numberOfLines={1}>
81 {list.purpose === 'app.bsky.graph.defs#curatelist' &&
82 (list.creator.did === currentAccount?.did ? (
83 <Trans>User list by you</Trans>
84 ) : (
85 <Trans>
86 User list by {sanitizeHandle(list.creator.handle, '@')}
87 </Trans>
88 ))}
89 {list.purpose === 'app.bsky.graph.defs#modlist' &&
90 (list.creator.did === currentAccount?.did ? (
91 <Trans>Moderation list by you</Trans>
92 ) : (
93 <Trans>
94 Moderation list by {sanitizeHandle(list.creator.handle, '@')}
95 </Trans>
96 ))}
97 </Text>
98 <View style={s.flexRow}>
99 {list.viewer?.muted ? (
100 <View style={[s.mt5, pal.btn, styles.pill]}>
101 <Text type="xs" style={pal.text}>
102 <Trans>Muted</Trans>
103 </Text>
104 </View>
105 ) : null}
106
107 {list.viewer?.blocked ? (
108 <View style={[s.mt5, pal.btn, styles.pill]}>
109 <Text type="xs" style={pal.text}>
110 <Trans>Blocked</Trans>
111 </Text>
112 </View>
113 ) : null}
114 </View>
115 </View>
116 {renderButton ? (
117 <View style={styles.layoutButton}>{renderButton()}</View>
118 ) : undefined}
119 </View>
120 {descriptionRichText ? (
121 <View style={styles.details}>
122 <RichTextCom
123 style={[a.flex_1]}
124 numberOfLines={20}
125 value={descriptionRichText}
126 />
127 </View>
128 ) : undefined}
129 </Link>
130 )
131}
132
133const styles = StyleSheet.create({
134 outer: {
135 borderTopWidth: 1,
136 paddingHorizontal: 6,
137 },
138 outerNoBorder: {
139 borderTopWidth: 0,
140 },
141 layout: {
142 flexDirection: 'row',
143 alignItems: 'center',
144 },
145 layoutAvi: {
146 width: 54,
147 paddingLeft: 4,
148 paddingTop: 8,
149 paddingBottom: 10,
150 },
151 avi: {
152 width: 40,
153 height: 40,
154 borderRadius: 20,
155 resizeMode: 'cover',
156 },
157 layoutContent: {
158 flex: 1,
159 paddingRight: 10,
160 paddingTop: 10,
161 paddingBottom: 10,
162 },
163 layoutButton: {
164 paddingRight: 10,
165 },
166 details: {
167 paddingLeft: 54,
168 paddingRight: 10,
169 paddingBottom: 10,
170 },
171 pill: {
172 borderRadius: 4,
173 paddingHorizontal: 6,
174 paddingVertical: 2,
175 },
176 btn: {
177 paddingVertical: 7,
178 borderRadius: 50,
179 marginLeft: 6,
180 paddingHorizontal: 14,
181 },
182})