diff --git a/src/components/LHNOptionsList/OptionRowLHN.js b/src/components/LHNOptionsList/OptionRowLHN.js index 3cfd7c4c4138..5bfab8f57a67 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.js +++ b/src/components/LHNOptionsList/OptionRowLHN.js @@ -104,6 +104,11 @@ function OptionRowLHN(props) { const shouldShowGreenDotIndicator = !hasBrickError && (optionItem.isUnreadWithMention || optionItem.isWaitingForTaskCompleteFromAssignee || ReportUtils.isWaitingForIOUActionFromCurrentUser(optionItem)); + const fullTitle = + optionItem.type === CONST.REPORT.TYPE.CHAT && !optionItem.isArchivedRoom && lodashGet(optionItem, 'displayNamesWithTooltips.length', 0) > 1 + ? ReportUtils.getDisplayNamesStringFromTooltips(optionItem.displayNamesWithTooltips) + : optionItem.text; + /** * Show the ReportActionContextMenu modal popover. * @@ -206,7 +211,7 @@ function OptionRowLHN(props) { { - const accountID = Number(user.accountID); - const displayName = getDisplayNameForParticipant(accountID, isMultipleParticipantReport) || user.login || ''; - const avatar = UserUtils.getDefaultAvatar(accountID); - - let pronouns = user.pronouns; - if (pronouns && pronouns.startsWith(CONST.PRONOUNS.PREFIX)) { - const pronounTranslationKey = pronouns.replace(CONST.PRONOUNS.PREFIX, ''); - pronouns = Localize.translateLocal(`pronouns.${pronounTranslationKey}`); - } + return _.chain(personalDetailsList) + .map((user) => { + const accountID = Number(user.accountID); + const displayName = getDisplayNameForParticipant(accountID, isMultipleParticipantReport) || user.login || ''; + const avatar = UserUtils.getDefaultAvatar(accountID); + + let pronouns = user.pronouns; + if (pronouns && pronouns.startsWith(CONST.PRONOUNS.PREFIX)) { + const pronounTranslationKey = pronouns.replace(CONST.PRONOUNS.PREFIX, ''); + pronouns = Localize.translateLocal(`pronouns.${pronounTranslationKey}`); + } - return { - displayName, - avatar, - login: user.login || '', - accountID, - pronouns, - }; - }); + return { + displayName, + avatar, + login: user.login || '', + accountID, + pronouns, + }; + }) + .sort((first, second) => { + // First sort by displayName/login + const displayNameLoginOrder = first.displayName.localeCompare(second.displayName); + if (displayNameLoginOrder !== 0) { + return displayNameLoginOrder; + } + + // Then fallback on accountID as the final sorting criteria. + return first.accountID > second.accountID; + }) + .value(); +} + +/** + * Gets a joined string of display names from the list of display name with tooltip objects. + * + * @param {Object} displayNamesWithTooltips + * @returns {String} + */ +function getDisplayNamesStringFromTooltips(displayNamesWithTooltips) { + return _.filter( + _.map(displayNamesWithTooltips, ({displayName}) => displayName), + (displayName) => !_.isEmpty(displayName), + ).join(', '); } /** @@ -3721,6 +3746,7 @@ export { getIcons, getRoomWelcomeMessage, getDisplayNamesWithTooltips, + getDisplayNamesStringFromTooltips, getReportName, getReport, getReportIDFromLink, diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js index de3e202bf7a3..39aa42b0b3ab 100644 --- a/src/pages/home/HeaderView.js +++ b/src/pages/home/HeaderView.js @@ -79,7 +79,8 @@ function HeaderView(props) { const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(props.report); const isTaskReport = ReportUtils.isTaskReport(props.report); const reportHeaderData = !isTaskReport && !isChatThread && props.report.parentReportID ? props.parentReport : props.report; - const title = ReportUtils.getReportName(reportHeaderData); + // Use sorted display names for the title for group chats on native small screen widths + const title = isMultipleParticipant ? ReportUtils.getDisplayNamesStringFromTooltips(displayNamesWithTooltips) : ReportUtils.getReportName(reportHeaderData); const subtitle = ReportUtils.getChatRoomSubtitle(reportHeaderData); const parentNavigationSubtitleData = ReportUtils.getParentNavigationSubtitle(reportHeaderData); const isConcierge = ReportUtils.hasSingleParticipant(props.report) && _.contains(participants, CONST.ACCOUNT_ID.CONCIERGE); diff --git a/tests/unit/ReportUtilsTest.js b/tests/unit/ReportUtilsTest.js index 24397a04a0e9..f7f91a9d47a6 100644 --- a/tests/unit/ReportUtilsTest.js +++ b/tests/unit/ReportUtilsTest.js @@ -113,12 +113,12 @@ describe('ReportUtils', () => { test('withSingleParticipantReport', () => { expect(ReportUtils.getDisplayNamesWithTooltips(participantsPersonalDetails, false)).toStrictEqual([ { - displayName: 'Ragnar Lothbrok', - login: 'ragnar@vikings.net', + displayName: '(833) 240-3627', avatar: { - testUri: '../../../assets/images/avatars/user/default-avatar_2.svg', + testUri: '../../../assets/images/avatars/user/default-avatar_5.svg', }, - accountID: 1, + login: '+18332403627@expensify.sms', + accountID: 4, pronouns: undefined, }, { @@ -139,15 +139,6 @@ describe('ReportUtils', () => { accountID: 3, pronouns: 'She/her', }, - { - displayName: '(833) 240-3627', - avatar: { - testUri: '../../../assets/images/avatars/user/default-avatar_5.svg', - }, - login: '+18332403627@expensify.sms', - accountID: 4, - pronouns: undefined, - }, { displayName: 'Lagertha Lothbrok', avatar: { @@ -157,18 +148,27 @@ describe('ReportUtils', () => { accountID: 5, pronouns: 'She/her', }, + { + displayName: 'Ragnar Lothbrok', + login: 'ragnar@vikings.net', + avatar: { + testUri: '../../../assets/images/avatars/user/default-avatar_2.svg', + }, + accountID: 1, + pronouns: undefined, + }, ]); }); test('withMultiParticipantReport', () => { expect(ReportUtils.getDisplayNamesWithTooltips(participantsPersonalDetails, true)).toStrictEqual([ { - displayName: 'Ragnar', - login: 'ragnar@vikings.net', + displayName: '(833) 240-3627', avatar: { - testUri: '../../../assets/images/avatars/user/default-avatar_2.svg', + testUri: '../../../assets/images/avatars/user/default-avatar_5.svg', }, - accountID: 1, + login: '+18332403627@expensify.sms', + accountID: 4, pronouns: undefined, }, { @@ -189,15 +189,6 @@ describe('ReportUtils', () => { accountID: 3, pronouns: 'She/her', }, - { - displayName: '(833) 240-3627', - avatar: { - testUri: '../../../assets/images/avatars/user/default-avatar_5.svg', - }, - login: '+18332403627@expensify.sms', - accountID: 4, - pronouns: undefined, - }, { displayName: 'Lagertha', avatar: { @@ -207,6 +198,15 @@ describe('ReportUtils', () => { accountID: 5, pronouns: 'She/her', }, + { + displayName: 'Ragnar', + login: 'ragnar@vikings.net', + avatar: { + testUri: '../../../assets/images/avatars/user/default-avatar_2.svg', + }, + accountID: 1, + pronouns: undefined, + }, ]); }); }); diff --git a/tests/unit/SidebarFilterTest.js b/tests/unit/SidebarFilterTest.js index 18e499d89293..f5124c1cb4db 100644 --- a/tests/unit/SidebarFilterTest.js +++ b/tests/unit/SidebarFilterTest.js @@ -352,7 +352,7 @@ describe('Sidebar', () => { const navigatesToChatHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); expect(screen.queryAllByAccessibilityHint(navigatesToChatHintText)).toHaveLength(1); expect(displayNames).toHaveLength(1); - expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Four, Three'); } else { // Both reports visible const navigatesToChatHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); @@ -394,7 +394,7 @@ describe('Sidebar', () => { const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(2); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('One, Two'); - expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Four, Three'); }) // When report3 becomes unread @@ -463,7 +463,7 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(2); - expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Four, Three'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); }) ); @@ -678,7 +678,7 @@ describe('Sidebar', () => { const navigatesToChatHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); expect(screen.queryAllByAccessibilityHint(navigatesToChatHintText)).toHaveLength(1); expect(displayNames).toHaveLength(1); - expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Four, Three'); } else { // Both reports visible const navigatesToChatHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); diff --git a/tests/unit/SidebarOrderTest.js b/tests/unit/SidebarOrderTest.js index 4a693d679b86..bb826ae8f326 100644 --- a/tests/unit/SidebarOrderTest.js +++ b/tests/unit/SidebarOrderTest.js @@ -140,7 +140,7 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(3); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); - expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Four, Three'); expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('One, Two'); }) ); @@ -190,7 +190,7 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(3); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('One, Two'); // this has `hasDraft` flag enabled so it will be on top expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Five, Six'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Four, Three'); }) ); }); @@ -237,7 +237,7 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(3); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('One, Two'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Five, Six'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Four, Three'); }) ); }); @@ -289,7 +289,7 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); - expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Four, Three'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Five, Six'); expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('One, Two'); }) @@ -432,7 +432,7 @@ describe('Sidebar', () => { expect(screen.queryAllByTestId('Pencil Icon')).toHaveLength(1); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('One, Two'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Email Two owes $100.00'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Four, Three'); }) ); }); @@ -478,7 +478,7 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(3); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Four, Three'); }) // When a new report is added @@ -491,8 +491,8 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(4); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Seven, Eight'); - expect(lodashGet(displayNames, [3, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Eight, Seven'); + expect(lodashGet(displayNames, [3, 'props', 'children'])).toBe('Four, Three'); }) ); }); @@ -538,7 +538,7 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(3); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Four, Three'); }) // When a new report is added @@ -551,8 +551,8 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(4); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Seven, Eight'); - expect(lodashGet(displayNames, [3, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Eight, Seven'); + expect(lodashGet(displayNames, [3, 'props', 'children'])).toBe('Four, Three'); }) ); }); @@ -597,7 +597,7 @@ describe('Sidebar', () => { const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); - expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Four, Three'); expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Report (archived)'); }) ); @@ -635,7 +635,7 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(3); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Four, Three'); }) // When a new report is added @@ -648,8 +648,8 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(4); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Seven, Eight'); - expect(lodashGet(displayNames, [3, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Eight, Seven'); + expect(lodashGet(displayNames, [3, 'props', 'children'])).toBe('Four, Three'); }) ); }); @@ -689,7 +689,7 @@ describe('Sidebar', () => { const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); - expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('Four, Three'); expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Report (archived)'); }) ); @@ -866,7 +866,7 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(3); expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); - expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Three, Four'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Four, Three'); }) ); });