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