diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.js b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.js index d2a88849dc34..c673677b73f2 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.js +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.js @@ -2,6 +2,7 @@ import _ from 'underscore'; import React from 'react'; import {Pressable, StyleSheet} from 'react-native'; import lodashGet from 'lodash/get'; +import Str from 'expensify-common/lib/str'; import Text from '../../Text'; import {propTypes, defaultProps} from '../anchorForCommentsOnlyPropTypes'; import PressableWithSecondaryInteraction from '../../PressableWithSecondaryInteraction'; @@ -44,12 +45,12 @@ class BaseAnchorForCommentsOnly extends React.Component { if (this.state.isDownloading) { return; } - this.processDownload(this.props.href, this.props.fileName); + this.processDownload(this.props.href, this.props.displayName); }} > @@ -61,7 +62,7 @@ class BaseAnchorForCommentsOnly extends React.Component { onSecondaryInteraction={ (event) => { ReportActionContextMenu.showContextMenu( - ContextMenuActions.CONTEXT_MENU_TYPES.LINK, + Str.isValidEmail(this.props.displayName) ? ContextMenuActions.CONTEXT_MENU_TYPES.EMAIL : ContextMenuActions.CONTEXT_MENU_TYPES.LINK, event, this.props.href, lodashGet(linkRef, 'current'), diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.native.js b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.native.js index c150a300b4ef..19e1b28774c2 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.native.js +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.native.js @@ -2,6 +2,7 @@ import _ from 'underscore'; import React from 'react'; import lodashGet from 'lodash/get'; import {Linking, StyleSheet, Pressable} from 'react-native'; +import Str from 'expensify-common/lib/str'; import {propTypes, defaultProps} from '../anchorForCommentsOnlyPropTypes'; import fileDownload from '../../../libs/fileDownload'; import Text from '../../Text'; @@ -47,12 +48,12 @@ class BaseAnchorForCommentsOnly extends React.Component { if (this.state.isDownloading) { return; } - this.processDownload(this.props.href, this.props.fileName); + this.processDownload(this.props.href, this.props.displayName); }} > @@ -64,7 +65,7 @@ class BaseAnchorForCommentsOnly extends React.Component { onSecondaryInteraction={ (event) => { ReportActionContextMenu.showContextMenu( - ContextMenuActions.CONTEXT_MENU_TYPES.LINK, + Str.isValidEmail(this.props.displayName) ? ContextMenuActions.CONTEXT_MENU_TYPES.EMAIL : ContextMenuActions.CONTEXT_MENU_TYPES.LINK, event, this.props.href, lodashGet(linkRef, 'current'), diff --git a/src/components/AnchorForCommentsOnly/anchorForCommentsOnlyPropTypes.js b/src/components/AnchorForCommentsOnly/anchorForCommentsOnlyPropTypes.js index 5beecad66f70..fd8b2148a4af 100644 --- a/src/components/AnchorForCommentsOnly/anchorForCommentsOnlyPropTypes.js +++ b/src/components/AnchorForCommentsOnly/anchorForCommentsOnlyPropTypes.js @@ -21,8 +21,8 @@ const propTypes = { /** Any children to display */ children: PropTypes.node, - /** Display label in case of attachments */ - fileName: PropTypes.string, + /** Filename in case of attachments, anchor text in case of URLs or emails. */ + displayName: PropTypes.string, /** Any additional styles to apply */ // eslint-disable-next-line react/forbid-prop-types @@ -37,7 +37,7 @@ const defaultProps = { isAttachment: false, children: null, style: {}, - fileName: '', + displayName: '', }; export {propTypes, defaultProps}; diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js index 62362d41b77d..6f53780a4eb4 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js @@ -17,7 +17,7 @@ const AnchorRenderer = (props) => { // An auth token is needed to download Expensify chat attachments const isAttachment = Boolean(htmlAttribs['data-expensify-source']); - const fileName = lodashGet(props.tnode, 'domNode.children[0].data', ''); + const displayName = lodashGet(props.tnode, 'domNode.children[0].data', ''); const parentStyle = lodashGet(props.tnode, 'parent.styles.nativeTextRet', {}); const attrHref = htmlAttribs.href || ''; const internalExpensifyPath = (attrHref.startsWith(CONST.NEW_EXPENSIFY_URL) && attrHref.replace(CONST.NEW_EXPENSIFY_URL, '')) @@ -64,7 +64,7 @@ const AnchorRenderer = (props) => { rel={htmlAttribs.rel || 'noopener noreferrer'} style={{...props.style, ...parentStyle}} key={props.key} - fileName={fileName} + displayName={displayName} > diff --git a/src/languages/en.js b/src/languages/en.js index a17924c1f7dc..7b0a19ce7841 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -165,6 +165,7 @@ export default { copied: 'Copied!', copyLink: 'Copy link', copyURLToClipboard: 'Copy URL to clipboard', + copyEmailToClipboard: 'Copy email to clipboard', markAsUnread: 'Mark as unread', editComment: 'Edit comment', deleteComment: 'Delete comment', diff --git a/src/languages/es.js b/src/languages/es.js index a247568bb3e5..5afc9ce79b1c 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -165,6 +165,7 @@ export default { copied: '¡Copiado!', copyLink: 'Copiar enlace', copyURLToClipboard: 'Copiar URL al portapapeles', + copyEmailToClipboard: 'Copiar email al portapapeles', markAsUnread: 'Marcar como no leído', editComment: 'Editar commentario', deleteComment: 'Eliminar comentario', diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index 34ca78008e41..381c9e304f91 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -22,6 +22,7 @@ function getActionText(reportAction) { const CONTEXT_MENU_TYPES = { LINK: 'LINK', REPORT_ACTION: 'REPORT_ACTION', + EMAIL: 'EMAIL', }; // A list of all the context actions in this menu. @@ -37,6 +38,17 @@ export default [ hideContextMenu(true, ReportActionComposeFocusManager.focus); }, }, + { + textTranslateKey: 'reportActionContextMenu.copyEmailToClipboard', + icon: Expensicons.Clipboard, + successTextTranslateKey: 'reportActionContextMenu.copied', + successIcon: Expensicons.Checkmark, + shouldShow: type => type === CONTEXT_MENU_TYPES.EMAIL, + onPress: (closePopover, {selection}) => { + Clipboard.setString(selection.replace('mailto:', '')); + hideContextMenu(true, ReportActionComposeFocusManager.focus); + }, + }, { textTranslateKey: 'reportActionContextMenu.copyToClipboard', icon: Expensicons.Clipboard, diff --git a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.js b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.js index f94105654eea..bb2668573d70 100644 --- a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.js +++ b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.js @@ -101,7 +101,7 @@ class PopoverReportActionContextMenu extends React.Component { /** * Show the ReportActionContextMenu modal popover. * - * @param {string} type - context menu type [LINK, REPORT_ACTION] + * @param {string} type - context menu type [EMAIL, LINK, REPORT_ACTION] * @param {Object} [event] - A press event. * @param {string} [selection] - A copy text. * @param {Element} contextMenuAnchor - popoverAnchor diff --git a/src/pages/home/report/ContextMenu/ReportActionContextMenu.js b/src/pages/home/report/ContextMenu/ReportActionContextMenu.js index ae82626a0704..8952287fa850 100644 --- a/src/pages/home/report/ContextMenu/ReportActionContextMenu.js +++ b/src/pages/home/report/ContextMenu/ReportActionContextMenu.js @@ -5,7 +5,7 @@ const contextMenuRef = React.createRef(); /** * Show the ReportActionContextMenu modal popover. * - * @param {string} type - the context menu type to display [LINK, REPORT_ACTION] + * @param {string} type - the context menu type to display [EMAIL, LINK, REPORT_ACTION] * @param {Object} [event] - A press event. * @param {string} [selection] - A copy text. * @param {Element} contextMenuAnchor - popoverAnchor