From 4aa1a2344e1dbf8373bb387a4e71356679ef2a35 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Wed, 9 Oct 2024 20:19:08 -0300 Subject: [PATCH] fix: livechat stuck unread counter on new messages (#33229) --- .changeset/poor-falcons-doubt.md | 5 ++ .../omnichannel/omnichannel-livechat.spec.ts | 18 +++++- packages/livechat/src/lib/main.js | 55 +++++++++---------- 3 files changed, 47 insertions(+), 31 deletions(-) create mode 100644 .changeset/poor-falcons-doubt.md diff --git a/.changeset/poor-falcons-doubt.md b/.changeset/poor-falcons-doubt.md new file mode 100644 index 000000000000..cb297885c5a9 --- /dev/null +++ b/.changeset/poor-falcons-doubt.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/livechat': patch +--- + +Fixes an issue where the unread message counter in the livechat widget does not update when a visitor receives their first response from an agent while the widget is minimized. diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts index 405e7f82e3c4..cf805ca233dd 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts @@ -58,7 +58,7 @@ test.describe.serial('OC - Livechat', () => { }); }); - test('OC - Livechat - Send message to livechat costumer', async () => { + test('OC - Livechat - Send message to livechat customer', async () => { await poHomeOmnichannel.sidenav.openChat(firstVisitor.name); await test.step('expect message to be sent by agent', async () => { @@ -76,9 +76,23 @@ test.describe.serial('OC - Livechat', () => { await expect(poLiveChat.unreadMessagesBadge(1)).toBeVisible(); }); + await test.step('expect multiple messages to be received by minimized livechat', async () => { + await poHomeOmnichannel.content.sendMessage('this_a_test_message_once_again_from_agent'); + await expect(poLiveChat.unreadMessagesBadge(2)).toBeVisible(); + }); + await test.step('expect unread messages to be visible after a reload', async () => { await poLiveChat.page.reload(); - await expect(poLiveChat.unreadMessagesBadge(1)).toBeVisible(); + await expect(poLiveChat.unreadMessagesBadge(2)).toBeVisible(); + }); + }); + + test('OC - Livechat - Send message to agent after reload', async () => { + await test.step('expect unread counter to be empty after user sends a message', async () => { + await poLiveChat.openAnyLiveChat(); + await poLiveChat.onlineAgentMessage.fill('this_a_test_message_from_user'); + await poLiveChat.btnSendMessageToOnlineAgent.click(); + expect(await poLiveChat.unreadMessagesBadge(0).all()).toHaveLength(0); }); }); diff --git a/packages/livechat/src/lib/main.js b/packages/livechat/src/lib/main.js index ad93dc184dd9..499cda913b95 100644 --- a/packages/livechat/src/lib/main.js +++ b/packages/livechat/src/lib/main.js @@ -90,41 +90,38 @@ export const getUnreadMessages = () => { const { messages, user, lastReadMessageId } = store.state; const renderedMessages = messages.filter((message) => canRenderMessage(message)); + const lastReadMessageIndex = lastReadMessageId ? renderedMessages.findIndex((item) => item._id === lastReadMessageId) - : renderedMessages - .slice() - .reverse() - .findIndex((item) => item.u._id === user?._id); - - if (lastReadMessageIndex !== -1) { - const unreadMessages = renderedMessages.slice(lastReadMessageIndex + 1).filter((message) => message.u._id !== user?._id); - - return unreadMessages; - } + : renderedMessages.findLastIndex((item) => item.u._id === user?._id); - return []; + if (lastReadMessageIndex === -1) return 0; + return renderedMessages.slice(lastReadMessageIndex + 1).filter((message) => message.u._id !== user?._id).length; }; export const processUnread = async () => { + const unreadMessages = getUnreadMessages(); + if (unreadMessages <= 0) { + await store.setState({ unread: 0 }); + return; + } + const shouldMarkUnread = shouldMarkAsUnread(); - if (shouldMarkUnread) { - const unreadMessages = getUnreadMessages(); - - if (unreadMessages.length > 0) { - const { alerts } = store.state; - const lastReadMessage = getLastReadMessage(); - const alertMessage = i18next.t('count_new_messages_since_since', { - count: unreadMessages.length, - val: new Date(lastReadMessage.ts), - formatParams: { - val: { month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric' }, - }, - }); - - const alert = { id: constants.unreadMessagesAlertId, children: alertMessage, success: true, timeout: 0 }; - const newAlerts = alerts.filter((item) => item.id !== constants.unreadMessagesAlertId); - await store.setState({ alerts: (newAlerts.push(alert), newAlerts), unread: unreadMessages.length }); - } + if (!shouldMarkUnread) { + return; } + + const { alerts } = store.state; + const lastReadMessage = getLastReadMessage(); + const alertMessage = i18next.t('count_new_messages_since_since', { + count: unreadMessages, + val: new Date(lastReadMessage.ts), + formatParams: { + val: { month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric' }, + }, + }); + const alert = { id: constants.unreadMessagesAlertId, children: alertMessage, success: true, timeout: 0 }; + const newAlerts = alerts.filter((item) => item.id !== constants.unreadMessagesAlertId); + + await store.setState({ alerts: (newAlerts.push(alert), newAlerts), unread: unreadMessages }); };