Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 8 additions & 3 deletions src/components/DisplayNames/index.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ import TextWithEmojiFragment from '@pages/home/report/comment/TextWithEmojiFragm
import type DisplayNamesProps from './types';

// As we don't have to show tooltips of the Native platform so we simply render the full display names list.
function DisplayNames({accessibilityLabel, fullTitle, textStyles = [], numberOfLines = 1, renderAdditionalText, forwardedFSClass, testID}: DisplayNamesProps) {
function DisplayNames({accessibilityLabel, fullTitle, textStyles = [], numberOfLines = 1, renderAdditionalText, forwardedFSClass, testID, shouldParseFullTitle = true}: DisplayNamesProps) {
const {translate} = useLocalize();
const titleContainsTextAndCustomEmoji = useMemo(() => containsCustomEmoji(fullTitle) && !containsOnlyCustomEmoji(fullTitle), [fullTitle]);
const title = useMemo(() => {
const processedTitle = shouldParseFullTitle ? Parser.htmlToText(fullTitle) : fullTitle;
return StringUtils.lineBreaksToSpaces(processedTitle) || translate('common.hidden');
}, [fullTitle, shouldParseFullTitle, translate]);

return (
<Text
accessibilityLabel={accessibilityLabel}
Expand All @@ -21,11 +26,11 @@ function DisplayNames({accessibilityLabel, fullTitle, textStyles = [], numberOfL
>
{titleContainsTextAndCustomEmoji ? (
<TextWithEmojiFragment
message={StringUtils.lineBreaksToSpaces(Parser.htmlToText(fullTitle)) || translate('common.hidden')}
message={title}
style={textStyles}
/>
) : (
StringUtils.lineBreaksToSpaces(Parser.htmlToText(fullTitle)) || translate('common.hidden')
title
)}
{renderAdditionalText?.()}
</Text>
Expand Down
8 changes: 6 additions & 2 deletions src/components/DisplayNames/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, {useMemo} from 'react';
import useLocalize from '@hooks/useLocalize';
import Parser from '@libs/Parser';
import StringUtils from '@libs/StringUtils';
Expand All @@ -16,9 +16,13 @@ function DisplayNames({
displayNamesWithTooltips,
renderAdditionalText,
forwardedFSClass,
shouldParseFullTitle = true,
}: DisplayNamesProps) {
const {translate} = useLocalize();
const title = StringUtils.lineBreaksToSpaces(Parser.htmlToText(fullTitle)) || translate('common.hidden');
const title = useMemo(() => {
const processedTitle = shouldParseFullTitle ? Parser.htmlToText(fullTitle) : fullTitle;
return StringUtils.lineBreaksToSpaces(processedTitle) || translate('common.hidden');
}, [fullTitle, shouldParseFullTitle, translate]);

if (!tooltipEnabled) {
return (
Expand Down
8 changes: 8 additions & 0 deletions src/components/DisplayNames/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ type DisplayNamesProps = ForwardedFSClassProps & {
/** The full title of the DisplayNames component (not split up) */
fullTitle: string;

/**
* Whether `fullTitle` should be processed through Parser.htmlToText().
* Set to true when `fullTitle` contains HTML that needs to be converted to plain text
* Set to false when `fullTitle` is already plain text or when you want to preserve
* any HTML formatting in the display.
*/
shouldParseFullTitle?: boolean;

/** Array of objects that map display names to their corresponding tooltip */
displayNamesWithTooltips?: DisplayNameWithTooltip[];

Expand Down
3 changes: 3 additions & 0 deletions src/components/HeaderWithBackButton/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ type HeaderWithBackButtonProps = Partial<ChildrenProps> & {
/** Whether we should enable detail page navigation */
shouldEnableDetailPageNavigation?: boolean;

/** Number of lines to display for the title */
numberOfTitleLines?: number;

/** Whether we should overlay the 3 dots menu */
shouldOverlayDots?: boolean;

Expand Down
3 changes: 3 additions & 0 deletions src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import DisplayNames from '@components/DisplayNames';
import Hoverable from '@components/Hoverable';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';

Check warning on line 7 in src/components/LHNOptionsList/OptionRowLHN.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'@components/Icon/Expensicons' import is restricted from being used by a pattern. Direct imports from Icon/Expensicons are deprecated. Please use lazy loading hooks instead. Use `useMemoizedLazyExpensifyIcons` from @hooks/useLazyAsset. See docs/LAZY_ICONS_AND_ILLUSTRATIONS.md for details

Check warning on line 7 in src/components/LHNOptionsList/OptionRowLHN.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'@components/Icon/Expensicons' import is restricted from being used. Direct imports from @components/Icon/Expensicons are deprecated. Please use lazy loading hooks instead. Use `useMemoizedLazyExpensifyIcons` from @hooks/useLazyAsset. See docs/LAZY_ICONS_AND_ILLUSTRATIONS.md for details
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import {useSession} from '@components/OnyxListItemProvider';
import PressableWithSecondaryInteraction from '@components/PressableWithSecondaryInteraction';
Expand Down Expand Up @@ -170,6 +170,8 @@
const subscriptAvatarBorderColor = isOptionFocused ? focusedBackgroundColor : theme.sidebar;
const firstIcon = optionItem.icons?.at(0);

// This is used to ensure that we display the text exactly as the user entered it when displaying LHN title, instead of parsing their text to HTML.
const shouldParseFullTitle = optionItem?.parentReportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming from #77518. Group titles can end up as an empty string if they are parsed (e.g. if the title is < >) which causes them to render with the fallback text Hidden.

const alternateTextFSClass = FS.getChatFSClass(report);

const onOptionPress = (event: GestureResponderEvent | KeyboardEvent | undefined) => {
Expand Down Expand Up @@ -272,6 +274,7 @@
<DisplayNames
accessibilityLabel={translate('accessibilityHints.chatUserDisplayNames')}
fullTitle={optionItem.text ?? ''}
shouldParseFullTitle={shouldParseFullTitle}
displayNamesWithTooltips={optionItem.displayNamesWithTooltips ?? []}
tooltipEnabled
numberOfLines={1}
Expand Down
1 change: 1 addition & 0 deletions src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import FormHelpMessage from './FormHelpMessage';
import Hoverable from './Hoverable';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';

Check warning on line 37 in src/components/MenuItem.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'./Icon/Expensicons' import is restricted from being used by a pattern. Direct imports from Icon/Expensicons are deprecated. Please use lazy loading hooks instead. Use `useMemoizedLazyExpensifyIcons` from @hooks/useLazyAsset. See docs/LAZY_ICONS_AND_ILLUSTRATIONS.md for details
import {MenuItemGroupContext} from './MenuItemGroup';
import PlaidCardFeedIcon from './PlaidCardFeedIcon';
import type {PressableRef} from './Pressable/GenericPressable/types';
Expand Down Expand Up @@ -611,6 +611,7 @@
return (
<DisplayNames
fullTitle={title}
shouldParseFullTitle={!shouldRenderAsHTML}
displayNamesWithTooltips={titleWithTooltips}
tooltipEnabled
numberOfLines={1}
Expand Down
4 changes: 4 additions & 0 deletions src/pages/home/HeaderView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
const parentNavigationReport = isParentOneTransactionThread ? parentReport : reportHeaderData;
const isReportHeaderDataArchived = useReportIsArchived(reportHeaderData?.reportID);
// Use sorted display names for the title for group chats on native small screen widths
// eslint-disable-next-line @typescript-eslint/no-deprecated
const title = getReportName(reportHeaderData, policy, parentReportAction, personalDetails, invoiceReceiverPolicy, undefined, undefined, isReportHeaderDataArchived);
const subtitle = getChatRoomSubtitle(reportHeaderData, false, isReportHeaderDataArchived);
const isParentReportHeaderDataArchived = useReportIsArchived(reportHeaderData?.parentReportID);
Expand All @@ -154,6 +155,8 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
const policyDescription = getPolicyDescriptionText(policy);
const isPersonalExpenseChat = isPolicyExpenseChat && isCurrentUserSubmitter(report);
const hasTeam2025Pricing = useHasTeam2025Pricing();
// This is used to ensure that we display the text exactly as the user entered it when displaying thread header text, instead of parsing their text to HTML.
const shouldParseFullTitle = parentReportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT;
const subscriptionPlan = useSubscriptionPlan();
const ancestors = useAncestors(report);

Expand Down Expand Up @@ -300,6 +303,7 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
<DisplayNames
fullTitle={title}
displayNamesWithTooltips={displayNamesWithTooltips}
shouldParseFullTitle={shouldParseFullTitle}
tooltipEnabled
numberOfLines={1}
textStyles={[styles.headerText, styles.pre]}
Expand Down
Loading