UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

56 lines (55 loc) 4.18 kB
import clsx from 'clsx'; import React, { useCallback, useRef } from 'react'; import { MessageActionsBox } from './MessageActionsBox'; import { DialogAnchor, useDialog, useDialogIsOpen } from '../Dialog'; import { ActionsIcon as DefaultActionsIcon } from '../Message/icons'; import { isUserMuted, shouldRenderMessageActions } from '../Message/utils'; import { useChatContext } from '../../context/ChatContext'; import { useMessageContext } from '../../context/MessageContext'; import { useComponentContext, useTranslationContext } from '../../context'; export const MessageActions = (props) => { const { ActionsIcon = DefaultActionsIcon, customWrapperClass = '', getMessageActions: propGetMessageActions, handleDelete: propHandleDelete, handleFlag: propHandleFlag, handleMarkUnread: propHandleMarkUnread, handleMute: propHandleMute, handlePin: propHandlePin, inline, message: propMessage, mine, } = props; const { mutes } = useChatContext('MessageActions'); const { customMessageActions, getMessageActions: contextGetMessageActions, handleDelete: contextHandleDelete, handleFlag: contextHandleFlag, handleMarkUnread: contextHandleMarkUnread, handleMute: contextHandleMute, handlePin: contextHandlePin, isMyMessage, message: contextMessage, setEditingState, threadList, } = useMessageContext('MessageActions'); const { CustomMessageActionsList } = useComponentContext('MessageActions'); const { t } = useTranslationContext('MessageActions'); const getMessageActions = propGetMessageActions || contextGetMessageActions; const handleDelete = propHandleDelete || contextHandleDelete; const handleFlag = propHandleFlag || contextHandleFlag; const handleMarkUnread = propHandleMarkUnread || contextHandleMarkUnread; const handleMute = propHandleMute || contextHandleMute; const handlePin = propHandlePin || contextHandlePin; const message = propMessage || contextMessage; const isMine = mine ? mine() : isMyMessage(); const isMuted = useCallback(() => isUserMuted(message, mutes), [message, mutes]); const dialogId = `message-actions--${message.id}`; const dialog = useDialog({ id: dialogId }); const dialogIsOpen = useDialogIsOpen(dialogId); const messageActions = getMessageActions(); const renderMessageActions = shouldRenderMessageActions({ customMessageActions, CustomMessageActionsList, inThread: threadList, messageActions, }); const actionsBoxButtonRef = useRef(null); if (!renderMessageActions) return null; return (React.createElement(MessageActionsWrapper, { customWrapperClass: customWrapperClass, inline: inline, toggleOpen: dialog?.toggle }, React.createElement(DialogAnchor, { id: dialogId, placement: isMine ? 'top-end' : 'top-start', referenceElement: actionsBoxButtonRef.current, tabIndex: -1, trapFocus: true }, React.createElement(MessageActionsBox, { getMessageActions: getMessageActions, handleDelete: handleDelete, handleEdit: setEditingState, handleFlag: handleFlag, handleMarkUnread: handleMarkUnread, handleMute: handleMute, handlePin: handlePin, isUserMuted: isMuted, mine: isMine, open: dialogIsOpen })), React.createElement("button", { "aria-expanded": dialogIsOpen, "aria-haspopup": 'true', "aria-label": t('aria/Open Message Actions Menu'), className: 'str-chat__message-actions-box-button', "data-testid": 'message-actions-toggle-button', ref: actionsBoxButtonRef }, React.createElement(ActionsIcon, { className: 'str-chat__message-action-icon' })))); }; export const MessageActionsWrapper = (props) => { const { children, customWrapperClass, inline, toggleOpen } = props; const defaultWrapperClass = clsx('str-chat__message-simple__actions__action', 'str-chat__message-simple__actions__action--options', 'str-chat__message-actions-container'); const wrapperProps = { className: customWrapperClass || defaultWrapperClass, 'data-testid': 'message-actions', onClick: toggleOpen, }; if (inline) return React.createElement("span", { ...wrapperProps }, children); return React.createElement("div", { ...wrapperProps }, children); };