mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {memo, useCallback} from 'react'
2import {View} from 'react-native'
3import {msg, plural, Trans} from '@lingui/macro'
4import {useLingui} from '@lingui/react'
5
6import {useHaptics} from '#/lib/haptics'
7import {useRequireAuth} from '#/state/session'
8import {atoms as a, useTheme} from '#/alf'
9import {Button, ButtonText} from '#/components/Button'
10import * as Dialog from '#/components/Dialog'
11import {CloseQuote_Stroke2_Corner1_Rounded as Quote} from '#/components/icons/Quote'
12import {Repost_Stroke2_Corner3_Rounded as Repost} from '#/components/icons/Repost'
13import {useFormatPostStatCount} from '#/components/PostControls/util'
14import {Text} from '#/components/Typography'
15import {
16 PostControlButton,
17 PostControlButtonIcon,
18 PostControlButtonText,
19} from './PostControlButton'
20
21interface Props {
22 isReposted: boolean
23 repostCount?: number
24 onRepost: () => void
25 onQuote: () => void
26 big?: boolean
27 embeddingDisabled: boolean
28}
29
30let RepostButton = ({
31 isReposted,
32 repostCount,
33 onRepost,
34 onQuote,
35 big,
36 embeddingDisabled,
37}: Props): React.ReactNode => {
38 const t = useTheme()
39 const {_} = useLingui()
40 const requireAuth = useRequireAuth()
41 const dialogControl = Dialog.useDialogControl()
42 const formatPostStatCount = useFormatPostStatCount()
43
44 const onPress = () => requireAuth(() => dialogControl.open())
45
46 const onLongPress = () =>
47 requireAuth(() => {
48 if (embeddingDisabled) {
49 dialogControl.open()
50 } else {
51 onQuote()
52 }
53 })
54
55 return (
56 <>
57 <PostControlButton
58 testID="repostBtn"
59 active={isReposted}
60 activeColor={t.palette.positive_600}
61 big={big}
62 onPress={onPress}
63 onLongPress={onLongPress}
64 label={
65 isReposted
66 ? _(
67 msg({
68 message: `Undo repost (${plural(repostCount || 0, {
69 one: '# repost',
70 other: '# reposts',
71 })})`,
72 comment:
73 'Accessibility label for the repost button when the post has been reposted, verb followed by number of reposts and noun',
74 }),
75 )
76 : _(
77 msg({
78 message: `Repost (${plural(repostCount || 0, {
79 one: '# repost',
80 other: '# reposts',
81 })})`,
82 comment:
83 'Accessibility label for the repost button when the post has not been reposted, verb form followed by number of reposts and noun form',
84 }),
85 )
86 }>
87 <PostControlButtonIcon icon={Repost} />
88 {typeof repostCount !== 'undefined' && repostCount > 0 && (
89 <PostControlButtonText testID="repostCount">
90 {formatPostStatCount(repostCount)}
91 </PostControlButtonText>
92 )}
93 </PostControlButton>
94 <Dialog.Outer
95 control={dialogControl}
96 nativeOptions={{preventExpansion: true}}>
97 <Dialog.Handle />
98 <RepostButtonDialogInner
99 isReposted={isReposted}
100 onRepost={onRepost}
101 onQuote={onQuote}
102 embeddingDisabled={embeddingDisabled}
103 />
104 </Dialog.Outer>
105 </>
106 )
107}
108RepostButton = memo(RepostButton)
109export {RepostButton}
110
111let RepostButtonDialogInner = ({
112 isReposted,
113 onRepost,
114 onQuote,
115 embeddingDisabled,
116}: {
117 isReposted: boolean
118 onRepost: () => void
119 onQuote: () => void
120 embeddingDisabled: boolean
121}): React.ReactNode => {
122 const t = useTheme()
123 const {_} = useLingui()
124 const playHaptic = useHaptics()
125 const control = Dialog.useDialogContext()
126
127 const onPressRepost = useCallback(() => {
128 if (!isReposted) playHaptic()
129
130 control.close(() => {
131 onRepost()
132 })
133 }, [control, isReposted, onRepost, playHaptic])
134
135 const onPressQuote = useCallback(() => {
136 playHaptic()
137 control.close(() => {
138 onQuote()
139 })
140 }, [control, onQuote, playHaptic])
141
142 const onPressClose = useCallback(() => control.close(), [control])
143
144 return (
145 <Dialog.ScrollableInner label={_(msg`Repost or quote post`)}>
146 <View style={a.gap_xl}>
147 <View style={a.gap_xs}>
148 <Button
149 style={[a.justify_start, a.px_md, a.gap_sm]}
150 label={
151 isReposted
152 ? _(msg`Remove repost`)
153 : _(msg({message: `Repost`, context: 'action'}))
154 }
155 onPress={onPressRepost}
156 size="large"
157 variant="ghost"
158 color="primary">
159 <Repost size="lg" fill={t.palette.primary_500} />
160 <Text style={[a.font_semi_bold, a.text_xl]}>
161 {isReposted ? (
162 <Trans>Remove repost</Trans>
163 ) : (
164 <Trans context="action">Repost</Trans>
165 )}
166 </Text>
167 </Button>
168 <Button
169 disabled={embeddingDisabled}
170 testID="quoteBtn"
171 style={[a.justify_start, a.px_md, a.gap_sm]}
172 label={
173 embeddingDisabled
174 ? _(msg`Quote posts disabled`)
175 : _(msg`Quote post`)
176 }
177 onPress={onPressQuote}
178 size="large"
179 variant="ghost"
180 color="primary">
181 <Quote
182 size="lg"
183 fill={
184 embeddingDisabled
185 ? t.atoms.text_contrast_low.color
186 : t.palette.primary_500
187 }
188 />
189 <Text
190 style={[
191 a.font_semi_bold,
192 a.text_xl,
193 embeddingDisabled && t.atoms.text_contrast_low,
194 ]}>
195 {embeddingDisabled ? (
196 <Trans>Quote posts disabled</Trans>
197 ) : (
198 <Trans>Quote post</Trans>
199 )}
200 </Text>
201 </Button>
202 </View>
203 <Button
204 label={_(msg`Cancel quote post`)}
205 onPress={onPressClose}
206 size="large"
207 variant="outline"
208 color="primary">
209 <ButtonText>
210 <Trans>Cancel</Trans>
211 </ButtonText>
212 </Button>
213 </View>
214 </Dialog.ScrollableInner>
215 )
216}
217RepostButtonDialogInner = memo(RepostButtonDialogInner)
218export {RepostButtonDialogInner}