From a942936203c0965b1c7d69e107c343a114523ef0 Mon Sep 17 00:00:00 2001 From: artemenkoS <130140499+artemenkoS@users.noreply.github.com> Date: Thu, 11 Dec 2025 16:55:50 +0500 Subject: [PATCH] feat: CSL-778 --- .../chat-list/chat-list-item.component.tsx | 28 ++++++++++- .../shared/chat-list/chat-list.component.tsx | 48 +++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/components/shared/chat-list/chat-list-item.component.tsx b/src/components/shared/chat-list/chat-list-item.component.tsx index 1a81cf5..7383e77 100644 --- a/src/components/shared/chat-list/chat-list-item.component.tsx +++ b/src/components/shared/chat-list/chat-list-item.component.tsx @@ -1,6 +1,6 @@ import { FC, useEffect, useMemo } from 'react'; -import { Flex, List, Skeleton } from 'antd'; +import { Badge, Flex, List, Skeleton } from 'antd'; import { useTranslation } from 'react-i18next'; import emptyAvatar from 'assets/emptyAvatar.svg'; @@ -31,12 +31,18 @@ interface ContactListItemProps { lastMessage: MessageInterface; onNameExtracted?: (chatId: string, name: string) => void; showDescription?: boolean; + unreadCount?: number; + onClearUnread?: () => void; } +const WABA_POOLS = ['7835', '9908']; + const ChatListItem: FC = ({ lastMessage, onNameExtracted, showDescription = true, + unreadCount, + onClearUnread, }) => { const { t, @@ -151,6 +157,10 @@ const ChatListItem: FC = ({ }); setSearchQuery(''); + + if (onClearUnread) { + onClearUnread(); + } }; return ( @@ -196,7 +206,21 @@ const ChatListItem: FC = ({ } /> {showDescription && ( - {messageDate} + + {messageDate} + {unreadCount && + unreadCount > 0 && + WABA_POOLS.includes(instanceCredentials.idInstance.toString().slice(0, 4)) && ( + + )} + )} diff --git a/src/components/shared/chat-list/chat-list.component.tsx b/src/components/shared/chat-list/chat-list.component.tsx index 8ba150b..f2459a6 100644 --- a/src/components/shared/chat-list/chat-list.component.tsx +++ b/src/components/shared/chat-list/chat-list.component.tsx @@ -38,6 +38,10 @@ const ChatList: FC = () => { const [page, setPage] = useState(1); const [contactsPage, setContactsPage] = useState(1); const [messagesPage, setMessagesPage] = useState(1); + const [initialLoaded, setInitialLoaded] = useState(false); + + const [initialMessageIds, setInitialMessageIds] = useState>(new Set()); + const [unreadCounts, setUnreadCounts] = useState>({}); const limit = isMiniVersion ? 5 : matchMedia ? 16 : 12; @@ -59,6 +63,46 @@ const ChatList: FC = () => { const pagedFilteredContacts = filteredContacts.slice(0, contactsPage * limit); const pagedFilteredMessages = filteredMessages.slice(0, messagesPage * limit); + useEffect(() => { + if (!initialLoaded && allMessages.length > 0) { + const messageIds = new Set( + allMessages.map((msg) => msg.idMessage || `${msg.chatId}-${msg.timestamp}`) + ); + setInitialMessageIds(messageIds); + setInitialLoaded(true); + } + }, [allMessages, initialLoaded]); + + useEffect(() => { + if (!initialLoaded || allMessages.length === 0) return; + + const prevIds = initialMessageIds; + const newIds = new Set(prevIds); + + const newUnreadCounts: Record = { ...unreadCounts }; + + allMessages.forEach((msg) => { + const messageId = msg.idMessage || `${msg.chatId}-${msg.timestamp}`; + + if (!prevIds.has(messageId)) { + newUnreadCounts[msg.chatId] = (newUnreadCounts[msg.chatId] || 0) + 1; + } + + newIds.add(messageId); + }); + + setInitialMessageIds(newIds); + setUnreadCounts(newUnreadCounts); + }, [allMessages, initialLoaded]); + + const clearUnreadCount = (chatId: string) => { + setUnreadCounts((prev) => { + const updated = { ...prev }; + delete updated[chatId]; + return updated; + }); + }; + useEffect(() => { if (!allMessages.length) return; @@ -188,6 +232,8 @@ const ChatList: FC = () => { key={`${msg.chatId}-${msg.idMessage}`} lastMessage={msg} onNameExtracted={handleNameExtracted} + unreadCount={unreadCounts[msg.chatId]} + onClearUnread={() => clearUnreadCount(msg.chatId)} /> )} split={false} @@ -210,6 +256,8 @@ const ChatList: FC = () => { key={message.chatId} lastMessage={message} onNameExtracted={handleNameExtracted} + unreadCount={unreadCounts[message.chatId]} + onClearUnread={() => clearUnreadCount(message.chatId)} /> )} loading={{