diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 57c91c0435dd..8ea88cd543cc 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -2925,6 +2925,7 @@ const CONST = { }, CONCIERGE_DISPLAY_NAME: 'Concierge', + HIDDEN_DISPLAY_NAME: 'Hidden', CONCIERGE_GREETING_ACTION_ID: 'concierge-greeting', INTEGRATION_ENTITY_MAP_TYPES: { diff --git a/src/components/ReportActionAvatars/useReportActionAvatars.ts b/src/components/ReportActionAvatars/useReportActionAvatars.ts index 9f9c7516facf..38642b6fa1ef 100644 --- a/src/components/ReportActionAvatars/useReportActionAvatars.ts +++ b/src/components/ReportActionAvatars/useReportActionAvatars.ts @@ -218,7 +218,7 @@ function useReportActionAvatars({ const accountID = reportPreviewSenderID || (actorAccountID ?? CONST.DEFAULT_NUMBER_ID); const {avatar, fallbackIcon, login} = personalDetails?.[delegatePersonalDetails ? delegatePersonalDetails.accountID : accountID] ?? {}; - const defaultDisplayName = getDisplayNameForParticipant({accountID, personalDetailsData: personalDetails, formatPhoneNumber, translate}) ?? ''; + const defaultDisplayName = getDisplayNameForParticipant({accountID, personalDetailsData: personalDetails, formatPhoneNumber, hiddenTranslation: translate('common.hidden')}) ?? ''; const invoiceReport = [iouReport, chatReport, reportChatReport].find((susReport) => isInvoiceReport(susReport) || susReport?.chatType === CONST.REPORT.TYPE.INVOICE); const isNestedInInvoiceReport = !!invoiceReport && !isChatThread(report); const isInvoiceReportActor = isAInvoiceReport && (!actorAccountID || displayAllActors || isAReportPreviewAction); diff --git a/src/components/ReportActionItem/MoneyRequestReportPreview/usePreviewMessageAnimation.ts b/src/components/ReportActionItem/MoneyRequestReportPreview/usePreviewMessageAnimation.ts index 6d58d8a3fec4..fc5e1e24ea21 100644 --- a/src/components/ReportActionItem/MoneyRequestReportPreview/usePreviewMessageAnimation.ts +++ b/src/components/ReportActionItem/MoneyRequestReportPreview/usePreviewMessageAnimation.ts @@ -128,7 +128,7 @@ function usePreviewMessageAnimation({ accountID: managerID, shouldUseShortForm: true, formatPhoneNumber, - translate, + hiddenTranslation: translate('common.hidden'), }); } @@ -144,7 +144,7 @@ function usePreviewMessageAnimation({ accountID: chatReport?.ownerAccountID, shouldUseShortForm: true, formatPhoneNumber, - translate, + hiddenTranslation: translate('common.hidden'), }); } return translate(paymentVerb, payerOrApproverName); diff --git a/src/components/ReportActionItem/TaskView.tsx b/src/components/ReportActionItem/TaskView.tsx index 107284190694..0dba7c1cd4d5 100644 --- a/src/components/ReportActionItem/TaskView.tsx +++ b/src/components/ReportActionItem/TaskView.tsx @@ -273,7 +273,7 @@ function TaskView({report, parentReport, action}: TaskViewProps) { {report?.managerID ? ( ({ return getDisplayNameForParticipant({ accountID: item.accountID ?? CONST.DEFAULT_NUMBER_ID, formatPhoneNumber, - translate, + hiddenTranslation: translate('common.hidden'), }); }, [formatPhoneNumber, item.accountID, translate]); diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 90e7398dd528..8ce067caea0b 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -65,7 +65,7 @@ function buildNextStepMessage( formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], ): string { // Escape actor name to prevent HTML injection since this will be rendered as HTML - const actor = Str.safeEscape(getDisplayNameForParticipant({accountID: nextStep.actorAccountID, formatPhoneNumber, translate}) ?? ''); + const actor = Str.safeEscape(getDisplayNameForParticipant({accountID: nextStep.actorAccountID, formatPhoneNumber, hiddenTranslation: translate('common.hidden')}) ?? ''); let actorType: ValueOf; if (nextStep.actorAccountID === currentUserAccountID) { actorType = CONST.NEXT_STEP.ACTOR_TYPE.CURRENT_USER; diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index 33a557b3ebdf..9ded8fd59b33 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -1211,6 +1211,10 @@ function createOption({ let reportName; result.participantsList = personalDetailList; + // Resolve display-name translations once per option, then pass the strings to getDisplayNameForParticipant. + const hiddenText = translateFn('common.hidden'); + const youText = translateFn('common.you').toLowerCase(); + if (report) { result.private_isArchived = privateIsArchived; result.keyForList = String(report.reportID); @@ -1271,12 +1275,13 @@ function createOption({ shouldAddCurrentUserPostfix: true, personalDetailsData: personalDetails ?? undefined, formatPhoneNumber: formatPhoneNumberPhoneUtils, - translate: translateFn, + hiddenTranslation: hiddenText, + youTranslation: youText, }) : ''); reportName = showPersonalDetails - ? getDisplayNameForParticipant({accountID: accountIDs.at(0), formatPhoneNumber: formatPhoneNumberPhoneUtils, translate: translateFn}) || + ? getDisplayNameForParticipant({accountID: accountIDs.at(0), formatPhoneNumber: formatPhoneNumberPhoneUtils, hiddenTranslation: hiddenText}) || formatPhoneNumberPhoneUtils(personalDetail?.login ?? '') : computedReportName; } else { @@ -1285,7 +1290,7 @@ function createOption({ accountID: accountIDs.at(0), personalDetailsData: personalDetails ?? undefined, formatPhoneNumber: formatPhoneNumberPhoneUtils, - translate: translateFn, + hiddenTranslation: hiddenText, }) || formatPhoneNumberPhoneUtils(personalDetail?.login ?? ''); result.keyForList = String(accountIDs.at(0)); diff --git a/src/libs/PersonalDetailOptionsListUtils/index.ts b/src/libs/PersonalDetailOptionsListUtils/index.ts index 109bfdee7331..71b3d2bf4cea 100644 --- a/src/libs/PersonalDetailOptionsListUtils/index.ts +++ b/src/libs/PersonalDetailOptionsListUtils/index.ts @@ -78,7 +78,7 @@ function createOption( accountID: personalDetail.accountID, formatPhoneNumber, personalDetailsData: {[personalDetail.accountID]: personalDetail}, - translate, + hiddenTranslation: translate?.('common.hidden'), }) || formatPhoneNumber(personalDetail.login ?? ''); result.icons = [ { diff --git a/src/libs/PersonalDetailsUtils.ts b/src/libs/PersonalDetailsUtils.ts index 71709d6292b3..38e241d7f02c 100644 --- a/src/libs/PersonalDetailsUtils.ts +++ b/src/libs/PersonalDetailsUtils.ts @@ -15,7 +15,6 @@ import {Str} from 'expensify-common'; import Onyx from 'react-native-onyx'; import {getCountryCode} from './CountryUtils'; -import {translateLocal} from './Localize'; import {areEmailsFromSamePrivateDomain} from './LoginUtils'; import {addSMSDomainIfPhoneNumber, parsePhoneNumber} from './PhoneNumber'; import {getDefaultAvatarURL} from './UserAvatarUtils'; @@ -44,76 +43,15 @@ Onyx.connect({ }, }); -let hiddenTranslation = ''; -let youTranslation = ''; - -Onyx.connect({ - key: ONYXKEYS.RAM_ONLY_ARE_TRANSLATIONS_LOADING, - callback: (value) => { - if (value ?? true) { - return; - } - hiddenTranslation = translateLocal('common.hidden'); - youTranslation = translateLocal('common.you').toLowerCase(); - }, -}); - const regexMergedAccount = new RegExp(CONST.REGEX.MERGED_ACCOUNT_PREFIX); -function getDisplayNameOrDefault( - passedPersonalDetails?: Partial | null, - defaultValue = '', - shouldFallbackToHidden = true, - shouldAddCurrentUserPostfix = false, - youAfterTranslation = youTranslation, -): string { - let displayName = passedPersonalDetails?.displayName ?? ''; - - let login = passedPersonalDetails?.login ?? ''; - - // If the displayName starts with the merged account prefix, remove it. - if (regexMergedAccount.test(displayName)) { - // Remove the merged account prefix from the displayName. - displayName = displayName.replaceAll(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''); - } - - // If the displayName is not set by the user, the backend sets the displayName same as the login so - // we need to remove the sms domain from the displayName if it is an sms login. - if (Str.isSMSLogin(login)) { - if (displayName === login) { - displayName = Str.removeSMSDomain(displayName); - } - login = Str.removeSMSDomain(login); - } - - if (shouldAddCurrentUserPostfix && !!displayName) { - displayName = `${displayName} (${youAfterTranslation})`; - } - - if (passedPersonalDetails?.accountID === CONST.ACCOUNT_ID.CONCIERGE) { - displayName = CONST.CONCIERGE_DISPLAY_NAME; - } - - if (displayName) { - return displayName; - } - - if (defaultValue) { - return defaultValue; - } - - if (login) { - return login; - } - return shouldFallbackToHidden ? hiddenTranslation : ''; -} - function temporaryGetDisplayNameOrDefault({ passedPersonalDetails, defaultValue = '', shouldFallbackToHidden = true, shouldAddCurrentUserPostfix = false, youAfterTranslation, + hiddenAfterTranslation, translate, formatPhoneNumber, }: { @@ -122,11 +60,12 @@ function temporaryGetDisplayNameOrDefault({ shouldFallbackToHidden?: boolean; shouldAddCurrentUserPostfix?: boolean; youAfterTranslation?: string; - translate: LocalizedTranslate; + hiddenAfterTranslation?: string; + translate?: LocalizedTranslate; formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; }): string { - const temporaryHiddenTranslation = translate('common.hidden'); - const temporaryYouTranslation = translate('common.you').toLowerCase(); + const temporaryHiddenTranslation = hiddenAfterTranslation ?? translate?.('common.hidden') ?? ''; + const temporaryYouTranslation = translate?.('common.you').toLowerCase(); let displayName = passedPersonalDetails?.displayName ?? ''; const login = passedPersonalDetails?.login ?? ''; @@ -577,7 +516,6 @@ function areTravelPersonalDetailsMissing(privatePersonalDetails: OnyxEntry participant.name) @@ -247,7 +247,7 @@ const buildReportNameFromParticipantNames = ({ accountID, personalDetailsData, formatPhoneNumber: formatPhoneNumberPhoneUtils, - translate, + hiddenTranslation: translate('common.hidden'), }); } return formattedNames ? `${formattedNames}, ${name}` : name; @@ -293,10 +293,12 @@ function getGroupChatName( const isMultipleParticipantReport = participantAccountIDs.length > 1; if (isMultipleParticipantReport) { + // Resolve the translation once, not per participant. + const hiddenText = translate('common.hidden'); return participantAccountIDs .map( (participantAccountID, index) => - getDisplayNameForParticipant({accountID: participantAccountID, shouldUseShortForm: isMultipleParticipantReport, formatPhoneNumber, translate}) || + getDisplayNameForParticipant({accountID: participantAccountID, shouldUseShortForm: isMultipleParticipantReport, formatPhoneNumber, hiddenTranslation: hiddenText}) || formatPhoneNumber(participants?.[index]?.login ?? ''), ) .sort((first, second) => customCollator.compare(first ?? '', second ?? '')) @@ -305,7 +307,7 @@ function getGroupChatName( .slice(0, CONST.REPORT_NAME_LIMIT) .concat(shouldAddEllipsis ? '...' : ''); } - return translate('groupChat.defaultReportName', getDisplayNameForParticipant({accountID: participantAccountIDs.at(0), formatPhoneNumber, translate})); + return translate('groupChat.defaultReportName', getDisplayNameForParticipant({accountID: participantAccountIDs.at(0), formatPhoneNumber, hiddenTranslation: translate('common.hidden')})); } /** @@ -324,7 +326,9 @@ function getPolicyExpenseChatName({ const personalDetails = ownerAccountID ? personalDetailsList?.[ownerAccountID] : undefined; const login = personalDetails ? personalDetails.login : null; - const reportOwnerDisplayName = getDisplayNameForParticipant({accountID: ownerAccountID, shouldRemoveDomain: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) || login; + const reportOwnerDisplayName = + getDisplayNameForParticipant({accountID: ownerAccountID, shouldRemoveDomain: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, hiddenTranslation: translate('common.hidden')}) || + login; if (reportOwnerDisplayName) { return translate('workspace.common.policyExpenseChatName', reportOwnerDisplayName); @@ -453,7 +457,8 @@ function getMoneyRequestReportName({ const invoiceReceiverPersonalDetail = getInvoiceReceiverPersonalDetail(chatReport, personalDetailsList); payerOrApproverName = getInvoicePayerName(chatReport, translate, invoiceReceiverPersonalDetail, invoiceReceiverPolicy); } else { - payerOrApproverName = getDisplayNameForParticipant({accountID: report?.managerID, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) ?? ''; + payerOrApproverName = + getDisplayNameForParticipant({accountID: report?.managerID, formatPhoneNumber: formatPhoneNumberPhoneUtils, hiddenTranslation: translate('common.hidden')}) ?? ''; } const payerPaidAmountMessage = translate('iou.payerPaidAmount', formattedAmount, payerOrApproverName); @@ -466,7 +471,8 @@ function getMoneyRequestReportName({ } if (!isSettled(report?.reportID) && hasNonReimbursableTransactions(linkedTransactions)) { - payerOrApproverName = getDisplayNameForParticipant({accountID: report?.ownerAccountID, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) ?? ''; + payerOrApproverName = + getDisplayNameForParticipant({accountID: report?.ownerAccountID, formatPhoneNumber: formatPhoneNumberPhoneUtils, hiddenTranslation: translate('common.hidden')}) ?? ''; return translate('iou.payerSpentAmount', formattedAmount, payerOrApproverName); } @@ -1185,7 +1191,8 @@ function computeReportName({ shouldAddCurrentUserPostfix: true, personalDetailsData: personalDetailsList, formatPhoneNumber: formatPhoneNumberPhoneUtils, - translate, + hiddenTranslation: translate('common.hidden'), + youTranslation: translate('common.you').toLowerCase(), }); } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 37bf4a9d4674..3ef2231f8de9 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -146,7 +146,7 @@ import Parser from './Parser'; import {getParsedMessageWithShortMentions} from './ParsingUtils'; import {getBankAccountLastFourDigits} from './PaymentUtils'; import Permissions from './Permissions'; -import {getAccountIDsByLogins, getDisplayNameOrDefault, getLoginByAccountID, getPersonalDetailByEmail, temporaryGetDisplayNameOrDefault} from './PersonalDetailsUtils'; +import {getAccountIDsByLogins, getLoginByAccountID, getPersonalDetailByEmail, temporaryGetDisplayNameOrDefault} from './PersonalDetailsUtils'; import { canSendInvoiceFromWorkspace, getActivePolicies, @@ -3564,7 +3564,8 @@ function getDisplayNameForParticipant({ personalDetailsData = allPersonalDetails, shouldRemoveDomain = false, formatPhoneNumber, - translate, + hiddenTranslation: hiddenTranslationOverride, + youTranslation, }: { accountID?: number; shouldUseShortForm?: boolean; @@ -3573,7 +3574,14 @@ function getDisplayNameForParticipant({ personalDetailsData?: Partial; shouldRemoveDomain?: boolean; formatPhoneNumber: LocaleContextProps['formatPhoneNumber']; - translate?: LocalizedTranslate; + /** + * Pre-resolved "Hidden" string, passed instead of a `translate` fn. Callers resolve it once (e.g. `translate('common.hidden')`, + * hoisted out of loops) and pass the value; English-only persisted messages pass the English literal. Defaults to the cached + * module value when omitted. Mirrors `getPolicyName`'s `unavailableTranslation`. + */ + hiddenTranslation?: string; + /** Pre-resolved lowercase "you" string for the `shouldAddCurrentUserPostfix` "(you)" suffix. */ + youTranslation?: string; }): string { if (!accountID) { return ''; @@ -3606,23 +3614,24 @@ function getDisplayNameForParticipant({ // For selfDM, we display the user's displayName followed by '(you)' as a postfix const shouldAddPostfix = shouldAddCurrentUserPostfix && accountID === deprecatedCurrentUserAccountID; - let longName = translate - ? temporaryGetDisplayNameOrDefault({ - passedPersonalDetails: personalDetails, - defaultValue: formattedLogin, - shouldFallbackToHidden, - shouldAddCurrentUserPostfix: shouldAddPostfix, - translate, - formatPhoneNumber, - }) - : getDisplayNameOrDefault(personalDetails, formattedLogin, shouldFallbackToHidden, shouldAddPostfix); + // Resolve the "Hidden" fallback once from the passed string (or the cached module value), never via a per-call `translate`. + const resolvedHiddenTranslation = hiddenTranslationOverride ?? hiddenTranslation; + let longName = temporaryGetDisplayNameOrDefault({ + passedPersonalDetails: personalDetails, + defaultValue: formattedLogin, + shouldFallbackToHidden, + shouldAddCurrentUserPostfix: shouldAddPostfix, + youAfterTranslation: youTranslation, + hiddenAfterTranslation: resolvedHiddenTranslation, + formatPhoneNumber, + }); if (shouldRemoveDomain && longName === formattedLogin) { longName = longName.split('@').at(0) ?? ''; } // If the user's personal details (first name) should be hidden, make sure we return "hidden" instead of the short name - if (shouldFallbackToHidden && longName === (translate ? translate('common.hidden') : hiddenTranslation)) { + if (shouldFallbackToHidden && longName === resolvedHiddenTranslation) { return longName; } @@ -4165,12 +4174,24 @@ function getDisplayNamesWithTooltips( ): DisplayNameWithTooltips { const personalDetailsListArray = Array.isArray(personalDetailsList) ? personalDetailsList : Object.values(personalDetailsList); + // Resolve translations once, not per participant, then pass the strings down. + const hiddenText = translate('common.hidden'); + const youText = translate('common.you').toLowerCase(); + return personalDetailsListArray .map((user) => { const accountID = Number(user?.accountID); const displayName = - getDisplayNameForParticipant({accountID, shouldUseShortForm, shouldFallbackToHidden, shouldAddCurrentUserPostfix, formatPhoneNumber, translate}) || + getDisplayNameForParticipant({ + accountID, + shouldUseShortForm, + shouldFallbackToHidden, + shouldAddCurrentUserPostfix, + formatPhoneNumber, + hiddenTranslation: hiddenText, + youTranslation: youText, + }) || // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing user?.login || ''; @@ -4206,7 +4227,7 @@ function getDisplayNamesWithTooltips( * Returns the the display names of the given user accountIDs */ function getUserDetailTooltipText(accountID: number, formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], translate: LocalizedTranslate, fallbackUserDisplayName = ''): string { - const displayNameForParticipant = getDisplayNameForParticipant({accountID, formatPhoneNumber, translate}); + const displayNameForParticipant = getDisplayNameForParticipant({accountID, formatPhoneNumber, hiddenTranslation: translate('common.hidden')}); return displayNameForParticipant || fallbackUserDisplayName; } @@ -4250,7 +4271,7 @@ function getReimbursementQueuedActionMessage({ shouldUseShortForm: shouldUseShortDisplayName, personalDetailsData: personalDetails, formatPhoneNumber, - translate, + hiddenTranslation: translate('common.hidden'), }) ?? ''; const originalMessage = getOriginalMessage(reportAction); let messageKey: TranslationPaths; @@ -4278,7 +4299,13 @@ function getReimbursementDeQueuedOrCanceledActionMessage( if (originalMessage?.cancellationReason === CONST.REPORT.CANCEL_PAYMENT_REASONS.ADMIN || originalMessage?.cancellationReason === CONST.REPORT.CANCEL_PAYMENT_REASONS.USER) { return translate('iou.adminCanceledRequest'); } - const submitterDisplayName = getDisplayNameForParticipant({accountID: reportOwnerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) ?? ''; + const submitterDisplayName = + getDisplayNameForParticipant({ + accountID: reportOwnerAccountID, + shouldUseShortForm: true, + formatPhoneNumber: formatPhoneNumberPhoneUtils, + hiddenTranslation: translate('common.hidden'), + }) ?? ''; return translate('iou.canceledRequest', formattedAmount, submitterDisplayName); } @@ -5841,7 +5868,12 @@ function getReportPreviewMessage( const policyName = getPolicyName({report: parentReport ?? report, policy, unavailableTranslation: translate('workspace.common.unavailable')}); const payerName = isExpenseReport(report) ? policyName - : getDisplayNameForParticipant({accountID: report.managerID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}); + : getDisplayNameForParticipant({ + accountID: report.managerID, + shouldUseShortForm: !isPreviewMessageForParentChatReport, + formatPhoneNumber: formatPhoneNumberPhoneUtils, + hiddenTranslation: translate('common.hidden'), + }); const formattedAmount = convertToDisplayString(totalAmount, report.currency); @@ -5898,7 +5930,12 @@ function getReportPreviewMessage( let actualPayerName = report.managerID === deprecatedCurrentUserAccountID && !isForListPreview ? '' - : getDisplayNameForParticipant({accountID: payerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}); + : getDisplayNameForParticipant({ + accountID: payerAccountID, + shouldUseShortForm: true, + formatPhoneNumber: formatPhoneNumberPhoneUtils, + hiddenTranslation: translate('common.hidden'), + }); actualPayerName = actualPayerName && isForListPreview && !isPreviewMessageForParentChatReport ? `${actualPayerName}:` : actualPayerName; const payerDisplayName = isPreviewMessageForParentChatReport ? payerName : actualPayerName; @@ -5923,7 +5960,12 @@ function getReportPreviewMessage( if (report.isWaitingOnBankAccount) { const submitterDisplayName = - getDisplayNameForParticipant({accountID: report.ownerAccountID, shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) ?? ''; + getDisplayNameForParticipant({ + accountID: report.ownerAccountID, + shouldUseShortForm: true, + formatPhoneNumber: formatPhoneNumberPhoneUtils, + hiddenTranslation: translate('common.hidden'), + }) ?? ''; return translate('iou.waitingOnBankAccount', submitterDisplayName); } @@ -5952,7 +5994,12 @@ function getReportPreviewMessage( // We only want to show the actor name in the preview if it's not the current user who took the action const requestorName = lastActorID && lastActorID !== deprecatedCurrentUserAccountID - ? getDisplayNameForParticipant({accountID: lastActorID, shouldUseShortForm: !isPreviewMessageForParentChatReport, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) + ? getDisplayNameForParticipant({ + accountID: lastActorID, + shouldUseShortForm: !isPreviewMessageForParentChatReport, + formatPhoneNumber: formatPhoneNumberPhoneUtils, + hiddenTranslation: translate('common.hidden'), + }) : ''; return `${requestorName ? `${requestorName}: ` : ''}${translate('iou.expenseAmount', amountToDisplay, comment)}`; } @@ -5961,7 +6008,7 @@ function getReportPreviewMessage( return translate( 'iou.payerSpentAmount', formattedAmount, - getDisplayNameForParticipant({accountID: report.ownerAccountID, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) ?? '', + getDisplayNameForParticipant({accountID: report.ownerAccountID, formatPhoneNumber: formatPhoneNumberPhoneUtils, hiddenTranslation: translate('common.hidden')}) ?? '', ); } return translate('iou.payerOwesAmount', formattedAmount, payerName ?? '', comment); @@ -6316,7 +6363,12 @@ function getPayeeName(report: OnyxEntry, translate: LocalizedTranslate): if (participantsWithoutCurrentUser.length === 0) { return undefined; } - return getDisplayNameForParticipant({accountID: participantsWithoutCurrentUser.at(0), shouldUseShortForm: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}); + return getDisplayNameForParticipant({ + accountID: participantsWithoutCurrentUser.at(0), + shouldUseShortForm: true, + formatPhoneNumber: formatPhoneNumberPhoneUtils, + hiddenTranslation: translate('common.hidden'), + }); } // TODO: currentUserEmail will be required eventually so this becomes a pure function. Subscribe the data via useOnyx and pass it from the component. Refactor issue: https://github.com/Expensify/App/issues/66412 @@ -6436,7 +6488,12 @@ function getParentNavigationSubtitle( const login = personalDetails ? personalDetails.login : null; const reportOwnerDisplayName = - getDisplayNameForParticipant({accountID: ownerAccountID, shouldRemoveDomain: true, formatPhoneNumber: formatPhoneNumberPhoneUtils, translate}) || login; + getDisplayNameForParticipant({ + accountID: ownerAccountID, + shouldRemoveDomain: true, + formatPhoneNumber: formatPhoneNumberPhoneUtils, + hiddenTranslation: translate('common.hidden'), + }) || login; if (isExpenseReport(report)) { return { @@ -8800,7 +8857,7 @@ function buildOptimisticChangedTaskAssigneeReportAction( message: [ { type: CONST.REPORT.MESSAGE.TYPE.COMMENT, - text: `assigned to ${getDisplayNameForParticipant({accountID: assigneeAccountID, formatPhoneNumber})}`, + text: `assigned to ${getDisplayNameForParticipant({accountID: assigneeAccountID, formatPhoneNumber, hiddenTranslation: CONST.HIDDEN_DISPLAY_NAME})}`, html: `assigned to `, }, ], @@ -8944,7 +9001,7 @@ function buildOptimisticChangeApproverReportAction( message: [ { type: CONST.REPORT.MESSAGE.TYPE.COMMENT, - text: `changed the approver to ${getDisplayNameForParticipant({accountID: managerID, formatPhoneNumber})}`, + text: `changed the approver to ${getDisplayNameForParticipant({accountID: managerID, formatPhoneNumber, hiddenTranslation: CONST.HIDDEN_DISPLAY_NAME})}`, html: `changed the approver to `, }, ], @@ -10688,8 +10745,10 @@ function getWhisperDisplayNames(translate: LocalizedTranslate, formatPhoneNumber return translate('common.youAfterPreposition'); } + // Resolve the translation once, not per participant. + const hiddenText = translate('common.hidden'); return participantAccountIDs - ?.map((accountID) => getDisplayNameForParticipant({accountID, shouldUseShortForm: !isWhisperOnlyVisibleToCurrentUser, formatPhoneNumber, translate})) + ?.map((accountID) => getDisplayNameForParticipant({accountID, shouldUseShortForm: !isWhisperOnlyVisibleToCurrentUser, formatPhoneNumber, hiddenTranslation: hiddenText})) .join(', '); } diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 3993e4de416b..279bf292d906 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -1487,7 +1487,7 @@ function getWelcomeMessage(params: WelcomeMessageParams): WelcomeMessage { welcomeMessage.messageHtml = translate( 'reportActionsView.beginningOfChatHistoryPolicyExpenseChat', getPolicyName({report, policy, unavailableTranslation: translate('workspace.common.unavailable')}), - getDisplayNameForParticipant({accountID: report?.ownerAccountID, formatPhoneNumber, translate}), + getDisplayNameForParticipant({accountID: report?.ownerAccountID, formatPhoneNumber, hiddenTranslation: translate('common.hidden')}), ); welcomeMessage.messageText = Parser.htmlToText(welcomeMessage.messageHtml); } @@ -1571,7 +1571,7 @@ function getRoomWelcomeMessage({ } else if (isInvoiceRoom(report)) { const payer = report?.invoiceReceiver?.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.INDIVIDUAL - ? getDisplayNameForParticipant({accountID: report?.invoiceReceiver?.accountID, formatPhoneNumber, translate}) + ? getDisplayNameForParticipant({accountID: report?.invoiceReceiver?.accountID, formatPhoneNumber, hiddenTranslation: translate('common.hidden')}) : invoiceReceiverPolicy?.name; const receiver = getPolicyName({report, unavailableTranslation: translate('workspace.common.unavailable')}); welcomeMessage.messageHtml = translate('reportActionsView.beginningOfChatHistoryInvoiceRoom', payer ?? '', receiver); diff --git a/src/libs/SuggestionUtils.ts b/src/libs/SuggestionUtils.ts index 28636f7be71b..b5b6f75f55c1 100644 --- a/src/libs/SuggestionUtils.ts +++ b/src/libs/SuggestionUtils.ts @@ -11,8 +11,8 @@ function trimLeadingSpace(str: string): string { return str.startsWith(' ') ? str.slice(1) : str; } -function getDisplayName(details: PersonalDetails, formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], translate: LocaleContextProps['translate']) { - const displayNameFromAccountID = getDisplayNameForParticipant({accountID: details.accountID, formatPhoneNumber, translate}); +function getDisplayName(details: PersonalDetails, formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], hiddenTranslation: string) { + const displayNameFromAccountID = getDisplayNameForParticipant({accountID: details.accountID, formatPhoneNumber, hiddenTranslation}); if (!displayNameFromAccountID) { return details.login?.length ? details.login : ''; } @@ -28,12 +28,14 @@ function getSortedPersonalDetails( formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], translate: LocaleContextProps['translate'], ) { + // Resolve the translation once, not per comparison. + const hiddenText = translate('common.hidden'); return personalDetails.sort((first, second) => { if (first.weight !== second.weight) { return first.weight - second.weight; } - const displayNameLoginOrder = localeCompare(getDisplayName(first, formatPhoneNumber, translate), getDisplayName(second, formatPhoneNumber, translate)); + const displayNameLoginOrder = localeCompare(getDisplayName(first, formatPhoneNumber, hiddenText), getDisplayName(second, formatPhoneNumber, hiddenText)); if (displayNameLoginOrder !== 0) { return displayNameLoginOrder; } diff --git a/src/pages/ReportAddApproverPage.tsx b/src/pages/ReportAddApproverPage.tsx index c9a5c947c3b0..75d03b9f1863 100644 --- a/src/pages/ReportAddApproverPage.tsx +++ b/src/pages/ReportAddApproverPage.tsx @@ -62,6 +62,8 @@ function ReportAddApproverPage({report, isLoadingReportData, policy}: ReportAddA } const policyMemberEmailsToAccountIDs = getMemberAccountIDsForWorkspace(employeeList, true, false); + // Resolve the translation once, not per member. + const hiddenText = translate('common.hidden'); return Object.values(employeeList) .map((employee): SelectionListApprover | null => { const isAdmin = employee?.role === CONST.REPORT.ROLE.ADMIN; @@ -79,7 +81,7 @@ function ReportAddApproverPage({report, isLoadingReportData, policy}: ReportAddA } const {avatar} = personalDetails?.[accountID] ?? {}; - const displayName = getDisplayNameForParticipant({accountID, personalDetailsData: personalDetails, formatPhoneNumber, translate}); + const displayName = getDisplayNameForParticipant({accountID, personalDetailsData: personalDetails, formatPhoneNumber, hiddenTranslation: hiddenText}); return { text: displayName, alternateText: email, diff --git a/src/pages/Search/SearchAddApproverPage.tsx b/src/pages/Search/SearchAddApproverPage.tsx index 71f678cea82a..3464b94ff96a 100644 --- a/src/pages/Search/SearchAddApproverPage.tsx +++ b/src/pages/Search/SearchAddApproverPage.tsx @@ -58,6 +58,8 @@ function SearchAddApproverPage() { const intersectedEmployees = firstWorkspaceEmployees ? lodashPick(firstWorkspaceEmployees, lodashIntersection(...employeeLists.map(Object.keys))) : {}; const policyMemberEmailsToAccountIDs = getMemberAccountIDsForWorkspace(intersectedEmployees, true, false); // We get the intersection here as we only want to show members who belong to all workspaces when adding an additional approver + // Resolve the translation once, not per member. + const hiddenText = translate('common.hidden'); return Object.values(intersectedEmployees) .map((employee): SelectionListApprover | null => { const isAdmin = employee?.role === CONST.REPORT.ROLE.ADMIN; @@ -106,7 +108,7 @@ function SearchAddApproverPage() { } const {avatar} = personalDetails?.[accountID] ?? {}; - const displayName = getDisplayNameForParticipant({accountID, formatPhoneNumber, personalDetailsData: personalDetails, translate}); + const displayName = getDisplayNameForParticipant({accountID, formatPhoneNumber, personalDetailsData: personalDetails, hiddenTranslation: hiddenText}); return { text: displayName, alternateText: email, diff --git a/src/pages/ShareCodePage.tsx b/src/pages/ShareCodePage.tsx index 18e40346e74f..2eb2045f9940 100644 --- a/src/pages/ShareCodePage.tsx +++ b/src/pages/ShareCodePage.tsx @@ -120,9 +120,10 @@ function ShareCodePage({report, policy, backTo}: ShareCodePageProps) { return getPolicyName({report, unavailableTranslation: translate('workspace.common.unavailable')}); } if (isMoneyRequestReport(report)) { - // generate subtitle from participants + // generate subtitle from participants; resolve the translation once, not per participant + const hiddenText = translate('common.hidden'); return getParticipantsAccountIDsForDisplay(report, true) - .map((accountID) => getDisplayNameForParticipant({accountID, formatPhoneNumber, translate})) + .map((accountID) => getDisplayNameForParticipant({accountID, formatPhoneNumber, hiddenTranslation: hiddenText})) .join(' & '); } diff --git a/src/pages/inbox/report/ReportTypingIndicator.tsx b/src/pages/inbox/report/ReportTypingIndicator.tsx index 9d9ad4d59c8e..2e9b440d4c45 100755 --- a/src/pages/inbox/report/ReportTypingIndicator.tsx +++ b/src/pages/inbox/report/ReportTypingIndicator.tsx @@ -35,7 +35,7 @@ function ReportTypingIndicator({reportID}: ReportTypingIndicatorProps) { // If the user is typing on OldDot, firstUserTyping will be a string (the user's displayName) const firstUserTypingDisplayName = isUserTypingADisplayName ? firstUserTyping - : getDisplayNameForParticipant({accountID: Number(firstUserTyping), shouldFallbackToHidden: false, formatPhoneNumber, translate}); + : getDisplayNameForParticipant({accountID: Number(firstUserTyping), shouldFallbackToHidden: false, formatPhoneNumber, hiddenTranslation: translate('common.hidden')}); if (usersTyping.length === 1) { return ( diff --git a/src/pages/inbox/sidebar/FABPopoverContent/menuItems/QuickActionMenuItem.tsx b/src/pages/inbox/sidebar/FABPopoverContent/menuItems/QuickActionMenuItem.tsx index a9619dce4eb4..20f12260c240 100644 --- a/src/pages/inbox/sidebar/FABPopoverContent/menuItems/QuickActionMenuItem.tsx +++ b/src/pages/inbox/sidebar/FABPopoverContent/menuItems/QuickActionMenuItem.tsx @@ -97,7 +97,7 @@ function QuickActionMenuItem({reportID}: QuickActionMenuItemProps) { if (!isEmptyObject(quickActionReport)) { if (quickAction?.action === CONST.QUICK_ACTIONS.SEND_MONEY && quickActionAvatars.length > 0) { const accountID = quickActionAvatars.at(0)?.id ?? CONST.DEFAULT_NUMBER_ID; - const name = getDisplayNameForParticipant({accountID: Number(accountID), shouldUseShortForm: true, formatPhoneNumber, translate}) ?? ''; + const name = getDisplayNameForParticipant({accountID: Number(accountID), shouldUseShortForm: true, formatPhoneNumber, hiddenTranslation: translate('common.hidden')}) ?? ''; quickActionTitle = translate('quickAction.paySomeone', name); } else { const titleKey = getQuickActionTitle(quickAction?.action ?? ('' as QuickActionName)); diff --git a/src/pages/workspace/WorkspaceMembersPage.tsx b/src/pages/workspace/WorkspaceMembersPage.tsx index 4349da8316b0..957f9bb1dd9a 100644 --- a/src/pages/workspace/WorkspaceMembersPage.tsx +++ b/src/pages/workspace/WorkspaceMembersPage.tsx @@ -162,14 +162,15 @@ function WorkspaceMembersPage({personalDetails, route, policy}: WorkspaceMembers const canSelectMultiple = canWriteMembers && (shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true); const confirmModalPrompt = useMemo(() => { + const hiddenText = translate('common.hidden'); const approverEmail = selectedEmployees.find((selectedEmployee) => isPolicyApprover(policy, selectedEmployee)); if (approverEmail) { const approverAccountID = policyMemberEmailsToAccountIDs[approverEmail]; return translate( 'workspace.people.removeMembersWarningPrompt', - getDisplayNameForParticipant({accountID: approverAccountID, formatPhoneNumber, translate}), - getDisplayNameForParticipant({accountID: policy?.ownerAccountID, formatPhoneNumber, translate}), + getDisplayNameForParticipant({accountID: approverAccountID, formatPhoneNumber, hiddenTranslation: hiddenText}), + getDisplayNameForParticipant({accountID: policy?.ownerAccountID, formatPhoneNumber, hiddenTranslation: hiddenText}), ); } @@ -179,8 +180,8 @@ function WorkspaceMembersPage({personalDetails, route, policy}: WorkspaceMembers if (userExporter) { const exporterAccountID = policyMemberEmailsToAccountIDs[userExporter]; return translate('workspace.people.removeMemberPromptExporter', { - memberName: getDisplayNameForParticipant({accountID: exporterAccountID, formatPhoneNumber, translate}), - workspaceOwner: getDisplayNameForParticipant({accountID: policy?.ownerAccountID, formatPhoneNumber, translate}), + memberName: getDisplayNameForParticipant({accountID: exporterAccountID, formatPhoneNumber, hiddenTranslation: hiddenText}), + workspaceOwner: getDisplayNameForParticipant({accountID: policy?.ownerAccountID, formatPhoneNumber, hiddenTranslation: hiddenText}), }); } diff --git a/tests/unit/QuickActionMenuItemTest.tsx b/tests/unit/QuickActionMenuItemTest.tsx index 968b41e34d72..b59787dc73e7 100644 --- a/tests/unit/QuickActionMenuItemTest.tsx +++ b/tests/unit/QuickActionMenuItemTest.tsx @@ -64,7 +64,7 @@ describe('QuickActionMenuItem', () => { await waitForBatchedUpdates(); // The pay-someone quick action resolves the payee name via getDisplayNameForParticipant, which must receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: AVATAR_ACCOUNT_ID, shouldUseShortForm: true, translate: mockTranslate})); + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: AVATAR_ACCOUNT_ID, shouldUseShortForm: true, hiddenTranslation: 'common.hidden'})); expect(mockTranslate).toHaveBeenCalledWith('quickAction.paySomeone', 'SPY_NAME'); }); }); diff --git a/tests/unit/ReportAddApproverPageTranslateTest.tsx b/tests/unit/ReportAddApproverPageTranslateTest.tsx index c6f2c5af13cd..1750d98836ad 100644 --- a/tests/unit/ReportAddApproverPageTranslateTest.tsx +++ b/tests/unit/ReportAddApproverPageTranslateTest.tsx @@ -92,6 +92,6 @@ describe('ReportAddApproverPage', () => { await waitForBatchedUpdates(); // Each candidate approver's name resolves via getDisplayNameForParticipant, which must receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: APPROVER_ACCOUNT_ID, translate: mockTranslate})); + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: APPROVER_ACCOUNT_ID, hiddenTranslation: 'common.hidden'})); }); }); diff --git a/tests/unit/ReportTypingIndicatorTest.tsx b/tests/unit/ReportTypingIndicatorTest.tsx index adf7b3cf6afb..e09ec3132d70 100644 --- a/tests/unit/ReportTypingIndicatorTest.tsx +++ b/tests/unit/ReportTypingIndicatorTest.tsx @@ -57,7 +57,9 @@ describe('ReportTypingIndicator', () => { await waitForBatchedUpdates(); // The typing user's name resolves via getDisplayNameForParticipant, which must receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: TYPING_ACCOUNT_ID, shouldFallbackToHidden: false, translate: mockTranslate})); + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith( + expect.objectContaining({accountID: TYPING_ACCOUNT_ID, shouldFallbackToHidden: false, hiddenTranslation: 'common.hidden'}), + ); expect(screen.getByText('SPY_NAME')).toBeOnTheScreen(); }); }); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 931b0b781a82..d73a9498d407 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -15284,7 +15284,7 @@ describe('ReportUtils', () => { formatPhoneNumber, accountID: hiddenAccountID, personalDetailsData: personalDetailsWithHidden, - translate: translateLocal, + hiddenTranslation: translateLocal('common.hidden'), }); expect(result).toBe(translateLocal('common.hidden')); @@ -15311,23 +15311,21 @@ describe('ReportUtils', () => { accountID: hiddenAccountID, shouldUseShortForm: true, personalDetailsData: personalDetailsWithHidden, - translate: translateLocal, + hiddenTranslation: translateLocal('common.hidden'), }); expect(result).toBe(translateLocal('common.hidden')); expect(result).not.toBe('ShortName'); }); - it('resolves the hidden participant fallback through the provided translate function', () => { + it('resolves the hidden participant fallback through the provided hiddenTranslation string', () => { const hiddenAccountID = 909090; - // A known participant with no displayName/login resolves to the hidden label, which must come from the provided translate function. - const translateWithHiddenMarker: LocalizedTranslate = (path, ...parameters) => (path === 'common.hidden' ? 'HiddenMarker' : translateLocal(path, ...parameters)); - + // A known participant with no displayName/login resolves to the hidden label, which must come from the provided hiddenTranslation string. const displayName = getDisplayNameForParticipant({ accountID: hiddenAccountID, formatPhoneNumber, personalDetailsData: {[hiddenAccountID]: {accountID: hiddenAccountID, login: '', displayName: ''}}, - translate: translateWithHiddenMarker, + hiddenTranslation: 'HiddenMarker', }); expect(displayName).toBe('HiddenMarker'); diff --git a/tests/unit/SearchAddApproverPageTranslateTest.tsx b/tests/unit/SearchAddApproverPageTranslateTest.tsx index 134ecbfeabdf..8426219ec673 100644 --- a/tests/unit/SearchAddApproverPageTranslateTest.tsx +++ b/tests/unit/SearchAddApproverPageTranslateTest.tsx @@ -90,6 +90,6 @@ describe('SearchAddApproverPage', () => { await waitForBatchedUpdates(); // Each candidate approver's name resolves via getDisplayNameForParticipant, which must receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: APPROVER_ACCOUNT_ID, translate: mockTranslate})); + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: APPROVER_ACCOUNT_ID, hiddenTranslation: 'common.hidden'})); }); }); diff --git a/tests/unit/ShareCodePageTranslateTest.tsx b/tests/unit/ShareCodePageTranslateTest.tsx index 6284dc048ec3..87b2cc6966b4 100644 --- a/tests/unit/ShareCodePageTranslateTest.tsx +++ b/tests/unit/ShareCodePageTranslateTest.tsx @@ -89,7 +89,7 @@ describe('ShareCodePage', () => { await waitForBatchedUpdates(); // Each participant's name resolves via getDisplayNameForParticipant, which must receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({translate: mockTranslate})); + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({hiddenTranslation: 'common.hidden'})); }); describe('profile QR code avatar logo', () => { diff --git a/tests/unit/SuggestionUtilsTranslateTest.ts b/tests/unit/SuggestionUtilsTranslateTest.ts index 1407b31eef81..f18c6227c04a 100644 --- a/tests/unit/SuggestionUtilsTranslateTest.ts +++ b/tests/unit/SuggestionUtilsTranslateTest.ts @@ -27,14 +27,14 @@ describe('SuggestionUtils - getSortedPersonalDetails translate threading', () => jest.clearAllMocks(); }); - it('passes the provided translate function to getDisplayNameForParticipant', () => { + it('passes the resolved hidden string to getDisplayNameForParticipant', () => { const first = {login: 'first@test.com', weight: 2, accountID: 801} as PersonalDetails & {weight: number}; const second = {login: 'second@test.com', weight: 2, accountID: 802} as PersonalDetails & {weight: number}; getSortedPersonalDetails([second, first], localeCompare, formatPhoneNumber, translateLocal); - // The sort comparator resolves each display name via getDisplayNameForParticipant, which must receive the provided translate. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({translate: translateLocal})); + // The sort comparator resolves each display name via getDisplayNameForParticipant, which must receive the resolved "Hidden" string. + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({hiddenTranslation: translateLocal('common.hidden')})); }); it('sorts by the display name resolved through the provided translate function', () => { diff --git a/tests/unit/TaskViewTranslateTest.tsx b/tests/unit/TaskViewTranslateTest.tsx index 5656e131128a..404c621c5287 100644 --- a/tests/unit/TaskViewTranslateTest.tsx +++ b/tests/unit/TaskViewTranslateTest.tsx @@ -70,6 +70,6 @@ describe('TaskView', () => { await waitForBatchedUpdates(); // The assignee menu item resolves its title via getDisplayNameForParticipant, which must receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: TASK_MANAGER_ACCOUNT_ID, translate: mockTranslate})); + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: TASK_MANAGER_ACCOUNT_ID, hiddenTranslation: 'common.hidden'})); }); }); diff --git a/tests/unit/UserSelectionListItemTest.tsx b/tests/unit/UserSelectionListItemTest.tsx index 7446855b8c76..2eb2b69f0686 100644 --- a/tests/unit/UserSelectionListItemTest.tsx +++ b/tests/unit/UserSelectionListItemTest.tsx @@ -50,6 +50,6 @@ describe('UserSelectionListItem', () => { ); // The row's display name resolves via getDisplayNameForParticipant, which must receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: ITEM_ACCOUNT_ID, translate: mockTranslate})); + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: ITEM_ACCOUNT_ID, hiddenTranslation: 'common.hidden'})); }); }); diff --git a/tests/unit/usePreviewMessageAnimationTest.ts b/tests/unit/usePreviewMessageAnimationTest.ts index 289371792b88..e047b513eb70 100644 --- a/tests/unit/usePreviewMessageAnimationTest.ts +++ b/tests/unit/usePreviewMessageAnimationTest.ts @@ -59,7 +59,7 @@ describe('usePreviewMessageAnimation', () => { const {result} = renderHook(() => usePreviewMessageAnimation(baseParams)); // The hook resolves the payer/approver name via getDisplayNameForParticipant, which must receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: MANAGER_ID, shouldUseShortForm: true, translate: mockTranslate})); + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: MANAGER_ID, shouldUseShortForm: true, hiddenTranslation: 'common.hidden'})); expect(result.current.previewMessageStyle).toBeDefined(); }); @@ -69,6 +69,6 @@ describe('usePreviewMessageAnimation', () => { renderHook(() => usePreviewMessageAnimation({...baseParams, hasNonReimbursableTransactions: true, chatReport})); // The payerSpent branch re-resolves the name from the chat owner, and it must also receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: CHAT_OWNER_ID, shouldUseShortForm: true, translate: mockTranslate})); + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: CHAT_OWNER_ID, shouldUseShortForm: true, hiddenTranslation: 'common.hidden'})); }); }); diff --git a/tests/unit/useReportActionAvatarsTranslateTest.tsx b/tests/unit/useReportActionAvatarsTranslateTest.tsx index 7998f89abb8d..b13c1ed4f3b2 100644 --- a/tests/unit/useReportActionAvatarsTranslateTest.tsx +++ b/tests/unit/useReportActionAvatarsTranslateTest.tsx @@ -51,7 +51,7 @@ describe('useReportActionAvatars translate wiring', () => { renderHook(() => useReportActionAvatars({report, action}), {wrapper}); - // The hook resolves the default display name via getDisplayNameForParticipant, which must receive the translate from useLocalize. - expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({accountID: ACTOR_ACCOUNT_ID, translate: mockTranslate})); + // The hook resolves the default display name via getDisplayNameForParticipant, which must receive the resolved "Hidden" string from useLocalize. + expect(mockGetDisplayNameForParticipant).toHaveBeenCalledWith(expect.objectContaining({hiddenTranslation: 'common.hidden'})); }); });