,
) => {
- const { isMessageListScrolledToBottom, onClick, unreadCount = 0 } = props;
+ const { isMessageListScrolledToBottom, onClick, threadList } = props;
+
+ const { channel: activeChannel, client } = useChatContext();
+ const { thread } = useChannelStateContext();
+ const [countUnread, setCountUnread] = useState(activeChannel?.countUnread() || 0);
+ const [replyCount, setReplyCount] = useState(thread?.reply_count || 0);
+ const observedEvent = threadList ? 'message.updated' : 'message.new';
+
+ useEffect(() => {
+ const handleEvent = (event: Event) => {
+ const newMessageInAnotherChannel = event.cid !== activeChannel?.cid;
+ const newMessageIsMine = event.user?.id === client.user?.id;
+
+ const isThreadOpen = !!thread;
+ const newMessageIsReply = !!event.message?.parent_id;
+ const dontIncreaseMainListCounterOnNewReply =
+ isThreadOpen && !threadList && newMessageIsReply;
+
+ if (
+ isMessageListScrolledToBottom ||
+ newMessageInAnotherChannel ||
+ newMessageIsMine ||
+ dontIncreaseMainListCounterOnNewReply
+ ) {
+ return;
+ }
+
+ if (event.type === 'message.new') {
+ // cannot rely on channel.countUnread because active channel is automatically marked read
+ setCountUnread((prev) => prev + 1);
+ } else if (event.message?.id === thread?.id) {
+ const newReplyCount = event.message?.reply_count || 0;
+ setCountUnread(() => newReplyCount - replyCount);
+ }
+ };
+ client.on(observedEvent, handleEvent);
+
+ return () => {
+ client.off(observedEvent, handleEvent);
+ };
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [activeChannel, isMessageListScrolledToBottom, observedEvent, replyCount, thread]);
+
+ useEffect(() => {
+ if (isMessageListScrolledToBottom) {
+ setCountUnread(0);
+ setReplyCount(thread?.reply_count || 0);
+ }
+ }, [isMessageListScrolledToBottom, thread]);
if (isMessageListScrolledToBottom) return null;
@@ -28,7 +76,7 @@ const UnMemoizedScrollToBottomButton = (
onClick={onClick}
>
- {unreadCount > 0 && (
+ {countUnread > 0 && (
- {unreadCount}
+ {countUnread}
)}
diff --git a/src/components/MessageList/UnreadMessagesNotification.tsx b/src/components/MessageList/UnreadMessagesNotification.tsx
index 5c7f6135b2..3f3117e767 100644
--- a/src/components/MessageList/UnreadMessagesNotification.tsx
+++ b/src/components/MessageList/UnreadMessagesNotification.tsx
@@ -3,12 +3,23 @@ import { CloseIcon } from './icons';
import { useChannelActionContext, useTranslationContext } from '../../context';
export type UnreadMessagesNotificationProps = {
+ /**
+ * Configuration parameter to determine the message page size, when jumping to the first unread message.
+ */
queryMessageLimit?: number;
+ /**
+ * Configuration parameter to determine, whether the unread count is to be shown on the component. Disabled by default.
+ */
+ showCount?: boolean;
+ /**
+ * The count of unread messages to be displayed if enabled.
+ */
unreadCount?: number;
};
export const UnreadMessagesNotification = ({
queryMessageLimit,
+ showCount,
unreadCount,
}: UnreadMessagesNotificationProps) => {
const { jumpToFirstUnreadMessage, markRead } = useChannelActionContext(
@@ -22,7 +33,9 @@ export const UnreadMessagesNotification = ({
data-testid='unread-messages-notification'
>