diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 9f8e138afccd..22eb5834a1cd 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -3280,6 +3280,15 @@ function shouldHideReport(report, currentReportId) { return parentReport.reportID !== report.reportID && !isChildReportHasComment; } +/** + * @param {Object} report + * @returns {boolean} + */ +function isEmptyChat(report) { + const lastVisibleMessage = ReportActionsUtils.getLastVisibleMessage(report.reportID); + return !report.lastMessageText && !report.lastMessageTranslationKey && !lastVisibleMessage.lastMessageText && !lastVisibleMessage.lastMessageTranslationKey; +} + /** * Takes several pieces of data from Onyx and evaluates if a report should be shown in the option list (either when searching * for reports or the reports shown in the LHN). @@ -3335,8 +3344,7 @@ function shouldReportBeInOptionList(report, currentReportId, isInGSDMode, betas, if (report.hasDraft || requiresAttentionFromCurrentUser(report)) { return true; } - const lastVisibleMessage = ReportActionsUtils.getLastVisibleMessage(report.reportID); - const isEmptyChat = !report.lastMessageText && !report.lastMessageTranslationKey && !lastVisibleMessage.lastMessageText && !lastVisibleMessage.lastMessageTranslationKey; + const canHideReport = shouldHideReport(report, currentReportId); // Include reports if they are pinned @@ -3345,7 +3353,7 @@ function shouldReportBeInOptionList(report, currentReportId, isInGSDMode, betas, } // Hide only chat threads that haven't been commented on (other threads are actionable) - if (isChatThread(report) && canHideReport && isEmptyChat) { + if (isChatThread(report) && canHideReport && isEmptyChat(report)) { return false; } @@ -3355,6 +3363,11 @@ function shouldReportBeInOptionList(report, currentReportId, isInGSDMode, betas, return true; } + // Hide chats between users that haven't been commented on from the LNH + if (excludeEmptyChats && isEmptyChat(report) && isChatReport(report) && !isChatRoom(report) && !isPolicyExpenseChat(report) && canHideReport) { + return false; + } + // All unread chats (even archived ones) in GSD mode will be shown. This is because GSD mode is specifically for focusing the user on the most relevant chats, primarily, the unread ones if (isInGSDMode) { return isUnread(report); @@ -3365,11 +3378,6 @@ function shouldReportBeInOptionList(report, currentReportId, isInGSDMode, betas, return true; } - // Hide chats between two users that haven't been commented on from the LNH - if (excludeEmptyChats && isEmptyChat && isChatReport(report) && !isChatRoom(report) && !isPolicyExpenseChat(report) && canHideReport) { - return false; - } - return true; } @@ -4338,6 +4346,7 @@ export { shouldUseFullTitleToDisplay, parseReportRouteParams, getReimbursementQueuedActionMessage, + isEmptyChat, getPersonalDetailsForAccountID, getRoom, }; diff --git a/src/libs/UnreadIndicatorUpdater/index.js b/src/libs/UnreadIndicatorUpdater/index.js index 9af74f8313c3..be2edaaccbf3 100644 --- a/src/libs/UnreadIndicatorUpdater/index.js +++ b/src/libs/UnreadIndicatorUpdater/index.js @@ -9,7 +9,10 @@ Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT, waitForCollectionCallback: true, callback: (reportsFromOnyx) => { - const unreadReports = _.filter(reportsFromOnyx, (report) => ReportUtils.isUnread(report) && report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN); + const unreadReports = _.filter( + reportsFromOnyx, + (report) => ReportUtils.isUnread(report) && !ReportUtils.isEmptyChat(report) && report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, + ); updateUnread(_.size(unreadReports)); }, }); diff --git a/tests/unit/SidebarFilterTest.js b/tests/unit/SidebarFilterTest.js index 23a958e3aa9d..04307d751d7a 100644 --- a/tests/unit/SidebarFilterTest.js +++ b/tests/unit/SidebarFilterTest.js @@ -374,6 +374,10 @@ describe('Sidebar', () => { const report3 = LHNTestUtils.getFakeReport([5, 6]); LHNTestUtils.getDefaultRenderedSidebarLinks(report1.reportID); + const reportAction1 = LHNTestUtils.getFakeReportAction(); + const reportAction2 = LHNTestUtils.getFakeReportAction(); + const reportAction3 = LHNTestUtils.getFakeReportAction(); + return ( waitForBatchedUpdates() // When Onyx is updated to contain that data and the sidebar re-renders @@ -385,6 +389,9 @@ describe('Sidebar', () => { [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report1.reportID}`]: {[reportAction1.reportActionID]: reportAction1}, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report2.reportID}`]: {[reportAction2.reportActionID]: reportAction1}, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report3.reportID}`]: {[reportAction3.reportActionID]: reportAction1}, }), ) @@ -490,6 +497,10 @@ describe('Sidebar', () => { }; LHNTestUtils.getDefaultRenderedSidebarLinks(); + const archivedReportAction = LHNTestUtils.getFakeReportAction(); + const archivedPolicyRoomReportAction = LHNTestUtils.getFakeReportAction(); + const archivedUserCreatedPolicyRoomReportAction = LHNTestUtils.getFakeReportAction(); + const betas = [CONST.BETAS.DEFAULT_ROOMS, CONST.BETAS.POLICY_ROOMS]; return ( @@ -504,6 +515,11 @@ describe('Sidebar', () => { [`${ONYXKEYS.COLLECTION.REPORT}${archivedReport.reportID}`]: archivedReport, [`${ONYXKEYS.COLLECTION.REPORT}${archivedPolicyRoomReport.reportID}`]: archivedPolicyRoomReport, [`${ONYXKEYS.COLLECTION.REPORT}${archivedUserCreatedPolicyRoomReport.reportID}`]: archivedUserCreatedPolicyRoomReport, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${archivedReport.reportID}`]: {[archivedReportAction.reportActionID]: archivedReportAction}, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${archivedPolicyRoomReport.reportID}`]: {[archivedPolicyRoomReportAction.reportActionID]: archivedPolicyRoomReportAction}, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${archivedUserCreatedPolicyRoomReport.reportID}`]: { + [archivedUserCreatedPolicyRoomReportAction.reportActionID]: archivedUserCreatedPolicyRoomReportAction, + }, }), ) @@ -691,58 +707,6 @@ describe('Sidebar', () => { }); describe('Archived chat', () => { - describe('in default (most recent) mode', () => { - it('is shown regardless if it has comments or not', () => { - LHNTestUtils.getDefaultRenderedSidebarLinks(); - - // Given an archived report with no comments - const report = { - ...LHNTestUtils.getFakeReport(), - lastVisibleActionCreated: '2022-11-22 03:48:27.267', - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, - }; - - // Given the user is in all betas - const betas = [CONST.BETAS.DEFAULT_ROOMS, CONST.BETAS.POLICY_ROOMS]; - - return ( - waitForBatchedUpdates() - // When Onyx is updated to contain that data and the sidebar re-renders - .then(() => - Onyx.multiSet({ - [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, - [ONYXKEYS.BETAS]: betas, - [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.IS_LOADING_REPORT_DATA]: false, - [`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`]: report, - }), - ) - - // Then the report is rendered in the LHN - .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); - const optionRows = screen.queryAllByAccessibilityHint(hintText); - expect(optionRows).toHaveLength(1); - }) - - // When the report has comments - .then(() => - Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, { - lastVisibleActionCreated: DateUtils.getDBTime(), - }), - ) - - // Then the report is rendered in the LHN - .then(() => { - const hintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); - const optionRows = screen.queryAllByAccessibilityHint(hintText); - expect(optionRows).toHaveLength(1); - }) - ); - }); - }); - describe('in GSD (focus) mode', () => { it('is shown when it is unread', () => { LHNTestUtils.getDefaultRenderedSidebarLinks(); @@ -753,6 +717,7 @@ describe('Sidebar', () => { statusNum: CONST.REPORT.STATUS.CLOSED, stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, }; + const reportAction = LHNTestUtils.getFakeReportAction(); // Given the user is in all betas const betas = [CONST.BETAS.DEFAULT_ROOMS, CONST.BETAS.POLICY_ROOMS]; @@ -778,9 +743,13 @@ describe('Sidebar', () => { }) // When the report has a new comment and is now unread + .then(() => Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, {[reportAction.reportActionID]: reportAction})) .then(() => { jest.advanceTimersByTime(10); - return Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, {lastVisibleActionCreated: DateUtils.getDBTime()}); + return Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, { + lastVisibleActionCreated: DateUtils.getDBTime(), + lastMessageText: reportAction.message[0].text, + }); }) // Then the report is rendered in the LHN diff --git a/tests/unit/SidebarOrderTest.js b/tests/unit/SidebarOrderTest.js index e9caed9f3dc7..9e8462342318 100644 --- a/tests/unit/SidebarOrderTest.js +++ b/tests/unit/SidebarOrderTest.js @@ -613,6 +613,10 @@ describe('Sidebar', () => { const report3 = LHNTestUtils.getFakeReport([5, 6], 1, true); const report4 = LHNTestUtils.getFakeReport([7, 8], 0, true); + const reportAction1 = LHNTestUtils.getFakeReportAction(); + const reportAction2 = LHNTestUtils.getFakeReportAction(); + const reportAction3 = LHNTestUtils.getFakeReportAction(); + const reportAction4 = LHNTestUtils.getFakeReportAction(); return ( waitForBatchedUpdates() // Given the sidebar is rendered in #focus mode (hides read chats) @@ -625,6 +629,10 @@ describe('Sidebar', () => { [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report1.reportID}`]: {[reportAction1.reportActionID]: reportAction1}, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report2.reportID}`]: {[reportAction2.reportActionID]: reportAction2}, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report3.reportID}`]: {[reportAction3.reportActionID]: reportAction3}, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report4.reportID}`]: {[reportAction4.reportActionID]: reportAction4}, }), ) @@ -664,6 +672,9 @@ describe('Sidebar', () => { }; const report2 = LHNTestUtils.getFakeReport([3, 4], 2, true); const report3 = LHNTestUtils.getFakeReport([5, 6], 1, true); + const reportAction1 = LHNTestUtils.getFakeReportAction(); + const reportAction2 = LHNTestUtils.getFakeReportAction(); + const reportAction3 = LHNTestUtils.getFakeReportAction(); // Given the user is in all betas const betas = [CONST.BETAS.DEFAULT_ROOMS, CONST.BETAS.POLICY_ROOMS]; @@ -680,6 +691,9 @@ describe('Sidebar', () => { [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report1.reportID}`]: {[reportAction1.reportActionID]: reportAction1}, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report2.reportID}`]: {[reportAction2.reportActionID]: reportAction2}, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report3.reportID}`]: {[reportAction3.reportActionID]: reportAction3}, }), ) diff --git a/tests/utils/LHNTestUtils.js b/tests/utils/LHNTestUtils.js index 546853b8893b..106b9ec78846 100644 --- a/tests/utils/LHNTestUtils.js +++ b/tests/utils/LHNTestUtils.js @@ -130,7 +130,7 @@ function getFakeReportAction(actor = 'email1@test.com', millisecondsInThePast = actor, actorAccountID: 1, reportActionID: `${++lastFakeReportActionID}`, - actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, + actionName: CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT, shouldShow: true, timestamp, reportActionTimestamp: timestamp,