forked from
jollywhoppers.com/witchsky.app
fork
Configure Feed
Select the types of activity you want to include in your feed.
Bluesky app fork with some witchin' additions 馃挮
fork
Configure Feed
Select the types of activity you want to include in your feed.
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 QuoteIcon} from '#/components/icons/Quote'
12import {Repost_Stroke2_Corner3_Rounded as RepostIcon} 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_500}
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={RepostIcon} />
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`Reskeet or quote skeet`)}>
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 reskeet`)
153 : _(msg({message: `Reskeet`, context: 'action'}))
154 }
155 onPress={onPressRepost}
156 size="large"
157 variant="ghost"
158 color="primary">
159 <RepostIcon size="lg" fill={t.palette.primary_500} />
160 <Text style={[a.font_semi_bold, a.text_xl]}>
161 {isReposted ? (
162 <Trans>Remove reskeet</Trans>
163 ) : (
164 <Trans context="action">Reskeet</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 skeets disabled`)
175 : _(msg`Quote skeet`)
176 }
177 onPress={onPressQuote}
178 size="large"
179 variant="ghost"
180 color="primary">
181 <QuoteIcon
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 skeets disabled</Trans>
197 ) : (
198 <Trans>Quote skeet</Trans>
199 )}
200 </Text>
201 </Button>
202 </View>
203 <Button
204 label={_(msg`Cancel quote skeet`)}
205 onPress={onPressClose}
206 size="large"
207 color="secondary">
208 <ButtonText>
209 <Trans>Cancel</Trans>
210 </ButtonText>
211 </Button>
212 </View>
213 </Dialog.ScrollableInner>
214 )
215}
216RepostButtonDialogInner = memo(RepostButtonDialogInner)
217export {RepostButtonDialogInner}