UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

60 lines (59 loc) 2.89 kB
import React from 'react'; import clsx from 'clsx'; import { useChannelStateContext } from '../../context/ChannelStateContext'; import { useChatContext } from '../../context/ChatContext'; import { useTypingContext } from '../../context/TypingContext'; import { useTranslationContext } from '../../context/TranslationContext'; const useJoinTypingUsers = (names) => { const { t } = useTranslationContext(); if (!names.length) return null; const [name, ...rest] = names; if (names.length === 1) return t('{{ user }} is typing...', { user: name, }); const MAX_JOINED_USERS = 3; if (names.length > MAX_JOINED_USERS) return t('{{ users }} and more are typing...', { users: names.slice(0, MAX_JOINED_USERS).join(', ').trim(), }); return t('{{ users }} and {{ user }} are typing...', { user: name, users: rest.join(', ').trim(), }); }; /** * TypingIndicator lists users currently typing, it needs to be a child of Channel component */ const UnMemoizedTypingIndicator = (props) => { const { threadList } = props; const { channelConfig, thread } = useChannelStateContext('TypingIndicator'); const { client } = useChatContext('TypingIndicator'); const { typing = {} } = useTypingContext('TypingIndicator'); const typingInChannel = !threadList ? Object.values(typing).filter(({ parent_id, user }) => user?.id !== client.user?.id && !parent_id) : []; const typingInThread = threadList ? Object.values(typing).filter(({ parent_id, user }) => user?.id !== client.user?.id && parent_id === thread?.id) : []; const typingUserList = (threadList ? typingInThread : typingInChannel) .map(({ user }) => user?.name || user?.id) .filter(Boolean); const joinedTypingUsers = useJoinTypingUsers(typingUserList); const isTypingActive = (threadList && typingInThread.length) || (!threadList && typingInChannel.length); if (channelConfig?.typing_events === false) { return null; } if (!isTypingActive) return null; return (React.createElement("div", { className: clsx('str-chat__typing-indicator', { 'str-chat__typing-indicator--typing': isTypingActive, }), "data-testid": 'typing-indicator' }, React.createElement("div", { className: 'str-chat__typing-indicator__dots' }, React.createElement("span", { className: 'str-chat__typing-indicator__dot' }), React.createElement("span", { className: 'str-chat__typing-indicator__dot' }), React.createElement("span", { className: 'str-chat__typing-indicator__dot' })), React.createElement("div", { className: 'str-chat__typing-indicator__users', "data-testid": 'typing-users' }, joinedTypingUsers))); }; export const TypingIndicator = React.memo(UnMemoizedTypingIndicator);