UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

65 lines (64 loc) 4.65 kB
import React, { useCallback, useMemo } from 'react'; import { useDeleteHandler, useUserRole } from './hooks'; import { MessageDeleted as DefaultMessageDeleted } from './MessageDeleted'; import { MessageTimestamp } from './MessageTimestamp'; import { getMessageActions } from './utils'; import { Avatar } from '../Avatar'; import { Gallery } from '../Gallery'; import { MessageActions } from '../MessageActions'; import { useChatContext } from '../../context/ChatContext'; import { useComponentContext } from '../../context/ComponentContext'; import { useMessageContext } from '../../context/MessageContext'; import { useTranslationContext } from '../../context/TranslationContext'; import { renderText } from './renderText'; const selectColor = (number, dark) => { const hue = number * 137.508; // use golden angle approximation return `hsl(${hue},${dark ? '50%' : '85%'}, ${dark ? '75%' : '55%'})`; }; const hashUserId = (userId) => { const hash = userId.split('').reduce((acc, c) => { acc = (acc << 5) - acc + c.charCodeAt(0); return acc & acc; }, 0); return Math.abs(hash) / 10 ** Math.ceil(Math.log10(Math.abs(hash) + 1)); }; const getUserColor = (theme, userId) => selectColor(hashUserId(userId), theme.includes('dark')); const UnMemoizedFixedHeightMessage = (props) => { const { groupedByUser: propGroupedByUser, message: propMessage } = props; const { theme } = useChatContext('FixedHeightMessage'); const { groupedByUser: contextGroupedByUser, message: contextMessage } = useMessageContext('FixedHeightMessage'); const { MessageDeleted = DefaultMessageDeleted } = useComponentContext('FixedHeightMessage'); const { userLanguage } = useTranslationContext('FixedHeightMessage'); const groupedByUser = propGroupedByUser !== undefined ? propGroupedByUser : contextGroupedByUser; const message = propMessage || contextMessage; const handleDelete = useDeleteHandler(message); const role = useUserRole(message); const messageTextToRender = message?.i18n?.[`${userLanguage}_text`] || message?.text; const renderedText = useMemo(() => renderText(messageTextToRender, message.mentioned_users), [message.mentioned_users, messageTextToRender]); const userId = message.user?.id || ''; const userColor = useMemo(() => getUserColor(theme, userId), [userId, theme]); const messageActionsHandler = useCallback(() => getMessageActions(['delete'], { canDelete: role.canDelete }), [role]); const images = message?.attachments?.filter(({ type }) => type === 'image'); return (React.createElement("div", { className: `str-chat__virtual-message__wrapper ${role.isMyMessage ? 'str-chat__virtual-message__wrapper--me' : ''} ${groupedByUser ? 'str-chat__virtual-message__wrapper--group' : ''}`, key: message.id }, message.user && (React.createElement(Avatar, { image: message.user.image, name: message.user.name || message.user.id, user: message.user })), React.createElement("div", { className: 'str-chat__virtual-message__content' }, React.createElement("div", { className: 'str-chat__virtual-message__meta' }, React.createElement("div", { className: 'str-chat__virtual-message__author', style: { color: userColor } }, React.createElement("strong", null, message.user?.name || 'unknown'))), message.deleted_at || message.type === 'deleted' ? (React.createElement(MessageDeleted, { message: message })) : (React.createElement(React.Fragment, null, images && React.createElement(Gallery, { images: images }), React.createElement("div", { className: 'str-chat__virtual-message__text', "data-testid": 'msg-text' }, renderedText, React.createElement("div", { className: 'str-chat__virtual-message__data' }, React.createElement(MessageActions, { customWrapperClass: 'str-chat__virtual-message__actions', getMessageActions: messageActionsHandler, handleDelete: handleDelete, message: message, mine: () => role.isMyMessage }), React.createElement("span", { className: 'str-chat__virtual-message__date' }, React.createElement(MessageTimestamp, { customClass: 'str-chat__message-simple-timestamp', message: message }))))))))); }; /** * @deprecated - This UI component will be removed in the next major release. * * FixedHeightMessage - This component renders a single message. * It uses fixed height elements to make sure it works well in VirtualizedMessageList */ export const FixedHeightMessage = React.memo(UnMemoizedFixedHeightMessage);