UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

68 lines (67 loc) 4.84 kB
import React, { useState } from 'react'; import clsx from 'clsx'; import { MessageDeliveredIcon, MessageSentIcon } from './icons'; import { getReadByTooltipText, mapToUserNameOrId } from './utils'; import { Avatar as DefaultAvatar } from '../Avatar'; import { LoadingIndicator } from '../Loading'; import { PopperTooltip } from '../Tooltip'; import { useEnterLeaveHandlers } from '../Tooltip/hooks'; import { useChatContext } from '../../context/ChatContext'; import { useComponentContext } from '../../context/ComponentContext'; import { useMessageContext } from '../../context/MessageContext'; import { useTranslationContext } from '../../context/TranslationContext'; const UnMemoizedMessageStatus = (props) => { const { Avatar: propAvatar, MessageDeliveredStatus, MessageReadStatus, MessageSendingStatus, MessageSentStatus, messageType = 'simple', tooltipUserNameMapper = mapToUserNameOrId, } = props; const { handleEnter, handleLeave, tooltipVisible } = useEnterLeaveHandlers(); const { client } = useChatContext('MessageStatus'); const { Avatar: contextAvatar } = useComponentContext('MessageStatus'); const { deliveredTo, isMyMessage, lastOwnMessage, message, readBy, returnAllReadData, threadList, } = useMessageContext('MessageStatus'); const { t } = useTranslationContext('MessageStatus'); const [referenceElement, setReferenceElement] = useState(null); const Avatar = propAvatar || contextAvatar || DefaultAvatar; if (!isMyMessage() || message.type === 'error') return null; const justReadByMe = readBy?.length === 1 && readBy[0].id === client.user?.id; const deliveredOnlyToMe = deliveredTo?.length === 1 && deliveredTo[0].id === client.user?.id; const sending = message.status === 'sending'; const read = !!(readBy?.length && !justReadByMe && !threadList); const delivered = !!(deliveredTo?.length && !deliveredOnlyToMe && !read && !threadList); const sent = (returnAllReadData || lastOwnMessage?.id === message.id) && message.status === 'received' && !delivered && !read && !threadList; const readersWithoutOwnUser = read ? readBy.filter((item) => item.id !== client.user?.id) : []; const [lastReadUser] = readersWithoutOwnUser; return (React.createElement("span", { className: clsx(`str-chat__message-${messageType}-status str-chat__message-status`, { 'str-chat__message-status-delivered': delivered, 'str-chat__message-status-read-by': read, 'str-chat__message-status-sending': sending, 'str-chat__message-status-sent': sent, }), "data-testid": clsx({ 'message-status-delivered': delivered, 'message-status-read-by': read, 'message-status-sending': sending, 'message-status-sent': sent, }), onMouseEnter: handleEnter, onMouseLeave: handleLeave, ref: setReferenceElement }, sending && (MessageSendingStatus ? (React.createElement(MessageSendingStatus, null)) : (React.createElement(React.Fragment, null, React.createElement(PopperTooltip, { offset: [0, 5], referenceElement: referenceElement, visible: tooltipVisible }, t('Sending...')), React.createElement(LoadingIndicator, null)))), sent && (MessageSentStatus ? (React.createElement(MessageSentStatus, null)) : (React.createElement(React.Fragment, null, React.createElement(PopperTooltip, { offset: [0, 5], referenceElement: referenceElement, visible: tooltipVisible }, t('Sent')), React.createElement(MessageSentIcon, null)))), delivered && (MessageDeliveredStatus ? (React.createElement(MessageDeliveredStatus, null)) : (React.createElement(React.Fragment, null, React.createElement(PopperTooltip, { offset: [0, 5], referenceElement: referenceElement, visible: tooltipVisible }, t('Delivered')), React.createElement(MessageDeliveredIcon, null)))), read && (MessageReadStatus ? (React.createElement(MessageReadStatus, null)) : (React.createElement(React.Fragment, null, React.createElement(PopperTooltip, { offset: [0, 5], referenceElement: referenceElement, visible: tooltipVisible }, getReadByTooltipText(readBy, t, client, tooltipUserNameMapper)), React.createElement(Avatar, { className: 'str-chat__avatar--message-status', image: lastReadUser.image, name: lastReadUser.name || lastReadUser.id, user: lastReadUser }), readersWithoutOwnUser.length > 1 && (React.createElement("span", { className: `str-chat__message-${messageType}-status-number`, "data-testid": 'message-status-read-by-many' }, readersWithoutOwnUser.length))))))); }; export const MessageStatus = React.memo(UnMemoizedMessageStatus);