diff options
author | Samuel Newman <mozzius@protonmail.com> | 2025-05-24 02:02:38 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-23 18:02:38 -0500 |
commit | c3f88e0a48bdf22831736ad3d44222e7c4418486 (patch) | |
tree | d72137786908d5c61ad52a7cb7aa8fd37472a615 /src/components/PostControls/RepostButton.tsx | |
parent | 5aadb9e41b1305e673947b28ba0566bdc3a3325d (diff) | |
download | voidsky-c3f88e0a48bdf22831736ad3d44222e7c4418486.tar.zst |
Share menu (#7840)
* move post ctrls to #/components * restructure post controls, basic share menu * add border radius to searchable people list for android * Revert "add border radius to searchable people list for android" This reverts commit 417449086e25b82f5683b12f6405d972f48ce50e. * add copy link to native share menu * reorg files again * open native share menu on long press * Translation comments Thanks @surfdude29 * abs path * update type imports, remove forwardRef * rm react import * equal spacing of buttons, extract disco debug * add better icon * add right offset to share button for visual alignment * Add recent chats to share menu (#7853) * add recent chats to share menu * Update RecentChats.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update RecentChats.tsx * add fading edge on andriod * tweak scrollview * Add metrics and A/B alt icon to share menu (#8401) * add metrics * add a/b tested alt icon --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * More descriptive share text/icon on web (#7854) * more descriptive share text on web * revert dev mode changes * add missing import * use modified share icon everywhere * Add back conflicting changes --------- Co-authored-by: Eric Bailey <git@esb.lol> --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/components/PostControls/RepostButton.tsx')
-rw-r--r-- | src/components/PostControls/RepostButton.tsx | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/components/PostControls/RepostButton.tsx b/src/components/PostControls/RepostButton.tsx new file mode 100644 index 000000000..db63a7383 --- /dev/null +++ b/src/components/PostControls/RepostButton.tsx @@ -0,0 +1,206 @@ +import {memo, useCallback} from 'react' +import {View} from 'react-native' +import {msg, plural, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useHaptics} from '#/lib/haptics' +import {useRequireAuth} from '#/state/session' +import {formatCount} from '#/view/com/util/numeric/format' +import {atoms as a, useTheme} from '#/alf' +import {Button, ButtonText} from '#/components/Button' +import * as Dialog from '#/components/Dialog' +import {CloseQuote_Stroke2_Corner1_Rounded as Quote} from '#/components/icons/Quote' +import {Repost_Stroke2_Corner2_Rounded as Repost} from '#/components/icons/Repost' +import {Text} from '#/components/Typography' +import { + PostControlButton, + PostControlButtonIcon, + PostControlButtonText, +} from './PostControlButton' + +interface Props { + isReposted: boolean + repostCount?: number + onRepost: () => void + onQuote: () => void + big?: boolean + embeddingDisabled: boolean +} + +let RepostButton = ({ + isReposted, + repostCount, + onRepost, + onQuote, + big, + embeddingDisabled, +}: Props): React.ReactNode => { + const t = useTheme() + const {_, i18n} = useLingui() + const requireAuth = useRequireAuth() + const dialogControl = Dialog.useDialogControl() + + return ( + <> + <PostControlButton + testID="repostBtn" + active={isReposted} + activeColor={t.palette.positive_600} + big={big} + onPress={() => requireAuth(() => dialogControl.open())} + onLongPress={() => requireAuth(() => onQuote())} + label={ + isReposted + ? _( + msg({ + message: `Undo repost (${plural(repostCount || 0, { + one: '# repost', + other: '# reposts', + })})`, + comment: + 'Accessibility label for the repost button when the post has been reposted, verb followed by number of reposts and noun', + }), + ) + : _( + msg({ + message: `Repost (${plural(repostCount || 0, { + one: '# repost', + other: '# reposts', + })})`, + comment: + 'Accessibility label for the repost button when the post has not been reposted, verb form followed by number of reposts and noun form', + }), + ) + }> + <PostControlButtonIcon icon={Repost} /> + {typeof repostCount !== 'undefined' && repostCount > 0 && ( + <PostControlButtonText testID="repostCount"> + {formatCount(i18n, repostCount)} + </PostControlButtonText> + )} + </PostControlButton> + <Dialog.Outer + control={dialogControl} + nativeOptions={{preventExpansion: true}}> + <Dialog.Handle /> + <RepostButtonDialogInner + isReposted={isReposted} + onRepost={onRepost} + onQuote={onQuote} + embeddingDisabled={embeddingDisabled} + /> + </Dialog.Outer> + </> + ) +} +RepostButton = memo(RepostButton) +export {RepostButton} + +let RepostButtonDialogInner = ({ + isReposted, + onRepost, + onQuote, + embeddingDisabled, +}: { + isReposted: boolean + onRepost: () => void + onQuote: () => void + embeddingDisabled: boolean +}): React.ReactNode => { + const t = useTheme() + const {_} = useLingui() + const playHaptic = useHaptics() + const control = Dialog.useDialogContext() + + const onPressRepost = useCallback(() => { + if (!isReposted) playHaptic() + + control.close(() => { + onRepost() + }) + }, [control, isReposted, onRepost, playHaptic]) + + const onPressQuote = useCallback(() => { + playHaptic() + control.close(() => { + onQuote() + }) + }, [control, onQuote, playHaptic]) + + const onPressClose = useCallback(() => control.close(), [control]) + + return ( + <Dialog.ScrollableInner label={_(msg`Repost or quote post`)}> + <View style={a.gap_xl}> + <View style={a.gap_xs}> + <Button + style={[a.justify_start, a.px_md]} + label={ + isReposted + ? _(msg`Remove repost`) + : _(msg({message: `Repost`, context: 'action'})) + } + onPress={onPressRepost} + size="large" + variant="ghost" + color="primary"> + <Repost size="lg" fill={t.palette.primary_500} /> + <Text style={[a.font_bold, a.text_xl]}> + {isReposted ? ( + <Trans>Remove repost</Trans> + ) : ( + <Trans context="action">Repost</Trans> + )} + </Text> + </Button> + <Button + disabled={embeddingDisabled} + testID="quoteBtn" + style={[a.justify_start, a.px_md]} + label={ + embeddingDisabled + ? _(msg`Quote posts disabled`) + : _(msg`Quote post`) + } + onPress={onPressQuote} + size="large" + variant="ghost" + color="primary"> + <Quote + size="lg" + fill={ + embeddingDisabled + ? t.atoms.text_contrast_low.color + : t.palette.primary_500 + } + /> + <Text + style={[ + a.font_bold, + a.text_xl, + embeddingDisabled && t.atoms.text_contrast_low, + ]}> + {embeddingDisabled ? ( + <Trans>Quote posts disabled</Trans> + ) : ( + <Trans>Quote post</Trans> + )} + </Text> + </Button> + </View> + <Button + label={_(msg`Cancel quote post`)} + onPress={onPressClose} + size="large" + variant="outline" + color="primary"> + <ButtonText> + <Trans>Cancel</Trans> + </ButtonText> + </Button> + </View> + </Dialog.ScrollableInner> + ) +} +RepostButtonDialogInner = memo(RepostButtonDialogInner) +export {RepostButtonDialogInner} |