stream-chat-react
Version:
React components to create chat conversations or livestream style chat
68 lines (67 loc) • 4.84 kB
JavaScript
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);