From 56ca0a060c0d448127523bfa50d260f56b3bbaf1 Mon Sep 17 00:00:00 2001 From: artus9033 Date: Thu, 9 Nov 2023 12:02:07 +0100 Subject: [PATCH 1/5] fix: unify word breaking in ContextMenuItem for Android mweb and Android native --- src/components/ContextMenuItem.js | 2 +- src/pages/home/report/ContextMenu/ContextMenuActions.js | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/ContextMenuItem.js b/src/components/ContextMenuItem.js index 80d4855392a4..2782efac5164 100644 --- a/src/components/ContextMenuItem.js +++ b/src/components/ContextMenuItem.js @@ -96,7 +96,7 @@ function ContextMenuItem({onPress, successIcon, successText, icon, text, isMini, wrapperStyle={styles.pr9} success={!isThrottledButtonActive} description={description} - descriptionTextStyle={styles.breakAll} + descriptionTextStyle={styles.breakWord} style={getContextMenuItemStyles(windowWidth)} isAnonymousAction={isAnonymousAction} focused={isFocused} diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index 5a1266d15a42..2bd65d382fc0 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -246,7 +246,12 @@ export default [ Clipboard.setString(selection.replace('mailto:', '')); hideContextMenu(true, ReportActionComposeFocusManager.focus); }, - getDescription: (selection) => selection.replace('mailto:', ''), + getDescription: (selection) => + selection.replace('mailto:', '').replace( + /([.@])/g, + // below: zero-width space (U+200B) character + '​$1', + ), }, { isAnonymousAction: true, From 81a50658949868f7565831f9dc2a1e0a591c9fda Mon Sep 17 00:00:00 2001 From: artus9033 Date: Wed, 29 Nov 2023 09:54:31 +0100 Subject: [PATCH 2/5] refactor: extracted trimMailTo and prefixMailSeparatorsWithBreakOpportunities to separate functions in src/pages/home/report/ContextMenu/ContextMenuActions.js --- .../report/ContextMenu/ContextMenuActions.js | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index 2bd65d382fc0..d7d506d36fe5 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -33,6 +33,30 @@ function getActionText(reportAction) { return lodashGet(message, 'html', ''); } +/** + * Trims the `mailto:` part from email address. + * @param {string} email + * @returns {String} + */ +function trimMailTo(email) { + return email.replace('mailto:', ''); +} + +/** + * Prepends a zero-width space (U+200B) character before all `.` and `@` characters + * in the email addres to provide explicit line break opportunities for consistent + * breaking across platforms. + * @param {string} email + * @returns {String} + */ +function prefixMailSeparatorsWithBreakOpportunities(email) { + return email.replace( + /([.@])/g, + // below: zero-width space (U+200B) character + '​$1', + ); +} + const CONTEXT_MENU_TYPES = { LINK: 'LINK', REPORT_ACTION: 'REPORT_ACTION', @@ -243,15 +267,10 @@ export default [ successIcon: Expensicons.Checkmark, shouldShow: (type) => type === CONTEXT_MENU_TYPES.EMAIL, onPress: (closePopover, {selection}) => { - Clipboard.setString(selection.replace('mailto:', '')); + Clipboard.setString(trimMailTo(selection)); hideContextMenu(true, ReportActionComposeFocusManager.focus); }, - getDescription: (selection) => - selection.replace('mailto:', '').replace( - /([.@])/g, - // below: zero-width space (U+200B) character - '​$1', - ), + getDescription: (selection) => prefixMailSeparatorsWithBreakOpportunities(trimMailTo(selection)), }, { isAnonymousAction: true, From 4435513b72f7879a8d1346699ea947829a786b49 Mon Sep 17 00:00:00 2001 From: artus9033 Date: Wed, 29 Nov 2023 13:31:19 +0100 Subject: [PATCH 3/5] Moved trimMailTo and prefixMailSeparatorsWithBreakOpportunities to src/libs/EmailUtils.ts src/pages/home/report/ContextMenu/ContextMenuActions.js --- src/libs/EmailUtils.ts | 23 +++++++++++++++++ .../report/ContextMenu/ContextMenuActions.js | 25 +------------------ 2 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 src/libs/EmailUtils.ts diff --git a/src/libs/EmailUtils.ts b/src/libs/EmailUtils.ts new file mode 100644 index 000000000000..f81448c59a3f --- /dev/null +++ b/src/libs/EmailUtils.ts @@ -0,0 +1,23 @@ +/** + * Trims the `mailto:` part from mail link. + * @param mailLink - the `mailto:` link to be trimmed + * @returns The email address + */ +export function trimMailTo(mailLink: string) { + return mailLink.replace('mailto:', ''); +} + +/** + * Prepends a zero-width space (U+200B) character before all `.` and `@` characters + * in the email addres to provide explicit line break opportunities for consistent + * breaking across platforms. + * @param email - The email address to be sanitized + * @returns The email with inserted line break opportunities + */ +export function prefixMailSeparatorsWithBreakOpportunities(email: string) { + return email.replace( + /([.@])/g, + // below: zero-width space (U+200B) character + '​$1', + ); +} diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index d7d506d36fe5..00247767ae90 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -7,6 +7,7 @@ import MiniQuickEmojiReactions from '@components/Reactions/MiniQuickEmojiReactio import QuickEmojiReactions from '@components/Reactions/QuickEmojiReactions'; import addEncryptedAuthTokenToURL from '@libs/addEncryptedAuthTokenToURL'; import Clipboard from '@libs/Clipboard'; +import {prefixMailSeparatorsWithBreakOpportunities, trimMailTo} from '@libs/EmailUtils'; import * as Environment from '@libs/Environment/Environment'; import fileDownload from '@libs/fileDownload'; import getAttachmentDetails from '@libs/fileDownload/getAttachmentDetails'; @@ -33,30 +34,6 @@ function getActionText(reportAction) { return lodashGet(message, 'html', ''); } -/** - * Trims the `mailto:` part from email address. - * @param {string} email - * @returns {String} - */ -function trimMailTo(email) { - return email.replace('mailto:', ''); -} - -/** - * Prepends a zero-width space (U+200B) character before all `.` and `@` characters - * in the email addres to provide explicit line break opportunities for consistent - * breaking across platforms. - * @param {string} email - * @returns {String} - */ -function prefixMailSeparatorsWithBreakOpportunities(email) { - return email.replace( - /([.@])/g, - // below: zero-width space (U+200B) character - '​$1', - ); -} - const CONTEXT_MENU_TYPES = { LINK: 'LINK', REPORT_ACTION: 'REPORT_ACTION', From 1b49dec6b8985f9bc75bdeae3509d0c82ed6e6f7 Mon Sep 17 00:00:00 2001 From: artus9033 Date: Thu, 30 Nov 2023 10:25:32 +0100 Subject: [PATCH 4/5] Refactored src/libs/EmailUtils.ts - added additional explanation for function naming in comment --- src/libs/EmailUtils.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libs/EmailUtils.ts b/src/libs/EmailUtils.ts index f81448c59a3f..19c6393bb138 100644 --- a/src/libs/EmailUtils.ts +++ b/src/libs/EmailUtils.ts @@ -1,6 +1,6 @@ /** * Trims the `mailto:` part from mail link. - * @param mailLink - the `mailto:` link to be trimmed + * @param mailLink - The `mailto:` link to be trimmed * @returns The email address */ export function trimMailTo(mailLink: string) { @@ -9,8 +9,13 @@ export function trimMailTo(mailLink: string) { /** * Prepends a zero-width space (U+200B) character before all `.` and `@` characters - * in the email addres to provide explicit line break opportunities for consistent + * in the email address to provide explicit line break opportunities for consistent * breaking across platforms. + * + * Note: as explained [here](https://github.com/Expensify/App/issues/30985#issuecomment-1815379835), + * this only provides opportunities for line breaking (rather than forcing line breaks) that shall + * be used by the platform implementation when there are no other customary rules applicable + * and the text would otherwise overflow. * @param email - The email address to be sanitized * @returns The email with inserted line break opportunities */ From 1af318e7d1c59d90e675ed1d321b0bce57535f43 Mon Sep 17 00:00:00 2001 From: artus9033 Date: Thu, 7 Dec 2023 14:54:37 +0100 Subject: [PATCH 5/5] Fixed lint problems in EmailUtils --- src/libs/EmailUtils.ts | 6 ++++-- src/pages/home/report/ContextMenu/ContextMenuActions.js | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libs/EmailUtils.ts b/src/libs/EmailUtils.ts index 19c6393bb138..886823faae87 100644 --- a/src/libs/EmailUtils.ts +++ b/src/libs/EmailUtils.ts @@ -3,7 +3,7 @@ * @param mailLink - The `mailto:` link to be trimmed * @returns The email address */ -export function trimMailTo(mailLink: string) { +function trimMailTo(mailLink: string) { return mailLink.replace('mailto:', ''); } @@ -19,10 +19,12 @@ export function trimMailTo(mailLink: string) { * @param email - The email address to be sanitized * @returns The email with inserted line break opportunities */ -export function prefixMailSeparatorsWithBreakOpportunities(email: string) { +function prefixMailSeparatorsWithBreakOpportunities(email: string) { return email.replace( /([.@])/g, // below: zero-width space (U+200B) character '​$1', ); } + +export default {trimMailTo, prefixMailSeparatorsWithBreakOpportunities}; diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index 21ee92f18640..832b3352b2e5 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -7,7 +7,7 @@ import MiniQuickEmojiReactions from '@components/Reactions/MiniQuickEmojiReactio import QuickEmojiReactions from '@components/Reactions/QuickEmojiReactions'; import addEncryptedAuthTokenToURL from '@libs/addEncryptedAuthTokenToURL'; import Clipboard from '@libs/Clipboard'; -import {prefixMailSeparatorsWithBreakOpportunities, trimMailTo} from '@libs/EmailUtils'; +import EmailUtils from '@libs/EmailUtils'; import * as Environment from '@libs/Environment/Environment'; import fileDownload from '@libs/fileDownload'; import getAttachmentDetails from '@libs/fileDownload/getAttachmentDetails'; @@ -244,10 +244,10 @@ export default [ successIcon: Expensicons.Checkmark, shouldShow: (type) => type === CONTEXT_MENU_TYPES.EMAIL, onPress: (closePopover, {selection}) => { - Clipboard.setString(trimMailTo(selection)); + Clipboard.setString(EmailUtils.trimMailTo(selection)); hideContextMenu(true, ReportActionComposeFocusManager.focus); }, - getDescription: (selection) => prefixMailSeparatorsWithBreakOpportunities(trimMailTo(selection)), + getDescription: (selection) => EmailUtils.prefixMailSeparatorsWithBreakOpportunities(EmailUtils.trimMailTo(selection)), }, { isAnonymousAction: true,