mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React from 'react'
2import {View} from 'react-native'
3import {AppBskyLabelerDefs} from '@atproto/api'
4import {msg, Trans} from '@lingui/macro'
5import {useLingui} from '@lingui/react'
6
7import {ReportOption, useReportOptions} from '#/lib/moderation/useReportOptions'
8import {Link} from '#/components/Link'
9import {DMCA_LINK} from '#/components/ReportDialog/const'
10export {useDialogControl as useReportDialogControl} from '#/components/Dialog'
11
12import {atoms as a, useBreakpoints, useTheme} from '#/alf'
13import {
14 Button,
15 ButtonIcon,
16 ButtonText,
17 useButtonContext,
18} from '#/components/Button'
19import {Divider} from '#/components/Divider'
20import {
21 ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft,
22 ChevronRight_Stroke2_Corner0_Rounded as ChevronRight,
23} from '#/components/icons/Chevron'
24import {SquareArrowTopRight_Stroke2_Corner0_Rounded as SquareArrowTopRight} from '#/components/icons/SquareArrowTopRight'
25import {Text} from '#/components/Typography'
26import {ReportDialogProps} from './types'
27
28export function SelectReportOptionView({
29 ...props
30}: ReportDialogProps & {
31 labelers: AppBskyLabelerDefs.LabelerViewDetailed[]
32 onSelectReportOption: (reportOption: ReportOption) => void
33 goBack: () => void
34}) {
35 const t = useTheme()
36 const {_} = useLingui()
37 const {gtMobile} = useBreakpoints()
38 const allReportOptions = useReportOptions()
39 const reportOptions = allReportOptions[props.params.type]
40
41 const i18n = React.useMemo(() => {
42 let title = _(msg`Report this content`)
43 let description = _(msg`Why should this content be reviewed?`)
44
45 if (props.params.type === 'account') {
46 title = _(msg`Report this user`)
47 description = _(msg`Why should this user be reviewed?`)
48 } else if (props.params.type === 'post') {
49 title = _(msg`Report this post`)
50 description = _(msg`Why should this post be reviewed?`)
51 } else if (props.params.type === 'list') {
52 title = _(msg`Report this list`)
53 description = _(msg`Why should this list be reviewed?`)
54 } else if (props.params.type === 'feedgen') {
55 title = _(msg`Report this feed`)
56 description = _(msg`Why should this feed be reviewed?`)
57 }
58
59 return {
60 title,
61 description,
62 }
63 }, [_, props.params.type])
64
65 return (
66 <View style={[a.gap_lg]}>
67 {props.labelers?.length > 1 ? (
68 <Button
69 size="small"
70 variant="solid"
71 color="secondary"
72 shape="round"
73 label={_(msg`Go back to previous step`)}
74 onPress={props.goBack}>
75 <ButtonIcon icon={ChevronLeft} />
76 </Button>
77 ) : null}
78
79 <View style={[a.justify_center, gtMobile ? a.gap_sm : a.gap_xs]}>
80 <Text style={[a.text_2xl, a.font_bold]}>{i18n.title}</Text>
81 <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
82 {i18n.description}
83 </Text>
84 </View>
85
86 <Divider />
87
88 <View style={[a.gap_sm]}>
89 {reportOptions.map(reportOption => {
90 return (
91 <Button
92 key={reportOption.reason}
93 label={_(msg`Create report for ${reportOption.title}`)}
94 onPress={() => props.onSelectReportOption(reportOption)}>
95 <ReportOptionButton
96 title={reportOption.title}
97 description={reportOption.description}
98 />
99 </Button>
100 )
101 })}
102
103 {(props.params.type === 'post' || props.params.type === 'account') && (
104 <View
105 style={[
106 a.flex_row,
107 a.align_center,
108 a.justify_between,
109 a.gap_lg,
110 a.p_md,
111 a.pl_lg,
112 a.rounded_md,
113 t.atoms.bg_contrast_900,
114 ]}>
115 <Text
116 style={[
117 a.flex_1,
118 t.atoms.text_inverted,
119 a.italic,
120 a.leading_snug,
121 ]}>
122 <Trans>Need to report a copyright violation?</Trans>
123 </Text>
124 <Link
125 to={DMCA_LINK}
126 label={_(msg`View details for reporting a copyright violation`)}
127 size="small"
128 variant="solid"
129 color="secondary">
130 <ButtonText>
131 <Trans>View details</Trans>
132 </ButtonText>
133 <ButtonIcon position="right" icon={SquareArrowTopRight} />
134 </Link>
135 </View>
136 )}
137 </View>
138 </View>
139 )
140}
141
142function ReportOptionButton({
143 title,
144 description,
145}: {
146 title: string
147 description: string
148}) {
149 const t = useTheme()
150 const {hovered, pressed} = useButtonContext()
151 const interacted = hovered || pressed
152
153 return (
154 <View
155 style={[
156 a.w_full,
157 a.flex_row,
158 a.align_center,
159 a.justify_between,
160 a.p_md,
161 a.rounded_md,
162 {paddingRight: 70},
163 t.atoms.bg_contrast_25,
164 interacted && t.atoms.bg_contrast_50,
165 ]}>
166 <View style={[a.flex_1, a.gap_xs]}>
167 <Text style={[a.text_md, a.font_bold, t.atoms.text_contrast_medium]}>
168 {title}
169 </Text>
170 <Text style={[a.leading_tight, {maxWidth: 400}]}>{description}</Text>
171 </View>
172
173 <View
174 style={[
175 a.absolute,
176 a.inset_0,
177 a.justify_center,
178 a.pr_md,
179 {left: 'auto'},
180 ]}>
181 <ChevronRight size="md" fill={t.atoms.text_contrast_low.color} />
182 </View>
183 </View>
184 )
185}