Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
685df71
fix: [Translation Migration] Fix split or incomplete translations in …
TaduJR Nov 14, 2025
15caba1
fix: eslint error
TaduJR Nov 14, 2025
593133f
Merge branch 'Expensify:main' into fix-Translation-Migration-Fix-spli…
TaduJR Nov 16, 2025
ca34574
Merge main into fix-Translation-Migration-Fix-split-or-incomplete-tra…
TaduJR Nov 18, 2025
3f45aa2
chore: move additional text generation to SidebarUtils for cleaner code
TaduJR Nov 18, 2025
538e574
Merge branch 'Expensify:main' into fix-Translation-Migration-Fix-spli…
TaduJR Nov 18, 2025
1501dde
Merge branch 'Expensify:main' into fix-Translation-Migration-Fix-spli…
TaduJR Nov 18, 2025
6237469
Merge branch 'Expensify:main' into fix-Translation-Migration-Fix-spli…
TaduJR Nov 19, 2025
af73561
Merge branch 'Expensify:main' into fix-Translation-Migration-Fix-spli…
TaduJR Nov 20, 2025
1a7bcd9
Merge branch 'main' of https://github.com/TaduJR/App into fix-Transla…
TaduJR Nov 21, 2025
dd71cb3
Merge branch 'Expensify:main' into fix-Translation-Migration-Fix-spli…
TaduJR Nov 22, 2025
96cf616
Merge branch 'fix-Translation-Migration-Fix-split-or-incomplete-trans…
TaduJR Nov 22, 2025
25caba9
Merge branch 'main' of https://github.com/TaduJR/App into fix-Transla…
TaduJR Nov 24, 2025
c6d87f2
Merge branch 'Expensify:main' into fix-Translation-Migration-Fix-spli…
TaduJR Nov 25, 2025
f563af1
Merge branch 'Expensify:main' into fix-Translation-Migration-Fix-spli…
TaduJR Nov 27, 2025
3a6b053
Merge branch 'Expensify:main' into fix-Translation-Migration-Fix-spli…
TaduJR Nov 29, 2025
0bcd546
fix: LHN regression by setting messageText from messageHtml
TaduJR Nov 29, 2025
d01ce59
fix: LHN regression by setting messageText from messageHtml
TaduJR Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"asar",
"ASPAC",
"assetlinks",
"accountid",
"attributes.accountid",
"attributes.reportid",
"authorised",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ function BaseHTMLEngineProvider({textSelectable = false, children, enableExperim
'mention-report': HTMLElementModel.fromCustomModel({tagName: 'mention-report', contentModel: HTMLContentModel.textual}),
'mention-here': HTMLElementModel.fromCustomModel({tagName: 'mention-here', contentModel: HTMLContentModel.textual}),
'mention-short': HTMLElementModel.fromCustomModel({tagName: 'mention-short', contentModel: HTMLContentModel.textual}),
'user-details': HTMLElementModel.fromCustomModel({tagName: 'user-details', contentModel: HTMLContentModel.textual}),
'copy-text': HTMLElementModel.fromCustomModel({tagName: 'copy-text', contentModel: HTMLContentModel.textual}),
'concierge-link': HTMLElementModel.fromCustomModel({tagName: 'concierge-link', contentModel: HTMLContentModel.textual}),
'account-manager-link': HTMLElementModel.fromCustomModel({tagName: 'account-manager-link', contentModel: HTMLContentModel.textual}),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import type {CustomRendererProps, TPhrasing, TText} from 'react-native-render-html';
import {TNodeChildrenRenderer} from 'react-native-render-html';
import Text from '@components/Text';
import UserDetailsTooltip from '@components/UserDetailsTooltip';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import {isOptimisticPersonalDetail} from '@libs/ReportUtils';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';

type UserDetailsRendererProps = CustomRendererProps<TText | TPhrasing>;

function UserDetailsRenderer({tnode, ...defaultRendererProps}: UserDetailsRendererProps) {
const styles = useThemeStyles();
const accountID = tnode.attributes.accountid ? parseInt(tnode.attributes.accountid, 10) : undefined;

if (!accountID) {
// Fallback: render without tooltip if no accountID
return <TNodeChildrenRenderer tnode={tnode} />;
}

const isOptimistic = isOptimisticPersonalDetail(accountID);

return (
<UserDetailsTooltip accountID={accountID}>
{isOptimistic ? (
<Text
// eslint-disable-next-line react/jsx-props-no-spreading
{...defaultRendererProps}
style={[styles.textStrong]}
>
<TNodeChildrenRenderer tnode={tnode} />
</Text>
) : (
<Text
// eslint-disable-next-line react/jsx-props-no-spreading
{...defaultRendererProps}
style={[styles.textStrong]}
onPress={() => Navigation.navigate(ROUTES.PROFILE.getRoute(accountID, Navigation.getActiveRoute()))}
suppressHighlighting
role={CONST.ROLE.LINK}
>
<TNodeChildrenRenderer tnode={tnode} />
</Text>
)}
</UserDetailsTooltip>
);
}

UserDetailsRenderer.displayName = 'UserDetailsRenderer';

export default UserDetailsRenderer;
2 changes: 2 additions & 0 deletions src/components/HTMLEngineProvider/HTMLRenderers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import PreRenderer from './PreRenderer';
import RBRRenderer from './RBRRenderer';
import ShortMentionRenderer from './ShortMentionRenderer';
import TaskTitleRenderer from './TaskTitleRenderer';
import UserDetailsRenderer from './UserDetailsRenderer';
import VideoRenderer from './VideoRenderer';

/**
Expand All @@ -38,6 +39,7 @@ const HTMLEngineProviderComponentList: CustomTagRendererRecord = {
'mention-report': MentionReportRenderer,
'mention-here': MentionHereRenderer,
'mention-short': ShortMentionRenderer,
'user-details': UserDetailsRenderer,
'copy-text': CopyTextRenderer,
emoji: EmojiRenderer,
'next-step-email': NextStepEmailRenderer,
Expand Down
50 changes: 11 additions & 39 deletions src/components/ReportWelcomeText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,11 @@ import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import {getPersonalDetailsForAccountIDs} from '@libs/OptionsListUtils';
import {
getDisplayNamesWithTooltips,
getParticipantsAccountIDsForDisplay,
getPolicyName,
getReportName,
isChatRoom as isChatRoomReportUtils,
isConciergeChatReport,
isInvoiceRoom as isInvoiceRoomReportUtils,
isOptimisticPersonalDetail,
isPolicyExpenseChat as isPolicyExpenseChatReportUtils,
isSelfDM as isSelfDMReportUtils,
isSystemChat as isSystemChatReportUtils,
Expand All @@ -32,7 +29,6 @@ import ROUTES from '@src/ROUTES';
import type {OnyxInputOrEntry, PersonalDetails, PersonalDetailsList, Policy, Report} from '@src/types/onyx';
import RenderHTML from './RenderHTML';
import Text from './Text';
import UserDetailsTooltip from './UserDetailsTooltip';

type ReportWelcomeTextProps = {
/** The report currently being looked at */
Expand Down Expand Up @@ -68,12 +64,6 @@ function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) {
const isSystemChat = isSystemChatReportUtils(report);
const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM || isSystemChat);
const participantAccountIDs = getParticipantsAccountIDsForDisplay(report, undefined, true, true, reportMetadata);
const isMultipleParticipant = participantAccountIDs.length > 1;
const displayNamesWithTooltips = getDisplayNamesWithTooltips(
getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails as OnyxInputOrEntry<PersonalDetailsList>),
isMultipleParticipant,
localeCompare,
);
const moneyRequestOptions = temporary_getMoneyRequestOptions(report, policy, participantAccountIDs, isReportArchived, isRestrictedToPreferredPolicy);
const policyName = getPolicyName({report});

Expand Down Expand Up @@ -135,7 +125,16 @@ function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) {
const participantPersonalDetailListExcludeCurrentUser = Object.values(
getPersonalDetailsForAccountIDs(participantAccountIDsExcludeCurrentUser, personalDetails as OnyxInputOrEntry<PersonalDetailsList>),
);
const welcomeMessage = SidebarUtils.getWelcomeMessage(report, policy, participantPersonalDetailListExcludeCurrentUser, localeCompare, isReportArchived, reportDetailsLink);
const welcomeMessage = SidebarUtils.getWelcomeMessage(
report,
policy,
participantPersonalDetailListExcludeCurrentUser,
localeCompare,
isReportArchived,
reportDetailsLink,
shouldShowUsePlusButtonText,
additionalText,
);

return (
<>
Expand All @@ -159,34 +158,7 @@ function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) {
<Text>{welcomeMessage.messageText}</Text>
</Text>
)}
{isDefault && displayNamesWithTooltips.length > 0 && (
<Text>
<Text>{welcomeMessage.phrase1}</Text>
{displayNamesWithTooltips.map(({displayName, accountID}, index) => (
// eslint-disable-next-line react/no-array-index-key
<Text key={`${displayName}${index}`}>
<UserDetailsTooltip accountID={accountID}>
{isOptimisticPersonalDetail(accountID) ? (
<Text style={[styles.textStrong]}>{displayName}</Text>
) : (
<Text
style={[styles.textStrong]}
onPress={() => Navigation.navigate(ROUTES.PROFILE.getRoute(accountID, Navigation.getActiveRoute()))}
suppressHighlighting
>
{displayName}
</Text>
)}
</UserDetailsTooltip>
{index === displayNamesWithTooltips.length - 1 && <Text>.</Text>}
{index === displayNamesWithTooltips.length - 2 && <Text>{`${displayNamesWithTooltips.length > 2 ? ',' : ''} ${translate('common.and')} `}</Text>}
{index < displayNamesWithTooltips.length - 2 && <Text>, </Text>}
</Text>
))}
{shouldShowUsePlusButtonText && <Text>{translate('reportActionsView.usePlusButton', {additionalText})}</Text>}
{isConciergeChatReport(report) && <Text>{translate('reportActionsView.askConcierge')}</Text>}
</Text>
)}
{isDefault && !!welcomeMessage.messageHtml && <RenderHTML html={welcomeMessage.messageHtml} />}
</View>
</>
);
Expand Down
3 changes: 2 additions & 1 deletion src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import type {
BeginningOfChatHistoryAnnounceRoomParams,
BeginningOfChatHistoryDomainRoomParams,
BeginningOfChatHistoryInvoiceRoomParams,
BeginningOfChatHistoryParams,
BeginningOfChatHistoryPolicyExpenseChatParams,
BeginningOfChatHistoryUserRoomParams,
BillableDefaultDescriptionParams,
Expand Down Expand Up @@ -955,7 +956,7 @@ const translations: TranslationDeepObject<typeof en> = {
`Dieser Chatraum ist für alles, was mit <strong><a class="no-style-link" href="${reportDetailsLink}">${reportName}</a></strong> zu tun hat.`,
beginningOfChatHistoryInvoiceRoom: ({invoicePayer, invoiceReceiver}: BeginningOfChatHistoryInvoiceRoomParams) =>
`Dieser Chat ist für Rechnungen zwischen <strong>${invoicePayer}</strong> und <strong>${invoiceReceiver}</strong>. Verwenden Sie die Schaltfläche +, um eine Rechnung zu senden.`,
beginningOfChatHistory: 'Dieser Chat ist mit',
beginningOfChatHistory: ({users}: BeginningOfChatHistoryParams) => `Dieser Chat ist mit ${users}.`,
beginningOfChatHistoryPolicyExpenseChat: ({workspaceName, submitterDisplayName}: BeginningOfChatHistoryPolicyExpenseChatParams) =>
`Hier wird <strong>${submitterDisplayName}</strong> die Ausgaben an <strong>${workspaceName}</strong> übermitteln. Verwenden Sie einfach die Schaltfläche +.`,
beginningOfChatHistorySelfDM: 'Dies ist Ihr persönlicher Bereich. Nutzen Sie ihn für Notizen, Aufgaben, Entwürfe und Erinnerungen.',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import type {
BeginningOfChatHistoryAnnounceRoomParams,
BeginningOfChatHistoryDomainRoomParams,
BeginningOfChatHistoryInvoiceRoomParams,
BeginningOfChatHistoryParams,
BeginningOfChatHistoryPolicyExpenseChatParams,
BeginningOfChatHistoryUserRoomParams,
BillableDefaultDescriptionParams,
Expand Down Expand Up @@ -944,7 +945,7 @@ const translations = {
`This chat room is for anything <strong><a class="no-style-link" href="${reportDetailsLink}">${reportName}</a></strong> related.`,
beginningOfChatHistoryInvoiceRoom: ({invoicePayer, invoiceReceiver}: BeginningOfChatHistoryInvoiceRoomParams) =>
`This chat is for invoices between <strong>${invoicePayer}</strong> and <strong>${invoiceReceiver}</strong>. Use the + button to send an invoice.`,
beginningOfChatHistory: 'This chat is with ',
beginningOfChatHistory: ({users}: BeginningOfChatHistoryParams) => `This chat is with ${users}.`,
beginningOfChatHistoryPolicyExpenseChat: ({workspaceName, submitterDisplayName}: BeginningOfChatHistoryPolicyExpenseChatParams) =>
`This is where <strong>${submitterDisplayName}</strong> will submit expenses to <strong>${workspaceName}</strong>. Just use the + button.`,
beginningOfChatHistorySelfDM: 'This is your personal space. Use it for notes, tasks, drafts, and reminders.',
Expand Down
4 changes: 2 additions & 2 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {CONST as COMMON_CONST} from 'expensify-common';
import dedent from '@libs/StringUtils/dedent';
import CONST from '@src/CONST';
import type en from './en';
import type {TagSelectionParams, ViolationsRterParams} from './params';
import type {BeginningOfChatHistoryParams, TagSelectionParams, ViolationsRterParams} from './params';
import type {TranslationDeepObject} from './types';

/* eslint-disable max-len */
Expand Down Expand Up @@ -608,7 +608,7 @@ const translations: TranslationDeepObject<typeof en> = {
`Esta sala de chat es para cualquier cosa relacionada con <strong><a class="no-style-link" href="${reportDetailsLink}">${reportName}</a></strong>.`,
beginningOfChatHistoryInvoiceRoom: ({invoicePayer, invoiceReceiver}) =>
`Este chat es para facturas entre <strong>${invoicePayer}</strong> y <strong>${invoiceReceiver}</strong>. Usa el botón + para enviar una factura.`,
beginningOfChatHistory: 'Este chat es con ',
beginningOfChatHistory: ({users}: BeginningOfChatHistoryParams) => `Este chat es con ${users}.`,
beginningOfChatHistoryPolicyExpenseChat: ({workspaceName, submitterDisplayName}) =>
`Aquí es donde <strong>${submitterDisplayName}</strong> enviará los gastos al espacio de trabajo <strong>${workspaceName}</strong>. Solo usa el botón +.`,
beginningOfChatHistorySelfDM: 'Este es tu espacio personal. Úsalo para notas, tareas, borradores y recordatorios.',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import type {
BeginningOfChatHistoryAnnounceRoomParams,
BeginningOfChatHistoryDomainRoomParams,
BeginningOfChatHistoryInvoiceRoomParams,
BeginningOfChatHistoryParams,
BeginningOfChatHistoryPolicyExpenseChatParams,
BeginningOfChatHistoryUserRoomParams,
BillableDefaultDescriptionParams,
Expand Down Expand Up @@ -957,7 +958,7 @@ const translations: TranslationDeepObject<typeof en> = {
`Ce salon de discussion est destiné à tout ce qui concerne <strong><a class="no-style-link" href="${reportDetailsLink}">${reportName}</a></strong>.`,
beginningOfChatHistoryInvoiceRoom: ({invoicePayer, invoiceReceiver}: BeginningOfChatHistoryInvoiceRoomParams) =>
`Ce chat concerne les factures entre <strong>${invoicePayer}</strong> et <strong>${invoiceReceiver}</strong>. Utilisez le bouton + pour envoyer une facture.`,
beginningOfChatHistory: 'Ce chat est avec',
beginningOfChatHistory: ({users}: BeginningOfChatHistoryParams) => `Ce chat est avec ${users}.`,
beginningOfChatHistoryPolicyExpenseChat: ({workspaceName, submitterDisplayName}: BeginningOfChatHistoryPolicyExpenseChatParams) =>
`C'est ici que <strong>${submitterDisplayName}</strong> soumettra ses dépenses à <strong>${workspaceName}</strong>. Il suffit d'utiliser le bouton +.`,
beginningOfChatHistorySelfDM: "C'est votre espace personnel. Utilisez-le pour des notes, des tâches, des brouillons et des rappels.",
Expand Down
3 changes: 2 additions & 1 deletion src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import type {
BeginningOfChatHistoryAnnounceRoomParams,
BeginningOfChatHistoryDomainRoomParams,
BeginningOfChatHistoryInvoiceRoomParams,
BeginningOfChatHistoryParams,
BeginningOfChatHistoryPolicyExpenseChatParams,
BeginningOfChatHistoryUserRoomParams,
BillableDefaultDescriptionParams,
Expand Down Expand Up @@ -954,7 +955,7 @@ const translations: TranslationDeepObject<typeof en> = {
`Questa chat è per tutto ciò che riguarda <strong><a class="no-style-link" href="${reportDetailsLink}">${reportName}</a></strong>.`,
beginningOfChatHistoryInvoiceRoom: ({invoicePayer, invoiceReceiver}: BeginningOfChatHistoryInvoiceRoomParams) =>
`Questa chat è per le fatture tra <strong>${invoicePayer}</strong> e <strong>${invoiceReceiver}</strong>. Utilizzare il pulsante + per inviare una fattura.`,
beginningOfChatHistory: 'Questa chat è con',
beginningOfChatHistory: ({users}: BeginningOfChatHistoryParams) => `Questa chat è con ${users}.`,
beginningOfChatHistoryPolicyExpenseChat: ({workspaceName, submitterDisplayName}: BeginningOfChatHistoryPolicyExpenseChatParams) =>
`È qui che <strong>${submitterDisplayName}</strong> presenterà le spese a <strong>${workspaceName}</strong>. Basta usare il pulsante +.`,
beginningOfChatHistorySelfDM: 'Questo è il tuo spazio personale. Usalo per appunti, compiti, bozze e promemoria.',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import type {
BeginningOfChatHistoryAnnounceRoomParams,
BeginningOfChatHistoryDomainRoomParams,
BeginningOfChatHistoryInvoiceRoomParams,
BeginningOfChatHistoryParams,
BeginningOfChatHistoryPolicyExpenseChatParams,
BeginningOfChatHistoryUserRoomParams,
BillableDefaultDescriptionParams,
Expand Down Expand Up @@ -955,7 +956,7 @@ const translations: TranslationDeepObject<typeof en> = {
`このチャットルームは、<strong><a class="no-style-link" href="${reportDetailsLink}">${reportName}</a></strong>に関することなら何でもどうぞ。`,
beginningOfChatHistoryInvoiceRoom: ({invoicePayer, invoiceReceiver}: BeginningOfChatHistoryInvoiceRoomParams) =>
`このチャットは、<strong>${invoicePayer}</strong>と<strong>${invoiceReceiver}</strong>間の請求書用です。請求書を送信するには、+ ボタンを使用してください。`,
beginningOfChatHistory: 'このチャットは',
beginningOfChatHistory: ({users}: BeginningOfChatHistoryParams) => `このチャットは${users}とのチャットです。`,
beginningOfChatHistoryPolicyExpenseChat: ({workspaceName, submitterDisplayName}: BeginningOfChatHistoryPolicyExpenseChatParams) =>
`ここで<strong>${submitterDisplayName}</strong>が<strong>${workspaceName}</strong>に経費を提出します。+ボタンをクリックしてください。`,
beginningOfChatHistorySelfDM: 'これはあなたの個人スペースです。メモ、タスク、下書き、リマインダーに使用してください。',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import type {
BeginningOfChatHistoryAnnounceRoomParams,
BeginningOfChatHistoryDomainRoomParams,
BeginningOfChatHistoryInvoiceRoomParams,
BeginningOfChatHistoryParams,
BeginningOfChatHistoryPolicyExpenseChatParams,
BeginningOfChatHistoryUserRoomParams,
BillableDefaultDescriptionParams,
Expand Down Expand Up @@ -953,7 +954,7 @@ const translations: TranslationDeepObject<typeof en> = {
`Deze chatroom is voor alles wat met <strong><a class="no-style-link" href="${reportDetailsLink}">${reportName}</a></strong> te maken heeft.`,
beginningOfChatHistoryInvoiceRoom: ({invoicePayer, invoiceReceiver}: BeginningOfChatHistoryInvoiceRoomParams) =>
`Deze chat is voor facturen tussen <strong>${invoicePayer}</strong> en <strong>${invoiceReceiver}</strong>. Gebruik de + knop om een factuur te sturen.`,
beginningOfChatHistory: 'Deze chat is met',
beginningOfChatHistory: ({users}: BeginningOfChatHistoryParams) => `Deze chat is met ${users}.`,
beginningOfChatHistoryPolicyExpenseChat: ({workspaceName, submitterDisplayName}: BeginningOfChatHistoryPolicyExpenseChatParams) =>
`Dit is waar <strong>${submitterDisplayName}</strong> kosten zal indienen bij <strong>${workspaceName}</strong>. Gebruik gewoon de + knop.`,
beginningOfChatHistorySelfDM: 'Dit is je persoonlijke ruimte. Gebruik het voor notities, taken, concepten en herinneringen.',
Expand Down
5 changes: 5 additions & 0 deletions src/languages/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ type BeginningOfChatHistoryInvoiceRoomParams = {
invoiceReceiver: string;
};

type BeginningOfChatHistoryParams = {
users: string;
};

type LearnMoreRouteParams = {
learnMoreMethodsRoute: string;
formattedPrice: string;
Expand Down Expand Up @@ -1051,6 +1055,7 @@ export type {
BeginningOfChatHistoryAnnounceRoomParams,
BeginningOfChatHistoryPolicyExpenseChatParams,
BeginningOfChatHistoryInvoiceRoomParams,
BeginningOfChatHistoryParams,
BeginningOfArchivedRoomParams,
BeginningOfChatHistoryUserRoomParams,
BeginningOfChatHistoryAnnounceRoomPartTwo,
Expand Down
Loading
Loading