From 106a3294d05cd8e85c03b3bbd88c1bb15c4c82f3 Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Wed, 14 Dec 2022 19:49:01 +0530 Subject: [PATCH 1/7] [FIX] Unread Message count not displayed for new messages in Omni-Rooms --- apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js b/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js index d01717912f3b..2310d29b3430 100644 --- a/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js +++ b/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js @@ -1,6 +1,7 @@ import moment from 'moment'; import { escapeRegExp } from '@rocket.chat/string-helpers'; import { Subscriptions as SubscriptionsRaw } from '@rocket.chat/models'; +import { isOmnichannelRoom } from '@rocket.chat/core-typings'; import { Rooms, Subscriptions } from '../../../models/server'; import { settings } from '../../../settings/server'; @@ -106,7 +107,8 @@ export async function updateUsersSubscriptions(message, room) { } // this shouldn't run only if has group mentions because it will already exclude mentioned users from the query - if (!toAll && !toHere && unreadCount === 'all_messages') { + // and this should always run if it's a omnichannel room + if (!toAll && !toHere && (unreadCount === 'all_messages' || isOmnichannelRoom(room))) { await SubscriptionsRaw.incUnreadForRoomIdExcludingUserIds(room._id, [...userIds, message.u._id]); } } From 3d9cb52305e13faa8a459755d37fbcbd3c7c28bb Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Fri, 16 Dec 2022 18:58:14 +0530 Subject: [PATCH 2/7] Add tests to verify omnichannel unread messages count --- apps/meteor/tests/data/livechat/department.ts | 10 +++++-- apps/meteor/tests/data/subscriptions.ts | 15 +++++++++++ .../tests/end-to-end/api/livechat/00-rooms.ts | 27 +++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 apps/meteor/tests/data/subscriptions.ts diff --git a/apps/meteor/tests/data/livechat/department.ts b/apps/meteor/tests/data/livechat/department.ts index 8a04f4297b46..73000b97050a 100644 --- a/apps/meteor/tests/data/livechat/department.ts +++ b/apps/meteor/tests/data/livechat/department.ts @@ -57,7 +57,10 @@ new Promise((resolve, reject) => { }); }); -export const createDepartmentWithAnOnlineAgent = async (): Promise<{department: ILivechatDepartment, agent: IUser}> => { +export const createDepartmentWithAnOnlineAgent = async (): Promise<{department: ILivechatDepartment, agent: { + credentials: { 'X-Auth-Token': string; 'X-User-Id': string; }; + user: IUser; +}}> => { const agent: IUser = await createUser(); const createdUserCredentials = await login(agent.username, password); await createAgent(agent.username); @@ -69,7 +72,10 @@ export const createDepartmentWithAnOnlineAgent = async (): Promise<{department: return { department, - agent, + agent: { + credentials: createdUserCredentials, + user: agent, + } }; }; diff --git a/apps/meteor/tests/data/subscriptions.ts b/apps/meteor/tests/data/subscriptions.ts new file mode 100644 index 000000000000..9dcab2cae25d --- /dev/null +++ b/apps/meteor/tests/data/subscriptions.ts @@ -0,0 +1,15 @@ +import { ISubscription } from "@rocket.chat/core-typings"; +import { api, credentials, request } from "./api-data"; + +export const getSubscriptionForRoom = async (roomId: string, overrideCredential?: { 'X-Auth-Token': string; 'X-User-Id': string; }): Promise => { + const response = await request + .get(api('subscriptions.getOne')) + .set(overrideCredential || credentials) + .query({ roomId }) + .expect('Content-Type', 'application/json') + .expect(200); + + const { subscription } = response.body; + + return subscription; +} diff --git a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts index 7072a6a668a3..b94c56240e8f 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts @@ -25,6 +25,7 @@ import { createDepartmentWithAnOnlineAgent } from '../../../data/livechat/depart import { sleep } from '../../../data/livechat/utils'; import { IS_EE } from '../../../e2e/config/constants'; import { createCustomField } from '../../../data/livechat/custom-fields'; +import { getSubscriptionForRoom } from '../../../data/subscriptions'; describe('LIVECHAT - rooms', function () { this.retries(0); @@ -1446,4 +1447,30 @@ describe('LIVECHAT - rooms', function () { expect(response.body.filters.find((f: IOmnichannelRoom['source']) => f.type === 'api')).to.not.be.undefined; }); }); + + describe('it should mark room as unread when a new message is sent', () => { + let room: IOmnichannelRoom; + let visitor: ILivechatVisitor; + let totalMessagesSent = 2; + let departmentWithAgent: Awaited>; + + before(async () => { + await updateSetting('Livechat_Routing_Method', 'Auto_Selection'); + + departmentWithAgent = await createDepartmentWithAnOnlineAgent(); + visitor = await createVisitor(departmentWithAgent.department._id); + room = await createLivechatRoom(visitor.token); + + await sendMessage(room._id, 'message 1', visitor.token); + await sendMessage(room._id, 'message 2', visitor.token); + + // 1st message is for the room creation, so we need to add 1 to the total messages sent + totalMessagesSent = 3; + }); + + it("room's subscription should have correct unread count", async () => { + const { unread } = await getSubscriptionForRoom(room._id, departmentWithAgent.agent.credentials); + expect(unread).to.equal(totalMessagesSent); + }); + }); }); From 323aacd050e7147f5b286709ba8389803a46bacc Mon Sep 17 00:00:00 2001 From: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com> Date: Sun, 18 Dec 2022 11:43:52 +0530 Subject: [PATCH 3/7] Update apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts --- apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts index b94c56240e8f..45815fb23e0c 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts @@ -1451,7 +1451,7 @@ describe('LIVECHAT - rooms', function () { describe('it should mark room as unread when a new message is sent', () => { let room: IOmnichannelRoom; let visitor: ILivechatVisitor; - let totalMessagesSent = 2; + let totalMessagesSent = 0; let departmentWithAgent: Awaited>; before(async () => { From dabe7457d0fcecb65cae90fd52ad16cc816a854d Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Thu, 12 Jan 2023 11:36:20 +0530 Subject: [PATCH 4/7] Create a config to control omni-chat's unread behaviour --- .../lib/server/lib/notifyUsersOnMessage.js | 31 ++++++++++++++----- .../meteor/app/lib/server/startup/settings.ts | 14 +++++++++ .../rocketchat-i18n/i18n/en.i18n.json | 3 +- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js b/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js index 2310d29b3430..de4fc6c0c3b3 100644 --- a/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js +++ b/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js @@ -1,7 +1,6 @@ import moment from 'moment'; import { escapeRegExp } from '@rocket.chat/string-helpers'; import { Subscriptions as SubscriptionsRaw } from '@rocket.chat/models'; -import { isOmnichannelRoom } from '@rocket.chat/core-typings'; import { Rooms, Subscriptions } from '../../../models/server'; import { settings } from '../../../settings/server'; @@ -64,14 +63,14 @@ export function getMentions(message) { const incGroupMentions = (rid, roomType, excludeUserId, unreadCount) => { const incUnreadByGroup = ['all_messages', 'group_mentions_only', 'user_and_group_mentions_only'].includes(unreadCount); - const incUnread = roomType === 'd' || incUnreadByGroup ? 1 : 0; + const incUnread = roomType === 'd' || roomType === 'l' || incUnreadByGroup ? 1 : 0; Subscriptions.incGroupMentionsAndUnreadForRoomIdExcludingUserId(rid, excludeUserId, 1, incUnread); }; const incUserMentions = (rid, roomType, uids, unreadCount) => { const incUnreadByUser = ['all_messages', 'user_mentions_only', 'user_and_group_mentions_only'].includes(unreadCount); - const incUnread = roomType === 'd' || incUnreadByUser ? 1 : 0; + const incUnread = roomType === 'd' || roomType === 'l' || incUnreadByUser ? 1 : 0; Subscriptions.incUserMentionsAndUnreadForRoomIdAndUserIds(rid, uids, 1, incUnread); }; @@ -87,6 +86,26 @@ const getUserIdsFromHighlights = (rid, message) => { .map(({ u: { _id: uid } }) => uid); }; +/* + * {IRoom['t']} roomType - The type of the room + * @returns {string} - The setting value for unread count + */ +const getUnreadSettingCount = (roomType) => { + let unreadSetting = 'Unread_Count'; + switch (roomType) { + case 'd': { + unreadSetting = 'Unread_Count_DM'; + break; + } + case 'l': { + unreadSetting = 'Unread_Count_Omni'; + break; + } + } + + return settings.get(unreadSetting); +}; + export async function updateUsersSubscriptions(message, room) { // Don't increase unread counter on thread messages if (room != null && !message.tmid) { @@ -94,8 +113,7 @@ export async function updateUsersSubscriptions(message, room) { const userIds = new Set(mentionIds); - const unreadSetting = room.t === 'd' ? 'Unread_Count_DM' : 'Unread_Count'; - const unreadCount = settings.get(unreadSetting); + const unreadCount = getUnreadSettingCount(room.t); getUserIdsFromHighlights(room._id, message).forEach((uid) => userIds.add(uid)); @@ -107,8 +125,7 @@ export async function updateUsersSubscriptions(message, room) { } // this shouldn't run only if has group mentions because it will already exclude mentioned users from the query - // and this should always run if it's a omnichannel room - if (!toAll && !toHere && (unreadCount === 'all_messages' || isOmnichannelRoom(room))) { + if (!toAll && !toHere && unreadCount === 'all_messages') { await SubscriptionsRaw.incUnreadForRoomIdExcludingUserIds(room._id, [...userIds, message.u._id]); } } diff --git a/apps/meteor/app/lib/server/startup/settings.ts b/apps/meteor/app/lib/server/startup/settings.ts index 2a3b25cd9771..4e45541acdce 100644 --- a/apps/meteor/app/lib/server/startup/settings.ts +++ b/apps/meteor/app/lib/server/startup/settings.ts @@ -945,6 +945,20 @@ settingsRegistry.addGroup('General', function () { ], public: true, }); + this.add('Unread_Count_Omni', 'all_messages', { + type: 'select', + values: [ + { + key: 'all_messages', + i18nLabel: 'All_messages', + }, + { + key: 'mentions_only', + i18nLabel: 'Mentions_only', + }, + ], + public: true, + }); this.add('DeepLink_Url', 'https://go.rocket.chat', { type: 'string', diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index 692385d35b24..2c3a208d3a22 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -4928,6 +4928,7 @@ "Unread": "Unread", "Unread_Count": "Unread Count", "Unread_Count_DM": "Unread Count for Direct Messages", + "Unread_Count_Omni": "Unread Count for Omnichannel Chats", "Unread_Messages": "Unread Messages", "Unread_on_top": "Unread on top", "Unread_Rooms": "Unread Rooms", @@ -5551,4 +5552,4 @@ "Theme_dark": "Dark", "Join_your_team": "Join your team", "Create_an_account": "Create an account" -} \ No newline at end of file +} From d6d2397275fb0a62b92b1ba0e200bc2fb36de922 Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Thu, 12 Jan 2023 11:51:19 +0530 Subject: [PATCH 5/7] Update tests --- .../tests/end-to-end/api/livechat/00-rooms.ts | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts index 45815fb23e0c..4dd0176f9deb 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts @@ -1448,7 +1448,7 @@ describe('LIVECHAT - rooms', function () { }); }); - describe('it should mark room as unread when a new message is sent', () => { + describe('it should mark room as unread when a new message and the config is activated', () => { let room: IOmnichannelRoom; let visitor: ILivechatVisitor; let totalMessagesSent = 0; @@ -1456,7 +1456,10 @@ describe('LIVECHAT - rooms', function () { before(async () => { await updateSetting('Livechat_Routing_Method', 'Auto_Selection'); + await updateSetting('Unread_Count_Omni', 'all_messages'); + }); + it('it should prepare the required data for further tests', async () => { departmentWithAgent = await createDepartmentWithAnOnlineAgent(); visitor = await createVisitor(departmentWithAgent.department._id); room = await createLivechatRoom(visitor.token); @@ -1473,4 +1476,33 @@ describe('LIVECHAT - rooms', function () { expect(unread).to.equal(totalMessagesSent); }); }); + + describe('it should NOT mark room as unread when a new message and the config is deactivated', () => { + let room: IOmnichannelRoom; + let visitor: ILivechatVisitor; + let totalMessagesSent = 0; + let departmentWithAgent: Awaited>; + + before(async () => { + await updateSetting('Livechat_Routing_Method', 'Auto_Selection'); + await updateSetting('Unread_Count_Omni', 'mentions_only'); + }); + + it('it should prepare the required data for further tests', async () => { + departmentWithAgent = await createDepartmentWithAnOnlineAgent(); + visitor = await createVisitor(departmentWithAgent.department._id); + room = await createLivechatRoom(visitor.token); + + await sendMessage(room._id, 'message 1', visitor.token); + await sendMessage(room._id, 'message 2', visitor.token); + + // 1st message is for the room creation, so we need to add 1 to the total messages sent + totalMessagesSent = 1; + }); + + it("room's subscription should have correct unread count", async () => { + const { unread } = await getSubscriptionForRoom(room._id, departmentWithAgent.agent.credentials); + expect(unread).to.equal(totalMessagesSent); + }); + }); }); From 2425dea4b0eb917352fd1e167ed704bb928d1693 Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Thu, 12 Jan 2023 11:57:32 +0530 Subject: [PATCH 6/7] ... --- apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts index 4dd0176f9deb..db77192a4eea 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts @@ -1448,7 +1448,7 @@ describe('LIVECHAT - rooms', function () { }); }); - describe('it should mark room as unread when a new message and the config is activated', () => { + describe('it should mark room as unread when a new message arrives and the config is activated', () => { let room: IOmnichannelRoom; let visitor: ILivechatVisitor; let totalMessagesSent = 0; @@ -1477,7 +1477,7 @@ describe('LIVECHAT - rooms', function () { }); }); - describe('it should NOT mark room as unread when a new message and the config is deactivated', () => { + describe('it should NOT mark room as unread when a new message arrives and the config is deactivated', () => { let room: IOmnichannelRoom; let visitor: ILivechatVisitor; let totalMessagesSent = 0; From 4a9908288f4826e9feaaf90ed375b8ebe6e75796 Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Thu, 12 Jan 2023 12:07:11 +0530 Subject: [PATCH 7/7] make the builds happy --- apps/meteor/tests/data/subscriptions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/tests/data/subscriptions.ts b/apps/meteor/tests/data/subscriptions.ts index 9dcab2cae25d..04e0f48c98e4 100644 --- a/apps/meteor/tests/data/subscriptions.ts +++ b/apps/meteor/tests/data/subscriptions.ts @@ -1,4 +1,4 @@ -import { ISubscription } from "@rocket.chat/core-typings"; +import type { ISubscription } from "@rocket.chat/core-typings"; import { api, credentials, request } from "./api-data"; export const getSubscriptionForRoom = async (roomId: string, overrideCredential?: { 'X-Auth-Token': string; 'X-User-Id': string; }): Promise => {