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