import {useCallback, useRef, useState} from 'react' import {Pressable, View} from 'react-native' import {type ChatBskyConvoDefs} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import type React from 'react' import {useConvoActive} from '#/state/messages/convo' import {useSession} from '#/state/session' import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' import {MessageContextMenu} from '#/components/dms/MessageContextMenu' import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontalIcon} from '#/components/icons/DotGrid' import {EmojiSmile_Stroke2_Corner0_Rounded as EmojiSmileIcon} from '#/components/icons/Emoji' import {EmojiReactionPicker} from './EmojiReactionPicker' import {hasReachedReactionLimit} from './util' export function ActionsWrapper({ message, isFromSelf, children, }: { message: ChatBskyConvoDefs.MessageView isFromSelf: boolean children: React.ReactNode }) { const viewRef = useRef(null) const t = useTheme() const {_} = useLingui() const convo = useConvoActive() const {currentAccount} = useSession() const [showActions, setShowActions] = useState(false) const onMouseEnter = useCallback(() => { setShowActions(true) }, []) const onMouseLeave = useCallback(() => { setShowActions(false) }, []) // We need to handle the `onFocus` separately because we want to know if there is a related target (the element // that is losing focus). If there isn't that means the focus is coming from a dropdown that is now closed. const onFocus = useCallback(e => { if (e.nativeEvent.relatedTarget == null) return setShowActions(true) }, []) const onEmojiSelect = useCallback( (emoji: string) => { if ( message.reactions?.find( reaction => reaction.value === emoji && reaction.sender.did === currentAccount?.did, ) ) { convo .removeReaction(message.id, emoji) .catch(() => Toast.show(_(msg`Failed to remove emoji reaction`))) } else { if (hasReachedReactionLimit(message, currentAccount?.did)) return convo .addReaction(message.id, emoji) .catch(() => Toast.show(_(msg`Failed to add emoji reaction`), 'xmark'), ) } }, [_, convo, message, currentAccount?.did], ) return ( {({props, state, isNative, control}) => { // always false, file is platform split if (isNative) return null const showMenuTrigger = showActions || control.isOpen ? 1 : 0 return ( ) }} {({props, state, isNative, control}) => { // always false, file is platform split if (isNative) return null const showMenuTrigger = showActions || control.isOpen ? 1 : 0 return ( ) }} {children} ) }