mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at remove-preload 141 lines 4.8 kB view raw
1import React from 'react' 2import {LayoutAnimation, Pressable, View} from 'react-native' 3import * as Clipboard from 'expo-clipboard' 4import {ChatBskyConvoDefs} from '@atproto-labs/api' 5import {msg} from '@lingui/macro' 6import {useLingui} from '@lingui/react' 7 8import {useChat} from 'state/messages' 9import {ConvoStatus} from 'state/messages/convo' 10import {useSession} from 'state/session' 11import * as Toast from '#/view/com/util/Toast' 12import {atoms as a, useTheme} from '#/alf' 13import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid' 14import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash' 15import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning' 16import * as Menu from '#/components/Menu' 17import * as Prompt from '#/components/Prompt' 18import {usePromptControl} from '#/components/Prompt' 19import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '../icons/Clipboard' 20 21export let MessageMenu = ({ 22 message, 23 control, 24 hideTrigger, 25 triggerOpacity, 26}: { 27 hideTrigger?: boolean 28 triggerOpacity?: number 29 onTriggerPress?: () => void 30 message: ChatBskyConvoDefs.MessageView 31 control: Menu.MenuControlProps 32}): React.ReactNode => { 33 const {_} = useLingui() 34 const t = useTheme() 35 const {currentAccount} = useSession() 36 const chat = useChat() 37 const deleteControl = usePromptControl() 38 const retryDeleteControl = usePromptControl() 39 40 const isFromSelf = message.sender?.did === currentAccount?.did 41 42 const onCopyPostText = React.useCallback(() => { 43 // use when we have rich text 44 // const str = richTextToString(richText, true) 45 46 Clipboard.setStringAsync(message.text) 47 Toast.show(_(msg`Copied to clipboard`)) 48 }, [_, message.text]) 49 50 const onDelete = React.useCallback(() => { 51 if (chat.status !== ConvoStatus.Ready) return 52 53 LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) 54 chat 55 .deleteMessage(message.id) 56 .then(() => Toast.show(_(msg`Message deleted`))) 57 .catch(() => retryDeleteControl.open()) 58 }, [_, chat, message.id, retryDeleteControl]) 59 60 const onReport = React.useCallback(() => { 61 // TODO report the message 62 }, []) 63 64 return ( 65 <> 66 <Menu.Root control={control}> 67 {!hideTrigger && ( 68 <View style={{opacity: triggerOpacity}}> 69 <Menu.Trigger label={_(msg`Chat settings`)}> 70 {({props, state}) => ( 71 <Pressable 72 {...props} 73 style={[ 74 a.p_sm, 75 a.rounded_full, 76 (state.hovered || state.pressed) && t.atoms.bg_contrast_25, 77 ]}> 78 <DotsHorizontal size="sm" style={t.atoms.text} /> 79 </Pressable> 80 )} 81 </Menu.Trigger> 82 </View> 83 )} 84 85 <Menu.Outer> 86 <Menu.Group> 87 <Menu.Item 88 testID="messageDropdownCopyBtn" 89 label={_(msg`Copy message text`)} 90 onPress={onCopyPostText}> 91 <Menu.ItemText>{_(msg`Copy message text`)}</Menu.ItemText> 92 <Menu.ItemIcon icon={ClipboardIcon} position="right" /> 93 </Menu.Item> 94 </Menu.Group> 95 <Menu.Divider /> 96 <Menu.Group> 97 <Menu.Item 98 testID="messageDropdownDeleteBtn" 99 label={_(msg`Delete message for me`)} 100 onPress={deleteControl.open}> 101 <Menu.ItemText>{_(msg`Delete for me`)}</Menu.ItemText> 102 <Menu.ItemIcon icon={Trash} position="right" /> 103 </Menu.Item> 104 {!isFromSelf && ( 105 <Menu.Item 106 testID="messageDropdownReportBtn" 107 label={_(msg`Report message`)} 108 onPress={onReport}> 109 <Menu.ItemText>{_(msg`Report`)}</Menu.ItemText> 110 <Menu.ItemIcon icon={Warning} position="right" /> 111 </Menu.Item> 112 )} 113 </Menu.Group> 114 </Menu.Outer> 115 </Menu.Root> 116 117 <Prompt.Basic 118 control={deleteControl} 119 title={_(msg`Delete message`)} 120 description={_( 121 msg`Are you sure you want to delete this message? The message will be deleted for you, but not for other participants.`, 122 )} 123 confirmButtonCta={_(msg`Delete`)} 124 confirmButtonColor="negative" 125 onConfirm={onDelete} 126 /> 127 128 <Prompt.Basic 129 control={retryDeleteControl} 130 title={_(msg`Failed to delete message`)} 131 description={_( 132 msg`An error occurred while trying to delete the message. Please try again.`, 133 )} 134 confirmButtonCta={_(msg`Retry`)} 135 confirmButtonColor="negative" 136 onConfirm={onDelete} 137 /> 138 </> 139 ) 140} 141MessageMenu = React.memo(MessageMenu)