// Copyright 2023 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { type RefObject } from 'react'; import { ContextMenu, MenuItem } from 'react-contextmenu'; import ReactDOM from 'react-dom'; import type { LocalizerType } from '../../types/I18N'; export type ContextMenuTriggerType = { handleContextClick: ( event: React.MouseEvent | MouseEvent ) => void; }; type MessageContextProps = { i18n: LocalizerType; triggerId: string; shouldShowAdditional: boolean; onDownload: (() => void) | undefined; onEdit: (() => void) | undefined; onReplyToMessage: (() => void) | undefined; onReact: (() => void) | undefined; onRetryMessageSend: (() => void) | undefined; onRetryDeleteForEveryone: (() => void) | undefined; onCopy: (() => void) | undefined; onForward: (() => void) | undefined; onDeleteMessage: () => void; onMoreInfo: (() => void) | undefined; onSelect: (() => void) | undefined; }; export const MessageContextMenu = ({ i18n, triggerId, shouldShowAdditional, onDownload, onEdit, onReplyToMessage, onReact, onMoreInfo, onCopy, onSelect, onRetryMessageSend, onRetryDeleteForEveryone, onForward, onDeleteMessage, }: MessageContextProps): JSX.Element => { const menu = ( {shouldShowAdditional && ( <> {onDownload && ( {i18n('icu:MessageContextMenu__download')} )} {onReplyToMessage && ( { event.stopPropagation(); event.preventDefault(); onReplyToMessage(); }} > {i18n('icu:MessageContextMenu__reply')} )} {onReact && ( { event.stopPropagation(); event.preventDefault(); onReact(); }} > {i18n('icu:MessageContextMenu__react')} )} )} {onForward && ( { event.stopPropagation(); event.preventDefault(); onForward(); }} > {i18n('icu:MessageContextMenu__forward')} )} {onEdit && ( { event.stopPropagation(); event.preventDefault(); onEdit(); }} > {i18n('icu:edit')} )} {onSelect && ( { onSelect(); }} > {i18n('icu:MessageContextMenu__select')} )} {onCopy && ( { onCopy(); }} > {i18n('icu:copy')} )} {onMoreInfo && ( { event.stopPropagation(); event.preventDefault(); onMoreInfo(); }} > {i18n('icu:MessageContextMenu__info')} )} { event.stopPropagation(); event.preventDefault(); onDeleteMessage(); }} > {i18n('icu:MessageContextMenu__deleteMessage')} {onRetryMessageSend && ( { event.stopPropagation(); event.preventDefault(); onRetryMessageSend(); }} > {i18n('icu:retrySend')} )} {onRetryDeleteForEveryone && ( { event.stopPropagation(); event.preventDefault(); onRetryDeleteForEveryone(); }} > {i18n('icu:retryDeleteForEveryone')} )} ); return ReactDOM.createPortal(menu, document.body); }; export function useHandleMessageContextMenu( menuTriggerRef: RefObject ): ContextMenuTriggerType['handleContextClick'] { return React.useCallback( (event: React.MouseEvent | MouseEvent): void => { const selection = window.getSelection(); if (selection && !selection.isCollapsed) { return; } if (event && event.target instanceof HTMLAnchorElement) { return; } if (menuTriggerRef.current) { menuTriggerRef.current.handleContextClick( event ?? new MouseEvent('click') ); } }, [menuTriggerRef] ); }