diff --git a/src/components/DisplayNames/index.native.tsx b/src/components/DisplayNames/index.native.tsx index cae91c80272e..0516cb1e1d5f 100644 --- a/src/components/DisplayNames/index.native.tsx +++ b/src/components/DisplayNames/index.native.tsx @@ -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 ( {titleContainsTextAndCustomEmoji ? ( ) : ( - StringUtils.lineBreaksToSpaces(Parser.htmlToText(fullTitle)) || translate('common.hidden') + title )} {renderAdditionalText?.()} diff --git a/src/components/DisplayNames/index.tsx b/src/components/DisplayNames/index.tsx index 5158747e4c25..58a4ee91da34 100644 --- a/src/components/DisplayNames/index.tsx +++ b/src/components/DisplayNames/index.tsx @@ -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'; @@ -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 ( diff --git a/src/components/DisplayNames/types.ts b/src/components/DisplayNames/types.ts index 1b9a69510da3..c7d038997433 100644 --- a/src/components/DisplayNames/types.ts +++ b/src/components/DisplayNames/types.ts @@ -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[]; diff --git a/src/components/HeaderWithBackButton/types.ts b/src/components/HeaderWithBackButton/types.ts index 7bc7df03b639..65f9bb45b5d3 100644 --- a/src/components/HeaderWithBackButton/types.ts +++ b/src/components/HeaderWithBackButton/types.ts @@ -132,6 +132,9 @@ type HeaderWithBackButtonProps = Partial & { /** 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; diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx index e65cb65cd887..5edf63100af0 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN.tsx @@ -170,6 +170,8 @@ function OptionRowLHN({ 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; const alternateTextFSClass = FS.getChatFSClass(report); const onOptionPress = (event: GestureResponderEvent | KeyboardEvent | undefined) => { @@ -272,6 +274,7 @@ function OptionRowLHN({