UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

85 lines (84 loc) 4.31 kB
import throttle from 'lodash.throttle'; import React, { useEffect, useMemo, useState } from 'react'; import { ChannelPreviewMessenger } from './ChannelPreviewMessenger'; import { useIsChannelMuted } from './hooks/useIsChannelMuted'; import { useChannelPreviewInfo } from './hooks/useChannelPreviewInfo'; import { getLatestMessagePreview as defaultGetLatestMessagePreview } from './utils'; import { useChatContext } from '../../context/ChatContext'; import { useTranslationContext } from '../../context/TranslationContext'; import { useMessageDeliveryStatus } from './hooks/useMessageDeliveryStatus'; export const ChannelPreview = (props) => { const { active, channel, channelUpdateCount, getLatestMessagePreview = defaultGetLatestMessagePreview, Preview = ChannelPreviewMessenger, } = props; const { channel: activeChannel, client, isMessageAIGenerated, setActiveChannel, } = useChatContext('ChannelPreview'); const { t, userLanguage } = useTranslationContext('ChannelPreview'); const { displayImage, displayTitle, groupChannelDisplayInfo } = useChannelPreviewInfo({ channel, }); const [lastMessage, setLastMessage] = useState(channel.state.messages[channel.state.messages.length - 1]); const [unread, setUnread] = useState(0); const { messageDeliveryStatus } = useMessageDeliveryStatus({ channel, lastMessage, }); const isActive = typeof active === 'undefined' ? activeChannel?.cid === channel.cid : active; const { muted } = useIsChannelMuted(channel); useEffect(() => { const handleEvent = (event) => { if (!event.cid) return setUnread(0); if (channel.cid === event.cid) setUnread(0); }; client.on('notification.mark_read', handleEvent); return () => client.off('notification.mark_read', handleEvent); }, [channel, client]); useEffect(() => { const handleEvent = (event) => { if (channel.cid !== event.cid) return; if (event.user?.id !== client.user?.id) return; setUnread(channel.countUnread()); }; channel.on('notification.mark_unread', handleEvent); return () => { channel.off('notification.mark_unread', handleEvent); }; }, [channel, client]); const refreshUnreadCount = useMemo(() => throttle(() => { if (muted) { setUnread(0); } else { setUnread(channel.countUnread()); } }, 400), [channel, muted]); useEffect(() => { refreshUnreadCount(); const handleEvent = (event) => { const deletedMessagesInAnotherChannel = event.type === 'user.messages.deleted' && event.cid && event.cid !== channel.cid; if (deletedMessagesInAnotherChannel) return; setLastMessage(channel.state.latestMessages[channel.state.latestMessages.length - 1]); refreshUnreadCount(); }; channel.on('message.new', handleEvent); channel.on('message.updated', handleEvent); channel.on('message.deleted', handleEvent); client.on('user.messages.deleted', handleEvent); channel.on('message.undeleted', handleEvent); channel.on('channel.truncated', handleEvent); return () => { channel.off('message.new', handleEvent); channel.off('message.updated', handleEvent); channel.off('message.deleted', handleEvent); client.off('user.messages.deleted', handleEvent); channel.off('message.undeleted', handleEvent); channel.off('channel.truncated', handleEvent); }; }, [channel, client, refreshUnreadCount, channelUpdateCount]); if (!Preview) return null; const latestMessagePreview = getLatestMessagePreview(channel, t, userLanguage, isMessageAIGenerated); return (React.createElement(Preview, { ...props, active: isActive, displayImage: displayImage, displayTitle: displayTitle, groupChannelDisplayInfo: groupChannelDisplayInfo, lastMessage: lastMessage, latestMessage: latestMessagePreview, latestMessagePreview: latestMessagePreview, messageDeliveryStatus: messageDeliveryStatus, setActiveChannel: setActiveChannel, unread: unread })); };