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}