mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {View} from 'react-native'
2import {ModerationCause} from '@atproto/api'
3import {msg, Trans} from '@lingui/macro'
4import {useLingui} from '@lingui/react'
5
6import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
7import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
8import {makeProfileLink} from '#/lib/routes/links'
9import {listUriToHref} from '#/lib/strings/url-helpers'
10import {isNative} from '#/platform/detection'
11import {useSession} from '#/state/session'
12import {atoms as a, useGutters, useTheme} from '#/alf'
13import * as Dialog from '#/components/Dialog'
14import {InlineLinkText} from '#/components/Link'
15import {AppModerationCause} from '#/components/Pills'
16import {Text} from '#/components/Typography'
17
18export {useDialogControl as useModerationDetailsDialogControl} from '#/components/Dialog'
19
20export interface ModerationDetailsDialogProps {
21 control: Dialog.DialogOuterProps['control']
22 modcause?: ModerationCause | AppModerationCause
23}
24
25export function ModerationDetailsDialog(props: ModerationDetailsDialogProps) {
26 return (
27 <Dialog.Outer control={props.control}>
28 <Dialog.Handle />
29 <ModerationDetailsDialogInner {...props} />
30 </Dialog.Outer>
31 )
32}
33
34function ModerationDetailsDialogInner({
35 modcause,
36 control,
37}: ModerationDetailsDialogProps & {
38 control: Dialog.DialogOuterProps['control']
39}) {
40 const t = useTheme()
41 const xGutters = useGutters([0, 'base'])
42 const {_} = useLingui()
43 const desc = useModerationCauseDescription(modcause)
44 const {currentAccount} = useSession()
45 const timeDiff = useGetTimeAgo({future: true})
46
47 let name
48 let description
49 if (!modcause) {
50 name = _(msg`Content Warning`)
51 description = _(
52 msg`Moderator has chosen to set a general warning on the content.`,
53 )
54 } else if (modcause.type === 'blocking') {
55 if (modcause.source.type === 'list') {
56 const list = modcause.source.list
57 name = _(msg`User Blocked by List`)
58 description = (
59 <Trans>
60 This user is included in the{' '}
61 <InlineLinkText
62 label={list.name}
63 to={listUriToHref(list.uri)}
64 style={[a.text_sm]}>
65 {list.name}
66 </InlineLinkText>{' '}
67 list which you have blocked.
68 </Trans>
69 )
70 } else {
71 name = _(msg`User Blocked`)
72 description = _(
73 msg`You have blocked this user. You cannot view their content.`,
74 )
75 }
76 } else if (modcause.type === 'blocked-by') {
77 name = _(msg`User Blocks You`)
78 description = _(
79 msg`This user has blocked you. You cannot view their content.`,
80 )
81 } else if (modcause.type === 'block-other') {
82 name = _(msg`Content Not Available`)
83 description = _(
84 msg`This content is not available because one of the users involved has blocked the other.`,
85 )
86 } else if (modcause.type === 'muted') {
87 if (modcause.source.type === 'list') {
88 const list = modcause.source.list
89 name = _(msg`Account Muted by List`)
90 description = (
91 <Trans>
92 This user is included in the{' '}
93 <InlineLinkText
94 label={list.name}
95 to={listUriToHref(list.uri)}
96 style={[a.text_sm]}>
97 {list.name}
98 </InlineLinkText>{' '}
99 list which you have muted.
100 </Trans>
101 )
102 } else {
103 name = _(msg`Account Muted`)
104 description = _(msg`You have muted this account.`)
105 }
106 } else if (modcause.type === 'mute-word') {
107 name = _(msg`Post Hidden by Muted Word`)
108 description = _(msg`You've chosen to hide a word or tag within this post.`)
109 } else if (modcause.type === 'hidden') {
110 name = _(msg`Post Hidden by You`)
111 description = _(msg`You have hidden this post.`)
112 } else if (modcause.type === 'reply-hidden') {
113 const isYou = currentAccount?.did === modcause.source.did
114 name = isYou
115 ? _(msg`Reply Hidden by You`)
116 : _(msg`Reply Hidden by Thread Author`)
117 description = isYou
118 ? _(msg`You hid this reply.`)
119 : _(msg`The author of this thread has hidden this reply.`)
120 } else if (modcause.type === 'label') {
121 name = desc.name
122 description = (
123 <Text emoji style={[t.atoms.text, a.text_md, a.leading_snug]}>
124 {desc.description}
125 </Text>
126 )
127 } else {
128 // should never happen
129 name = ''
130 description = ''
131 }
132
133 const sourceName =
134 desc.source || desc.sourceDisplayName || _(msg`an unknown labeler`)
135
136 return (
137 <Dialog.ScrollableInner
138 label={_(msg`Moderation details`)}
139 contentContainerStyle={{
140 paddingLeft: 0,
141 paddingRight: 0,
142 paddingBottom: 0,
143 }}>
144 <View style={[xGutters, a.pb_lg]}>
145 <Text emoji style={[t.atoms.text, a.text_2xl, a.font_heavy, a.mb_sm]}>
146 {name}
147 </Text>
148 <Text style={[t.atoms.text, a.text_sm, a.leading_snug]}>
149 {description}
150 </Text>
151 </View>
152
153 {modcause?.type === 'label' && (
154 <View
155 style={[
156 xGutters,
157 a.py_md,
158 a.border_t,
159 !isNative && t.atoms.bg_contrast_25,
160 t.atoms.border_contrast_low,
161 {
162 borderBottomLeftRadius: a.rounded_md.borderRadius,
163 borderBottomRightRadius: a.rounded_md.borderRadius,
164 },
165 ]}>
166 {modcause.source.type === 'user' ? (
167 <Text style={[t.atoms.text, a.text_md, a.leading_snug]}>
168 <Trans>This label was applied by the author.</Trans>
169 </Text>
170 ) : (
171 <>
172 <View
173 style={[
174 a.flex_row,
175 a.justify_between,
176 a.gap_xl,
177 {paddingBottom: 1},
178 ]}>
179 <Text
180 style={[
181 a.flex_1,
182 a.leading_snug,
183 t.atoms.text_contrast_medium,
184 ]}
185 numberOfLines={1}>
186 <Trans>
187 Source:{' '}
188 <InlineLinkText
189 label={sourceName}
190 to={makeProfileLink({
191 did: modcause.label.src,
192 handle: '',
193 })}
194 onPress={() => control.close()}>
195 {sourceName}
196 </InlineLinkText>
197 </Trans>
198 </Text>
199 {modcause.label.exp && (
200 <View>
201 <Text
202 style={[
203 a.leading_snug,
204 a.text_sm,
205 a.italic,
206 t.atoms.text_contrast_medium,
207 ]}>
208 <Trans>
209 Expires in {timeDiff(Date.now(), modcause.label.exp)}
210 </Trans>
211 </Text>
212 </View>
213 )}
214 </View>
215 </>
216 )}
217 </View>
218 )}
219
220 {isNative && <View style={{height: 40}} />}
221
222 <Dialog.Close />
223 </Dialog.ScrollableInner>
224 )
225}