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 ? _(msg`Undo repost`)
68 : _(msg({message: 'Repost', context: 'action'}))
69 } (${plural(repostCount || 0, {one: '# repost', other: '# reposts'})})`}
70 shape="round"
71 variant="ghost"
72 color="secondary"
73 hitSlop={POST_CTRL_HITSLOP}>
74 <Repost style={color} width={big ? 22 : 18} />
75 {typeof repostCount !== 'undefined' && repostCount > 0 ? (
76 <Text
77 testID="repostCount"
78 style={[
79 color,
80 big ? a.text_md : {fontSize: 15},
81 isReposted && a.font_bold,
82 ]}>
83 {formatCount(i18n, repostCount)}
84 </Text>
85 ) : undefined}
86 </Button>
87 <Dialog.Outer
88 control={dialogControl}
89 nativeOptions={{preventExpansion: true}}>
90 <Dialog.Handle />
91 <RepostButtonDialogInner
92 isReposted={isReposted}
93 onRepost={onRepost}
94 onQuote={onQuote}
95 embeddingDisabled={embeddingDisabled}
96 />
97 </Dialog.Outer>
98 </>
99 )
100}
101RepostButton = memo(RepostButton)
102export {RepostButton}
103
104let RepostButtonDialogInner = ({
105 isReposted,
106 onRepost,
107 onQuote,
108 embeddingDisabled,
109}: {
110 isReposted: boolean
111 onRepost: () => void
112 onQuote: () => void
113 embeddingDisabled: boolean
114}): React.ReactNode => {
115 const t = useTheme()
116 const {_} = useLingui()
117 const playHaptic = useHaptics()
118 const control = Dialog.useDialogContext()
119
120 const onPressRepost = useCallback(() => {
121 if (!isReposted) playHaptic()
122
123 control.close(() => {
124 onRepost()
125 })
126 }, [control, isReposted, onRepost, playHaptic])
127
128 const onPressQuote = useCallback(() => {
129 playHaptic()
130 control.close(() => {
131 onQuote()
132 })
133 }, [control, onQuote, playHaptic])
134
135 const onPressClose = useCallback(() => control.close(), [control])
136
137 return (
138 <Dialog.ScrollableInner label={_(msg`Repost or quote post`)}>
139 <View style={a.gap_xl}>
140 <View style={a.gap_xs}>
141 <Button
142 style={[a.justify_start, a.px_md]}
143 label={
144 isReposted
145 ? _(msg`Remove repost`)
146 : _(msg({message: `Repost`, context: 'action'}))
147 }
148 onPress={onPressRepost}
149 size="large"
150 variant="ghost"
151 color="primary">
152 <Repost size="lg" fill={t.palette.primary_500} />
153 <Text style={[a.font_bold, a.text_xl]}>
154 {isReposted ? (
155 <Trans>Remove repost</Trans>
156 ) : (
157 <Trans context="action">Repost</Trans>
158 )}
159 </Text>
160 </Button>
161 <Button
162 disabled={embeddingDisabled}
163 testID="quoteBtn"
164 style={[a.justify_start, a.px_md]}
165 label={
166 embeddingDisabled
167 ? _(msg`Quote posts disabled`)
168 : _(msg`Quote post`)
169 }
170 onPress={onPressQuote}
171 size="large"
172 variant="ghost"
173 color="primary">
174 <Quote
175 size="lg"
176 fill={
177 embeddingDisabled
178 ? t.atoms.text_contrast_low.color
179 : t.palette.primary_500
180 }
181 />
182 <Text
183 style={[
184 a.font_bold,
185 a.text_xl,
186 embeddingDisabled && t.atoms.text_contrast_low,
187 ]}>
188 {embeddingDisabled ? (
189 <Trans>Quote posts disabled</Trans>
190 ) : (
191 <Trans>Quote post</Trans>
192 )}
193 </Text>
194 </Button>
195 </View>
196 <Button
197 label={_(msg`Cancel quote post`)}
198 onPress={onPressClose}
199 size="large"
200 variant="outline"
201 color="primary">
202 <ButtonText>
203 <Trans>Cancel</Trans>
204 </ButtonText>
205 </Button>
206 </View>
207 </Dialog.ScrollableInner>
208 )
209}
210RepostButtonDialogInner = memo(RepostButtonDialogInner)
211export {RepostButtonDialogInner}