diff --git a/src/CONST.ts b/src/CONST.ts index 258a83190f32..c681d1fac1b0 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -3248,7 +3248,7 @@ const CONST = { EMOJI_NAME: /:[\p{L}0-9_+-]+:/gu, EMOJI_SUGGESTIONS: /:[\p{L}0-9_+-]{1,40}$/u, AFTER_FIRST_LINE_BREAK: /\n.*/g, - LINE_BREAK: /\r\n|\r|\n/g, + LINE_BREAK: /\r\n|\r|\n|\u2028/g, CODE_2FA: /^\d{6}$/, ATTACHMENT_ID: /chat-attachments\/(\d+)/, HAS_COLON_ONLY_AT_THE_BEGINNING: /^:[^:]+$/, diff --git a/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx b/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx index 0fb38f36ebd9..c4bcb31bd367 100644 --- a/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx +++ b/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx @@ -28,6 +28,7 @@ import {getAllTaxRates} from '@libs/PolicyUtils'; import type {OptionData} from '@libs/ReportUtils'; import {getAutocompleteQueryWithComma, getQueryWithoutAutocompletedPart} from '@libs/SearchAutocompleteUtils'; import {buildUserReadableQueryString, getQueryWithUpdatedValues, isDefaultExpensesQuery, sanitizeSearchValue} from '@libs/SearchQueryUtils'; +import StringUtils from '@libs/StringUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -130,11 +131,12 @@ function SearchPageHeaderInput({ const onSearchQueryChange = useCallback( (userQuery: string) => { - const updatedUserQuery = getAutocompleteQueryWithComma(textInputValue, userQuery); + const singleLineUserQuery = StringUtils.lineBreaksToSpaces(userQuery, true); + const updatedUserQuery = getAutocompleteQueryWithComma(textInputValue, singleLineUserQuery); setTextInputValue(updatedUserQuery); setAutocompleteQueryValue(updatedUserQuery); - const updatedSubstitutionsMap = getUpdatedSubstitutionsMap(userQuery, autocompleteSubstitutions); + const updatedSubstitutionsMap = getUpdatedSubstitutionsMap(singleLineUserQuery, autocompleteSubstitutions); if (!isEqual(autocompleteSubstitutions, updatedSubstitutionsMap)) { setAutocompleteSubstitutions(updatedSubstitutionsMap); } diff --git a/src/components/Search/SearchRouter/SearchRouter.tsx b/src/components/Search/SearchRouter/SearchRouter.tsx index 6574232d39cc..5281032967cf 100644 --- a/src/components/Search/SearchRouter/SearchRouter.tsx +++ b/src/components/Search/SearchRouter/SearchRouter.tsx @@ -26,6 +26,7 @@ import type {SearchOption} from '@libs/OptionsListUtils'; import type {OptionData} from '@libs/ReportUtils'; import {getAutocompleteQueryWithComma, getQueryWithoutAutocompletedPart} from '@libs/SearchAutocompleteUtils'; import {getQueryWithUpdatedValues, sanitizeSearchValue} from '@libs/SearchQueryUtils'; +import StringUtils from '@libs/StringUtils'; import Navigation from '@navigation/Navigation'; import type {ReportsSplitNavigatorParamList} from '@navigation/types'; import variables from '@styles/variables'; @@ -188,11 +189,12 @@ function SearchRouter({onRouterClose, shouldHideInputCaret}: SearchRouterProps, if (autoScrollToRight) { shouldScrollRef.current = true; } - const updatedUserQuery = getAutocompleteQueryWithComma(textInputValue, userQuery); + const singleLineUserQuery = StringUtils.lineBreaksToSpaces(userQuery, true); + const updatedUserQuery = getAutocompleteQueryWithComma(textInputValue, singleLineUserQuery); setTextInputValue(updatedUserQuery); setAutocompleteQueryValue(updatedUserQuery); - const updatedSubstitutionsMap = getUpdatedSubstitutionsMap(userQuery, autocompleteSubstitutions); + const updatedSubstitutionsMap = getUpdatedSubstitutionsMap(singleLineUserQuery, autocompleteSubstitutions); if (!isEqual(autocompleteSubstitutions, updatedSubstitutionsMap)) { setAutocompleteSubstitutions(updatedSubstitutionsMap); } diff --git a/src/libs/StringUtils.ts b/src/libs/StringUtils.ts index 2c528c33114a..79d9c0aa9d0b 100644 --- a/src/libs/StringUtils.ts +++ b/src/libs/StringUtils.ts @@ -1,6 +1,6 @@ import deburr from 'lodash/deburr'; import CONST from '@src/CONST'; -import * as Browser from './Browser'; +import {isSafari} from './Browser'; /** * Removes diacritical marks and non-alphabetic and non-latin characters from a string. @@ -38,7 +38,7 @@ function removeInvisibleCharacters(value: string): string { // - \u2060: word joiner result = result.replace(/[\u200B\u2060]/g, ''); - const invisibleCharacterRegex = Browser.isSafari() ? /([\uD800-\uDBFF][\uDC00-\uDFFF])|[\p{Cc}\p{Co}\p{Cn}]/gu : /[\p{Cc}\p{Cs}\p{Co}\p{Cn}]/gu; + const invisibleCharacterRegex = isSafari() ? /([\uD800-\uDBFF][\uDC00-\uDFFF])|[\p{Cc}\p{Co}\p{Cn}]/gu : /[\p{Cc}\p{Cs}\p{Co}\p{Cn}]/gu; // The control unicode (Cc) regex removes all newlines, // so we first split the string by newline and rejoin it afterward to retain the original line breaks. @@ -86,8 +86,8 @@ function normalizeCRLF(value?: string): string | undefined { /** * Replace all line breaks with white spaces */ -function lineBreaksToSpaces(text = '') { - return text.replace(CONST.REGEX.LINE_BREAK, ' '); +function lineBreaksToSpaces(text = '', useNonBreakingSpace = false) { + return text.replace(CONST.REGEX.LINE_BREAK, useNonBreakingSpace ? '\u00A0' : ' '); } /**