From fa0e58211054097f4c545db6f8e6a7b27aa3c90b Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Thu, 7 Dec 2023 15:17:29 +0100 Subject: [PATCH 1/9] [TS migration] Migrate 'AnchorForCommentsOnly' component --- ...sOnly.js => BaseAnchorForCommentsOnly.tsx} | 52 +++--- .../anchorForCommentsOnlyPropTypes.js | 35 ---- .../AnchorForCommentsOnly/index.native.js | 24 --- .../AnchorForCommentsOnly/index.native.tsx | 20 ++ .../{index.js => index.tsx} | 6 +- src/components/AnchorForCommentsOnly/types.ts | 23 +++ .../ContextMenu/ReportActionContextMenu.js | 138 -------------- .../ContextMenu/ReportActionContextMenu.ts | 172 ++++++++++++++++++ 8 files changed, 241 insertions(+), 229 deletions(-) rename src/components/AnchorForCommentsOnly/{BaseAnchorForCommentsOnly.js => BaseAnchorForCommentsOnly.tsx} (69%) delete mode 100644 src/components/AnchorForCommentsOnly/anchorForCommentsOnlyPropTypes.js delete mode 100644 src/components/AnchorForCommentsOnly/index.native.js create mode 100644 src/components/AnchorForCommentsOnly/index.native.tsx rename src/components/AnchorForCommentsOnly/{index.js => index.tsx} (69%) create mode 100644 src/components/AnchorForCommentsOnly/types.ts delete mode 100644 src/pages/home/report/ContextMenu/ReportActionContextMenu.js create mode 100644 src/pages/home/report/ContextMenu/ReportActionContextMenu.ts diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx similarity index 69% rename from src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js rename to src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx index 33d6cb014df2..9555e14ee1f8 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx @@ -1,9 +1,6 @@ import Str from 'expensify-common/lib/str'; -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React, {useEffect} from 'react'; -import {StyleSheet} from 'react-native'; -import _ from 'underscore'; +import React, {useEffect, useRef} from 'react'; +import {Text as RNText, StyleSheet} from 'react-native'; import PressableWithSecondaryInteraction from '@components/PressableWithSecondaryInteraction'; import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; @@ -14,25 +11,32 @@ import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportA import * as StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; -import {propTypes as anchorForCommentsOnlyPropTypes} from './anchorForCommentsOnlyPropTypes'; +import type AnchorForCommentsOnlyProps from './types'; -const propTypes = { +type BaseAnchorForCommentsOnlyProps = AnchorForCommentsOnlyProps & { /** Press in handler for the link */ - // eslint-disable-next-line react/require-default-props - onPressIn: PropTypes.func, + onPressIn?: () => void; /** Press out handler for the link */ - // eslint-disable-next-line react/require-default-props - onPressOut: PropTypes.func, + onPressOut?: () => void; +}; + +type LinkProps = { + /** Press handler for the link, when not passed, default href is used to create a link like behaviour */ + onPress?: () => Promise | void; - ...anchorForCommentsOnlyPropTypes, + /** The URL to open */ + href?: string; }; /* * This is a default anchor component for regular links. */ -function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', target = '', children = null, style = {}, onPress, ...rest}) { +function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', target = '', children = null, style, onPress, ...rest}: BaseAnchorForCommentsOnlyProps) { const styles = useThemeStyles(); + const linkRef = useRef(null); + const flattenStyle = StyleSheet.flatten(style); + useEffect( () => () => { ReportActionContextMenu.hideContextMenu(); @@ -42,10 +46,8 @@ function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', const {isSmallScreenWidth} = useWindowDimensions(); - let linkRef; - - const linkProps = {}; - if (_.isFunction(onPress)) { + const linkProps: LinkProps = {}; + if (typeof onPress === 'function') { linkProps.onPress = onPress; } else { linkProps.href = href; @@ -57,21 +59,16 @@ function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', { - ReportActionContextMenu.showContextMenu( - isEmail ? ContextMenuActions.CONTEXT_MENU_TYPES.EMAIL : ContextMenuActions.CONTEXT_MENU_TYPES.LINK, - event, - href, - lodashGet(linkRef, 'current'), - ); + ReportActionContextMenu.showContextMenu(isEmail ? ContextMenuActions.CONTEXT_MENU_TYPES.EMAIL : ContextMenuActions.CONTEXT_MENU_TYPES.LINK, event, href, linkRef.current); }} onPress={(event) => { if (!linkProps.onPress) { return; } - event.preventDefault(); + event?.preventDefault(); linkProps.onPress(); }} onPressIn={onPressIn} @@ -81,14 +78,14 @@ function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', > (linkRef = el)} + ref={linkRef} style={StyleSheet.flatten([style, defaultTextStyle])} role={CONST.ACCESSIBILITY_ROLE.LINK} hrefAttrs={{ rel, target: isEmail || !linkProps.href ? '_self' : target, }} - href={linkProps.href || href} + href={href} suppressHighlighting // Add testID so it gets selected as an anchor tag by SelectionScraper testID="a" @@ -102,7 +99,6 @@ function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', ); } -BaseAnchorForCommentsOnly.propTypes = propTypes; BaseAnchorForCommentsOnly.displayName = 'BaseAnchorForCommentsOnly'; export default BaseAnchorForCommentsOnly; diff --git a/src/components/AnchorForCommentsOnly/anchorForCommentsOnlyPropTypes.js b/src/components/AnchorForCommentsOnly/anchorForCommentsOnlyPropTypes.js deleted file mode 100644 index 6bf1d094497d..000000000000 --- a/src/components/AnchorForCommentsOnly/anchorForCommentsOnlyPropTypes.js +++ /dev/null @@ -1,35 +0,0 @@ -import PropTypes from 'prop-types'; -import stylePropTypes from '@styles/stylePropTypes'; - -const propTypes = { - /** The URL to open */ - href: PropTypes.string, - - /** What headers to send to the linked page (usually noopener and noreferrer) - This is unused in native, but is here for parity with web */ - rel: PropTypes.string, - - /** Used to determine where to open a link ("_blank" is passed for a new tab) - This is unused in native, but is here for parity with web */ - target: PropTypes.string, - - /** Any children to display */ - children: PropTypes.node, - - /** Any additional styles to apply */ - style: stylePropTypes, - - /** Press handler for the link, when not passed, default href is used to create a link like behaviour */ - onPress: PropTypes.func, -}; - -const defaultProps = { - href: '', - rel: '', - target: '', - children: null, - style: {}, - onPress: undefined, -}; - -export {propTypes, defaultProps}; diff --git a/src/components/AnchorForCommentsOnly/index.native.js b/src/components/AnchorForCommentsOnly/index.native.js deleted file mode 100644 index b9dc74b7ba05..000000000000 --- a/src/components/AnchorForCommentsOnly/index.native.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import {Linking} from 'react-native'; -import _ from 'underscore'; -import * as anchorForCommentsOnlyPropTypes from './anchorForCommentsOnlyPropTypes'; -import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; - -// eslint-disable-next-line react/jsx-props-no-spreading -function AnchorForCommentsOnly(props) { - const onPress = () => (_.isFunction(props.onPress) ? props.onPress() : Linking.openURL(props.href)); - - return ( - - ); -} - -AnchorForCommentsOnly.propTypes = anchorForCommentsOnlyPropTypes.propTypes; -AnchorForCommentsOnly.defaultProps = anchorForCommentsOnlyPropTypes.defaultProps; -AnchorForCommentsOnly.displayName = 'AnchorForCommentsOnly'; - -export default AnchorForCommentsOnly; diff --git a/src/components/AnchorForCommentsOnly/index.native.tsx b/src/components/AnchorForCommentsOnly/index.native.tsx new file mode 100644 index 000000000000..2d5063b752af --- /dev/null +++ b/src/components/AnchorForCommentsOnly/index.native.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import {Linking} from 'react-native'; +import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; +import type AnchorForCommentsOnlyProps from './types'; + +function AnchorForCommentsOnly(props: AnchorForCommentsOnlyProps) { + const onPress = () => (typeof props.onPress === 'function' ? props.onPress() : Linking.openURL(props.href ?? '')); + + return ( + + ); +} + +AnchorForCommentsOnly.displayName = 'AnchorForCommentsOnly'; + +export default AnchorForCommentsOnly; diff --git a/src/components/AnchorForCommentsOnly/index.js b/src/components/AnchorForCommentsOnly/index.tsx similarity index 69% rename from src/components/AnchorForCommentsOnly/index.js rename to src/components/AnchorForCommentsOnly/index.tsx index 24a903dca5fa..b76a8b6a3718 100644 --- a/src/components/AnchorForCommentsOnly/index.js +++ b/src/components/AnchorForCommentsOnly/index.tsx @@ -1,10 +1,10 @@ import React from 'react'; import ControlSelection from '@libs/ControlSelection'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import * as anchorForCommentsOnlyPropTypes from './anchorForCommentsOnlyPropTypes'; import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; +import type AnchorForCommentsOnlyProps from './types'; -function AnchorForCommentsOnly(props) { +function AnchorForCommentsOnly(props: AnchorForCommentsOnlyProps) { return ( ; + + /** Press handler for the link, when not passed, default href is used to create a link like behaviour */ + onPress?: () => Promise | void; +}; + +export default AnchorForCommentsOnlyProps; diff --git a/src/pages/home/report/ContextMenu/ReportActionContextMenu.js b/src/pages/home/report/ContextMenu/ReportActionContextMenu.js deleted file mode 100644 index 9467ff19b2f5..000000000000 --- a/src/pages/home/report/ContextMenu/ReportActionContextMenu.js +++ /dev/null @@ -1,138 +0,0 @@ -import React from 'react'; - -const contextMenuRef = React.createRef(); - -/** - * Hide the ReportActionContextMenu modal popover. - * Hides the popover menu with an optional delay - * @param {Boolean} shouldDelay - whether the menu should close after a delay - * @param {Function} [onHideCallback=() => {}] - Callback to be called after Context Menu is completely hidden - */ -function hideContextMenu(shouldDelay, onHideCallback = () => {}) { - if (!contextMenuRef.current) { - return; - } - if (!shouldDelay) { - contextMenuRef.current.hideContextMenu(onHideCallback); - - return; - } - - // Save the active instanceID for which hide action was called. - // If menu is being closed with a delay, check that whether the same instance exists or a new was created. - // If instance is not same, cancel the hide action - const instanceID = contextMenuRef.current.instanceID; - setTimeout(() => { - if (contextMenuRef.current.instanceID !== instanceID) { - return; - } - - contextMenuRef.current.hideContextMenu(onHideCallback); - }, 800); -} - -/** - * Show the ReportActionContextMenu modal popover. - * - * @param {string} type - the context menu type to display [EMAIL, LINK, REPORT_ACTION, REPORT] - * @param {Object} [event] - A press event. - * @param {String} [selection] - Copied content. - * @param {Element} contextMenuAnchor - popoverAnchor - * @param {String} reportID - Active Report Id - * @param {String} reportActionID - ReportActionID for ContextMenu - * @param {String} originalReportID - The currrent Report Id of the reportAction - * @param {String} draftMessage - ReportAction Draftmessage - * @param {Function} [onShow=() => {}] - Run a callback when Menu is shown - * @param {Function} [onHide=() => {}] - Run a callback when Menu is hidden - * @param {Boolean} isArchivedRoom - Whether the provided report is an archived room - * @param {Boolean} isChronosReport - Flag to check if the chat participant is Chronos - * @param {Boolean} isPinnedChat - Flag to check if the chat is pinned in the LHN. Used for the Pin/Unpin action - * @param {Boolean} isUnreadChat - Flag to check if the chat has unread messages in the LHN. Used for the Mark as Read/Unread action - */ -function showContextMenu( - type, - event, - selection, - contextMenuAnchor, - reportID = '0', - reportActionID = '0', - originalReportID = '0', - draftMessage = '', - onShow = () => {}, - onHide = () => {}, - isArchivedRoom = false, - isChronosReport = false, - isPinnedChat = false, - isUnreadChat = false, -) { - if (!contextMenuRef.current) { - return; - } - // If there is an already open context menu, close it first before opening - // a new one. - if (contextMenuRef.current.instanceID) { - hideContextMenu(); - contextMenuRef.current.runAndResetOnPopoverHide(); - } - - contextMenuRef.current.showContextMenu( - type, - event, - selection, - contextMenuAnchor, - reportID, - reportActionID, - originalReportID, - draftMessage, - onShow, - onHide, - isArchivedRoom, - isChronosReport, - isPinnedChat, - isUnreadChat, - ); -} - -function hideDeleteModal() { - if (!contextMenuRef.current) { - return; - } - contextMenuRef.current.hideDeleteModal(); -} - -/** - * Opens the Confirm delete action modal - * @param {String} reportID - * @param {Object} reportAction - * @param {Boolean} [shouldSetModalVisibility] - * @param {Function} [onConfirm] - * @param {Function} [onCancel] - */ -function showDeleteModal(reportID, reportAction, shouldSetModalVisibility, onConfirm, onCancel) { - if (!contextMenuRef.current) { - return; - } - contextMenuRef.current.showDeleteModal(reportID, reportAction, shouldSetModalVisibility, onConfirm, onCancel); -} - -/** - * Whether Context Menu is active for the Report Action. - * - * @param {Number|String} actionID - * @return {Boolean} - */ -function isActiveReportAction(actionID) { - if (!contextMenuRef.current) { - return; - } - return contextMenuRef.current.isActiveReportAction(actionID); -} - -function clearActiveReportAction() { - if (!contextMenuRef.current) { - return; - } - return contextMenuRef.current.clearActiveReportAction(); -} - -export {contextMenuRef, showContextMenu, hideContextMenu, isActiveReportAction, clearActiveReportAction, showDeleteModal, hideDeleteModal}; diff --git a/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts b/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts new file mode 100644 index 000000000000..2ff41df7b4f4 --- /dev/null +++ b/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts @@ -0,0 +1,172 @@ +import React from 'react'; +import {GestureResponderEvent, Text as RNText} from 'react-native'; +import {OnyxEntry} from 'react-native-onyx'; +import {ValueOf} from 'type-fest'; +import {CONTEXT_MENU_TYPES} from '@pages/home/report/ContextMenu/ContextMenuActions'; +import type {ReportAction} from '@src/types/onyx'; + +type OnHideCallback = () => void; + +type OnConfirm = () => void; + +type OnCancel = () => void; + +type ContextMenuType = ValueOf; + +type ShowContextMenu = ( + type: ContextMenuType, + event: GestureResponderEvent | MouseEvent, + selection: string, + contextMenuAnchor: RNText | null, + reportID?: string, + reportActionID?: string, + originalReportID?: string, + draftMessage?: string, + onShow?: () => void, + onHide?: () => void, + isArchivedRoom?: boolean, + isChronosReport?: boolean, + isPinnedChat?: boolean, + isUnreadChat?: boolean, +) => void; + +type ReportActionContextMenu = { + showContextMenu: ShowContextMenu; + hideContextMenu: (callback: OnHideCallback) => void; + showDeleteModal: (reportID: string, reportAction: OnyxEntry, shouldSetModalVisibility?: boolean, onConfirm?: OnConfirm, onCancel?: OnCancel) => void; + hideDeleteModal: () => void; + isActiveReportAction: (accountID: string | number) => boolean; + instanceID: string; + runAndResetOnPopoverHide: () => void; + clearActiveReportAction: () => void; +}; + +const contextMenuRef = React.createRef(); + +/** + * Hide the ReportActionContextMenu modal popover. + * Hides the popover menu with an optional delay + * @param [shouldDelay] - whether the menu should close after a delay + * @param [onHideCallback] - Callback to be called after Context Menu is completely hidden + */ +function hideContextMenu(shouldDelay?: boolean, onHideCallback = () => {}) { + if (!contextMenuRef.current) { + return; + } + if (!shouldDelay) { + contextMenuRef.current.hideContextMenu(onHideCallback); + + return; + } + + // Save the active instanceID for which hide action was called. + // If menu is being closed with a delay, check that whether the same instance exists or a new was created. + // If instance is not same, cancel the hide action + const instanceID = contextMenuRef.current.instanceID; + setTimeout(() => { + if (contextMenuRef.current?.instanceID !== instanceID) { + return; + } + + contextMenuRef.current.hideContextMenu(onHideCallback); + }, 800); +} + +/** + * Show the ReportActionContextMenu modal popover. + * + * @param type - the context menu type to display [EMAIL, LINK, REPORT_ACTION, REPORT] + * @param [event] - A press event. + * @param [selection] - Copied content. + * @param contextMenuAnchor - popoverAnchor + * @param reportID - Active Report Id + * @param reportActionID - ReportActionID for ContextMenu + * @param originalReportID - The currrent Report Id of the reportAction + * @param draftMessage - ReportAction Draftmessage + * @param [onShow=() => {}] - Run a callback when Menu is shown + * @param [onHide=() => {}] - Run a callback when Menu is hidden + * @param isArchivedRoom - Whether the provided report is an archived room + * @param isChronosReport - Flag to check if the chat participant is Chronos + * @param isPinnedChat - Flag to check if the chat is pinned in the LHN. Used for the Pin/Unpin action + * @param isUnreadChat - Flag to check if the chat has unread messages in the LHN. Used for the Mark as Read/Unread action + */ +function showContextMenu( + type: ContextMenuType, + event: GestureResponderEvent | MouseEvent, + selection: string, + contextMenuAnchor: RNText | null, + reportID = '0', + reportActionID = '0', + originalReportID = '0', + draftMessage = '', + onShow = () => {}, + onHide = () => {}, + isArchivedRoom = false, + isChronosReport = false, + isPinnedChat = false, + isUnreadChat = false, +) { + if (!contextMenuRef.current) { + return; + } + // If there is an already open context menu, close it first before opening + // a new one. + if (contextMenuRef.current.instanceID) { + hideContextMenu(); + contextMenuRef.current.runAndResetOnPopoverHide(); + } + + contextMenuRef.current.showContextMenu( + type, + event, + selection, + contextMenuAnchor, + reportID, + reportActionID, + originalReportID, + draftMessage, + onShow, + onHide, + isArchivedRoom, + isChronosReport, + isPinnedChat, + isUnreadChat, + ); +} + +function hideDeleteModal() { + if (!contextMenuRef.current) { + return; + } + contextMenuRef.current.hideDeleteModal(); +} + +/** + * Opens the Confirm delete action modal + */ +function showDeleteModal(reportID: string, reportAction: OnyxEntry, shouldSetModalVisibility?: boolean, onConfirm?: OnConfirm, onCancel?: OnCancel) { + if (!contextMenuRef.current) { + return; + } + contextMenuRef.current.showDeleteModal(reportID, reportAction, shouldSetModalVisibility, onConfirm, onCancel); +} + +/** + * Whether Context Menu is active for the Report Action. + */ +function isActiveReportAction(actionID: string | number): boolean { + if (!contextMenuRef.current) { + return false; + } + return contextMenuRef.current.isActiveReportAction(actionID); +} + +function clearActiveReportAction() { + if (!contextMenuRef.current) { + return; + } + + return contextMenuRef.current.clearActiveReportAction(); +} + +export {contextMenuRef, showContextMenu, hideContextMenu, isActiveReportAction, clearActiveReportAction, showDeleteModal, hideDeleteModal}; From 1112a8b82973d5298aac928e309cf3015c8c96ef Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Thu, 7 Dec 2023 15:22:10 +0100 Subject: [PATCH 2/9] Add props destructuring --- src/components/AnchorForCommentsOnly/index.native.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/AnchorForCommentsOnly/index.native.tsx b/src/components/AnchorForCommentsOnly/index.native.tsx index 2d5063b752af..453e2ad7f555 100644 --- a/src/components/AnchorForCommentsOnly/index.native.tsx +++ b/src/components/AnchorForCommentsOnly/index.native.tsx @@ -3,14 +3,15 @@ import {Linking} from 'react-native'; import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; import type AnchorForCommentsOnlyProps from './types'; -function AnchorForCommentsOnly(props: AnchorForCommentsOnlyProps) { - const onPress = () => (typeof props.onPress === 'function' ? props.onPress() : Linking.openURL(props.href ?? '')); +function AnchorForCommentsOnly({onPress, href, ...props}: AnchorForCommentsOnlyProps) { + const onLinkPress = () => (typeof onPress === 'function' ? onPress() : Linking.openURL(href ?? '')); return ( ); } From d70f96ba11e935b0a4b2f62e929a5b0b4326fb49 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Thu, 7 Dec 2023 15:39:52 +0100 Subject: [PATCH 3/9] Update import --- src/pages/home/report/ContextMenu/ReportActionContextMenu.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts b/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts index 2ff41df7b4f4..ff6f6bb09738 100644 --- a/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts +++ b/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts @@ -2,8 +2,9 @@ import React from 'react'; import {GestureResponderEvent, Text as RNText} from 'react-native'; import {OnyxEntry} from 'react-native-onyx'; import {ValueOf} from 'type-fest'; -import {CONTEXT_MENU_TYPES} from '@pages/home/report/ContextMenu/ContextMenuActions'; import type {ReportAction} from '@src/types/onyx'; +// eslint-disable-next-line import/no-cycle +import {CONTEXT_MENU_TYPES} from './ContextMenuActions'; type OnHideCallback = () => void; From de21d8d2ce255e080c9041a157ca27be53846ea2 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Fri, 8 Dec 2023 08:59:28 +0100 Subject: [PATCH 4/9] Add comment; use condition block for better readability --- src/components/AnchorForCommentsOnly/index.native.tsx | 8 +++++++- .../home/report/ContextMenu/ReportActionContextMenu.ts | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/AnchorForCommentsOnly/index.native.tsx b/src/components/AnchorForCommentsOnly/index.native.tsx index 453e2ad7f555..d1b0bda0a595 100644 --- a/src/components/AnchorForCommentsOnly/index.native.tsx +++ b/src/components/AnchorForCommentsOnly/index.native.tsx @@ -4,7 +4,13 @@ import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; import type AnchorForCommentsOnlyProps from './types'; function AnchorForCommentsOnly({onPress, href, ...props}: AnchorForCommentsOnlyProps) { - const onLinkPress = () => (typeof onPress === 'function' ? onPress() : Linking.openURL(href ?? '')); + const onLinkPress = () => { + if (typeof onPress === 'function') { + onPress(); + } else { + Linking.openURL(href ?? ''); + } + }; return ( Date: Fri, 8 Dec 2023 13:16:08 +0100 Subject: [PATCH 5/9] Update onPress type, simplify check --- .../AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx | 4 ++-- src/components/AnchorForCommentsOnly/index.native.tsx | 2 +- src/components/AnchorForCommentsOnly/types.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx index a80ed511c82a..fca1fe1decdf 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx @@ -23,7 +23,7 @@ type BaseAnchorForCommentsOnlyProps = AnchorForCommentsOnlyProps & { type LinkProps = { /** Press handler for the link, when not passed, default href is used to create a link like behaviour */ - onPress?: () => Promise | void; + onPress?: () => void; /** The URL to open */ href?: string; @@ -48,7 +48,7 @@ function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', const {isSmallScreenWidth} = useWindowDimensions(); const linkProps: LinkProps = {}; - if (typeof onPress === 'function') { + if (onPress) { linkProps.onPress = onPress; } else { linkProps.href = href; diff --git a/src/components/AnchorForCommentsOnly/index.native.tsx b/src/components/AnchorForCommentsOnly/index.native.tsx index d1b0bda0a595..3942a10be0c4 100644 --- a/src/components/AnchorForCommentsOnly/index.native.tsx +++ b/src/components/AnchorForCommentsOnly/index.native.tsx @@ -5,7 +5,7 @@ import type AnchorForCommentsOnlyProps from './types'; function AnchorForCommentsOnly({onPress, href, ...props}: AnchorForCommentsOnlyProps) { const onLinkPress = () => { - if (typeof onPress === 'function') { + if (onPress) { onPress(); } else { Linking.openURL(href ?? ''); diff --git a/src/components/AnchorForCommentsOnly/types.ts b/src/components/AnchorForCommentsOnly/types.ts index 280992b83eb4..7167ce320ada 100644 --- a/src/components/AnchorForCommentsOnly/types.ts +++ b/src/components/AnchorForCommentsOnly/types.ts @@ -17,7 +17,7 @@ type AnchorForCommentsOnlyProps = ChildrenProps & { style: StyleProp; /** Press handler for the link, when not passed, default href is used to create a link like behaviour */ - onPress?: () => Promise | void; + onPress?: () => void; }; export default AnchorForCommentsOnlyProps; From e5baca50fc2d1276596795e574ce9cdfe5b29d05 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Fri, 8 Dec 2023 13:32:46 +0100 Subject: [PATCH 6/9] Move CONTEXT_MENU_TYPES to CONST --- src/CONST.ts | 8 ++++ .../BaseAnchorForCommentsOnly.tsx | 3 +- src/components/LHNOptionsList/OptionRowLHN.js | 3 +- src/components/MenuItemList.js | 6 +-- src/components/ShowContextMenuContext.js | 4 +- .../BaseReportActionContextMenu.js | 4 +- .../report/ContextMenu/ContextMenuActions.js | 37 +++++++------------ .../ContextMenu/ReportActionContextMenu.ts | 5 +-- src/pages/home/report/ReportActionItem.js | 3 +- src/pages/settings/AboutPage/AboutPage.js | 3 +- src/pages/settings/AppDownloadLinks.js | 3 +- src/pages/settings/InitialSettingsPage.js | 3 +- 12 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index ebba780fd745..fa6652fe412e 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2895,6 +2895,14 @@ const CONST = { DEFAULT: 5, CAROUSEL: 3, }, + + /** Context menu types */ + CONTEXT_MENU_TYPES: { + LINK: 'LINK', + REPORT_ACTION: 'REPORT_ACTION', + EMAIL: 'EMAIL', + REPORT: 'REPORT', + }, } as const; export default CONST; diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx index fca1fe1decdf..73bd48dcf316 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx @@ -6,7 +6,6 @@ import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import * as ContextMenuActions from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; @@ -62,7 +61,7 @@ function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', suppressHighlighting style={[styles.cursorDefault, !!flattenStyle.fontSize && StyleUtils.getFontSizeStyle(flattenStyle.fontSize)]} onSecondaryInteraction={(event) => { - ReportActionContextMenu.showContextMenu(isEmail ? ContextMenuActions.CONTEXT_MENU_TYPES.EMAIL : ContextMenuActions.CONTEXT_MENU_TYPES.LINK, event, href, linkRef.current); + ReportActionContextMenu.showContextMenu(isEmail ? CONST.CONTEXT_MENU_TYPES.EMAIL : CONST.CONTEXT_MENU_TYPES.LINK, event, href, linkRef.current); }} onPress={(event) => { if (!linkProps.onPress) { diff --git a/src/components/LHNOptionsList/OptionRowLHN.js b/src/components/LHNOptionsList/OptionRowLHN.js index 053f201ac109..2abe2160dcfe 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.js +++ b/src/components/LHNOptionsList/OptionRowLHN.js @@ -22,7 +22,6 @@ import {getGroupChatName} from '@libs/GroupChatUtils'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; import * as ReportUtils from '@libs/ReportUtils'; -import * as ContextMenuActions from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import useTheme from '@styles/themes/useTheme'; import useStyleUtils from '@styles/useStyleUtils'; @@ -130,7 +129,7 @@ function OptionRowLHN(props) { } setIsContextMenuActive(true); ReportActionContextMenu.showContextMenu( - ContextMenuActions.CONTEXT_MENU_TYPES.REPORT, + CONST.CONTEXT_MENU_TYPES.REPORT, event, '', popoverAnchor, diff --git a/src/components/MenuItemList.js b/src/components/MenuItemList.js index b9f2e6fc228b..c9eee8e888e1 100644 --- a/src/components/MenuItemList.js +++ b/src/components/MenuItemList.js @@ -2,8 +2,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import _ from 'underscore'; import useSingleExecution from '@hooks/useSingleExecution'; -import {CONTEXT_MENU_TYPES} from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; +import CONST from '@src/CONST'; import MenuItem from './MenuItem'; import menuItemPropTypes from './menuItemPropTypes'; @@ -31,9 +31,9 @@ function MenuItemList(props) { */ const secondaryInteraction = (link, e) => { if (typeof link === 'function') { - link().then((url) => ReportActionContextMenu.showContextMenu(CONTEXT_MENU_TYPES.LINK, e, url, popoverAnchor)); + link().then((url) => ReportActionContextMenu.showContextMenu(CONST.CONTEXT_MENU_TYPES.LINK, e, url, popoverAnchor)); } else if (!_.isEmpty(link)) { - ReportActionContextMenu.showContextMenu(CONTEXT_MENU_TYPES.LINK, e, link, popoverAnchor); + ReportActionContextMenu.showContextMenu(CONST.CONTEXT_MENU_TYPES.LINK, e, link, popoverAnchor); } }; diff --git a/src/components/ShowContextMenuContext.js b/src/components/ShowContextMenuContext.js index 6248478e5fea..28822451956d 100644 --- a/src/components/ShowContextMenuContext.js +++ b/src/components/ShowContextMenuContext.js @@ -1,8 +1,8 @@ import React from 'react'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as ReportUtils from '@libs/ReportUtils'; -import * as ContextMenuActions from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; +import CONST from '@src/CONST'; const ShowContextMenuContext = React.createContext({ anchor: null, @@ -28,7 +28,7 @@ function showContextMenuForReport(event, anchor, reportID, action, checkIfContex return; } ReportActionContextMenu.showContextMenu( - ContextMenuActions.CONTEXT_MENU_TYPES.REPORT_ACTION, + CONST.CONTEXT_MENU_TYPES.REPORT_ACTION, event, '', anchor, diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js index 33adfa4b35f9..71942377d816 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js @@ -16,7 +16,7 @@ import useStyleUtils from '@styles/useStyleUtils'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ContextMenuActions, {CONTEXT_MENU_TYPES} from './ContextMenuActions'; +import ContextMenuActions from './ContextMenuActions'; import {defaultProps as GenericReportActionContextMenuDefaultProps, propTypes as genericReportActionContextMenuPropTypes} from './genericReportActionContextMenuPropTypes'; import {hideContextMenu} from './ReportActionContextMenu'; @@ -41,7 +41,7 @@ const propTypes = { }; const defaultProps = { - type: CONTEXT_MENU_TYPES.REPORT_ACTION, + type: CONST.CONTEXT_MENU_TYPES.REPORT_ACTION, anchor: null, contentRef: null, isChronosReport: false, diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index 4f35926c5957..d82ae47c2d03 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -33,19 +33,12 @@ function getActionText(reportAction) { return lodashGet(message, 'html', ''); } -const CONTEXT_MENU_TYPES = { - LINK: 'LINK', - REPORT_ACTION: 'REPORT_ACTION', - EMAIL: 'EMAIL', - REPORT: 'REPORT', -}; - // A list of all the context actions in this menu. export default [ { isAnonymousAction: false, shouldKeepOpen: true, - shouldShow: (type, reportAction) => type === CONTEXT_MENU_TYPES.REPORT_ACTION && _.has(reportAction, 'message') && !ReportActionsUtils.isMessageDeleted(reportAction), + shouldShow: (type, reportAction) => type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && _.has(reportAction, 'message') && !ReportActionsUtils.isMessageDeleted(reportAction), renderContent: (closePopover, {reportID, reportAction, close: closeManually, openContextMenu}) => { const isMini = !closePopover; @@ -122,7 +115,7 @@ export default [ successTextTranslateKey: '', successIcon: null, shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID) => { - if (type !== CONTEXT_MENU_TYPES.REPORT_ACTION) { + if (type !== CONST.CONTEXT_MENU_TYPES.REPORT_ACTION) { return false; } const isCommentAction = reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT; @@ -195,7 +188,7 @@ export default [ childReportNotificationPreference = isActionCreator ? CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS : CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; } const subscribed = childReportNotificationPreference !== 'hidden'; - if (type !== CONTEXT_MENU_TYPES.REPORT_ACTION) { + if (type !== CONST.CONTEXT_MENU_TYPES.REPORT_ACTION) { return false; } const isCommentAction = reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT && !ReportUtils.isThreadFirstChat(reportAction, reportID); @@ -228,7 +221,7 @@ export default [ icon: Expensicons.Copy, successTextTranslateKey: 'reportActionContextMenu.copied', successIcon: Expensicons.Checkmark, - shouldShow: (type) => type === CONTEXT_MENU_TYPES.LINK, + shouldShow: (type) => type === CONST.CONTEXT_MENU_TYPES.LINK, onPress: (closePopover, {selection}) => { Clipboard.setString(selection); hideContextMenu(true, ReportActionComposeFocusManager.focus); @@ -241,7 +234,7 @@ export default [ icon: Expensicons.Copy, successTextTranslateKey: 'reportActionContextMenu.copied', successIcon: Expensicons.Checkmark, - shouldShow: (type) => type === CONTEXT_MENU_TYPES.EMAIL, + shouldShow: (type) => type === CONST.CONTEXT_MENU_TYPES.EMAIL, onPress: (closePopover, {selection}) => { Clipboard.setString(selection.replace('mailto:', '')); hideContextMenu(true, ReportActionComposeFocusManager.focus); @@ -255,7 +248,7 @@ export default [ successTextTranslateKey: 'reportActionContextMenu.copied', successIcon: Expensicons.Checkmark, shouldShow: (type, reportAction) => - type === CONTEXT_MENU_TYPES.REPORT_ACTION && !ReportActionsUtils.isReportActionAttachment(reportAction) && !ReportActionsUtils.isMessageDeleted(reportAction), + type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && !ReportActionsUtils.isReportActionAttachment(reportAction) && !ReportActionsUtils.isMessageDeleted(reportAction), // If return value is true, we switch the `text` and `icon` on // `ContextMenuItem` with `successText` and `successIcon` which will fallback to @@ -313,7 +306,7 @@ export default [ // Only hide the copylink menu item when context menu is opened over img element. const isAttachmentTarget = lodashGet(menuTarget, 'tagName') === 'IMG' && isAttachment; - return Permissions.canUseCommentLinking(betas) && type === CONTEXT_MENU_TYPES.REPORT_ACTION && !isAttachmentTarget && !ReportActionsUtils.isMessageDeleted(reportAction); + return Permissions.canUseCommentLinking(betas) && type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && !isAttachmentTarget && !ReportActionsUtils.isMessageDeleted(reportAction); }, onPress: (closePopover, {reportAction, reportID}) => { Environment.getEnvironmentURL().then((environmentURL) => { @@ -331,7 +324,7 @@ export default [ icon: Expensicons.Mail, successIcon: Expensicons.Checkmark, shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat, isUnreadChat) => - type === CONTEXT_MENU_TYPES.REPORT_ACTION || (type === CONTEXT_MENU_TYPES.REPORT && !isUnreadChat), + type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION || (type === CONST.CONTEXT_MENU_TYPES.REPORT && !isUnreadChat), onPress: (closePopover, {reportAction, reportID}) => { Report.markCommentAsUnread(reportID, reportAction.created); if (closePopover) { @@ -346,7 +339,7 @@ export default [ textTranslateKey: 'reportActionContextMenu.markAsRead', icon: Expensicons.Mail, successIcon: Expensicons.Checkmark, - shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat, isUnreadChat) => type === CONTEXT_MENU_TYPES.REPORT && isUnreadChat, + shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat, isUnreadChat) => type === CONST.CONTEXT_MENU_TYPES.REPORT && isUnreadChat, onPress: (closePopover, {reportID}) => { Report.readNewestAction(reportID); if (closePopover) { @@ -361,7 +354,7 @@ export default [ textTranslateKey: 'reportActionContextMenu.editAction', icon: Expensicons.Pencil, shouldShow: (type, reportAction, isArchivedRoom, betas, menuTarget, isChronosReport) => - type === CONTEXT_MENU_TYPES.REPORT_ACTION && ReportUtils.canEditReportAction(reportAction) && !isArchivedRoom && !isChronosReport, + type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && ReportUtils.canEditReportAction(reportAction) && !isArchivedRoom && !isChronosReport, onPress: (closePopover, {reportID, reportAction, draftMessage}) => { if (ReportActionsUtils.isMoneyRequestAction(reportAction)) { hideContextMenu(false); @@ -396,7 +389,7 @@ export default [ icon: Expensicons.Trashcan, shouldShow: (type, reportAction, isArchivedRoom, betas, menuTarget, isChronosReport, reportID) => // Until deleting parent threads is supported in FE, we will prevent the user from deleting a thread parent - type === CONTEXT_MENU_TYPES.REPORT_ACTION && + type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && ReportUtils.canDeleteReportAction(reportAction, reportID) && !isArchivedRoom && !isChronosReport && @@ -418,7 +411,7 @@ export default [ textTranslateKey: 'common.pin', icon: Expensicons.Pin, shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat) => - type === CONTEXT_MENU_TYPES.REPORT && !isPinnedChat && !ReportUtils.isMoneyRequestReport(reportID), + type === CONST.CONTEXT_MENU_TYPES.REPORT && !isPinnedChat && !ReportUtils.isMoneyRequestReport(reportID), onPress: (closePopover, {reportID}) => { Report.togglePinnedState(reportID, false); if (closePopover) { @@ -432,7 +425,7 @@ export default [ textTranslateKey: 'common.unPin', icon: Expensicons.Pin, shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat) => - type === CONTEXT_MENU_TYPES.REPORT && isPinnedChat && !ReportUtils.isMoneyRequestReport(reportID), + type === CONST.CONTEXT_MENU_TYPES.REPORT && isPinnedChat && !ReportUtils.isMoneyRequestReport(reportID), onPress: (closePopover, {reportID}) => { Report.togglePinnedState(reportID, true); if (closePopover) { @@ -446,7 +439,7 @@ export default [ textTranslateKey: 'reportActionContextMenu.flagAsOffensive', icon: Expensicons.Flag, shouldShow: (type, reportAction, isArchivedRoom, betas, menuTarget, isChronosReport, reportID) => - type === CONTEXT_MENU_TYPES.REPORT_ACTION && + type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && ReportUtils.canFlagReportAction(reportAction, reportID) && !isArchivedRoom && !isChronosReport && @@ -463,5 +456,3 @@ export default [ getDescription: () => {}, }, ]; - -export {CONTEXT_MENU_TYPES}; diff --git a/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts b/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts index d57a8708d967..b269bc276b55 100644 --- a/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts +++ b/src/pages/home/report/ContextMenu/ReportActionContextMenu.ts @@ -2,9 +2,8 @@ import React from 'react'; import {GestureResponderEvent, Text as RNText} from 'react-native'; import {OnyxEntry} from 'react-native-onyx'; import {ValueOf} from 'type-fest'; +import CONST from '@src/CONST'; import type {ReportAction} from '@src/types/onyx'; -// eslint-disable-next-line import/no-cycle -import {CONTEXT_MENU_TYPES} from './ContextMenuActions'; type OnHideCallback = () => void; @@ -12,7 +11,7 @@ type OnConfirm = () => void; type OnCancel = () => void; -type ContextMenuType = ValueOf; +type ContextMenuType = ValueOf; type ShowContextMenu = ( type: ContextMenuType, diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index f850daaa1ffb..5bec9544fd41 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -60,7 +60,6 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; -import * as ContextMenuActions from './ContextMenu/ContextMenuActions'; import MiniReportActionContextMenu from './ContextMenu/MiniReportActionContextMenu'; import * as ReportActionContextMenu from './ContextMenu/ReportActionContextMenu'; import {hideContextMenu} from './ContextMenu/ReportActionContextMenu'; @@ -268,7 +267,7 @@ function ReportActionItem(props) { setIsContextMenuActive(true); const selection = SelectionScraper.getCurrentSelection(); ReportActionContextMenu.showContextMenu( - ContextMenuActions.CONTEXT_MENU_TYPES.REPORT_ACTION, + CONST.CONTEXT_MENU_TYPES.REPORT_ACTION, event, selection, popoverAnchorRef, diff --git a/src/pages/settings/AboutPage/AboutPage.js b/src/pages/settings/AboutPage/AboutPage.js index c192abf84e43..aae661763756 100644 --- a/src/pages/settings/AboutPage/AboutPage.js +++ b/src/pages/settings/AboutPage/AboutPage.js @@ -15,7 +15,6 @@ import useWaitForNavigation from '@hooks/useWaitForNavigation'; import compose from '@libs/compose'; import * as Environment from '@libs/Environment/Environment'; import Navigation from '@libs/Navigation/Navigation'; -import {CONTEXT_MENU_TYPES} from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import useThemeStyles from '@styles/useThemeStyles'; import * as Link from '@userActions/Link'; @@ -88,7 +87,7 @@ function AboutPage(props) { iconRight: item.iconRight, onPress: item.action, shouldShowRightIcon: true, - onSecondaryInteraction: !_.isEmpty(item.link) ? (e) => ReportActionContextMenu.showContextMenu(CONTEXT_MENU_TYPES.LINK, e, item.link, popoverAnchor) : undefined, + onSecondaryInteraction: !_.isEmpty(item.link) ? (e) => ReportActionContextMenu.showContextMenu(CONST.CONTEXT_MENU_TYPES.LINK, e, item.link, popoverAnchor) : undefined, ref: popoverAnchor, shouldBlockSelection: Boolean(item.link), })); diff --git a/src/pages/settings/AppDownloadLinks.js b/src/pages/settings/AppDownloadLinks.js index 182a25a121b5..494042ca57e3 100644 --- a/src/pages/settings/AppDownloadLinks.js +++ b/src/pages/settings/AppDownloadLinks.js @@ -9,7 +9,6 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; import compose from '@libs/compose'; import Navigation from '@libs/Navigation/Navigation'; -import {CONTEXT_MENU_TYPES} from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import useThemeStyles from '@styles/useThemeStyles'; import * as Link from '@userActions/Link'; @@ -66,7 +65,7 @@ function AppDownloadLinksPage(props) { item.action()} - onSecondaryInteraction={(e) => ReportActionContextMenu.showContextMenu(CONTEXT_MENU_TYPES.LINK, e, item.link, popoverAnchor)} + onSecondaryInteraction={(e) => ReportActionContextMenu.showContextMenu(CONST.CONTEXT_MENU_TYPES.LINK, e, item.link, popoverAnchor)} onKeyDown={(event) => { event.target.blur(); }} diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 8ca1f96b3796..7b086d439c8a 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -29,7 +29,6 @@ import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as UserUtils from '@libs/UserUtils'; import walletTermsPropTypes from '@pages/EnablePayments/walletTermsPropTypes'; -import {CONTEXT_MENU_TYPES} from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import policyMemberPropType from '@pages/policyMemberPropType'; import * as ReimbursementAccountProps from '@pages/ReimbursementAccount/reimbursementAccountPropTypes'; @@ -311,7 +310,7 @@ function InitialSettingsPage(props) { ref={popoverAnchor} shouldBlockSelection={Boolean(item.link)} onSecondaryInteraction={ - !_.isEmpty(item.link) ? (e) => ReportActionContextMenu.showContextMenu(CONTEXT_MENU_TYPES.LINK, e, item.link, popoverAnchor.current) : undefined + !_.isEmpty(item.link) ? (e) => ReportActionContextMenu.showContextMenu(CONST.CONTEXT_MENU_TYPES.LINK, e, item.link, popoverAnchor.current) : undefined } /> ); From 9dafe7aba69d760241adfd260b359455277d7d07 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Fri, 8 Dec 2023 16:17:58 +0100 Subject: [PATCH 7/9] Move types to 'types.ts' file --- .../BaseAnchorForCommentsOnly.tsx | 18 +----------------- .../AnchorForCommentsOnly/index.native.tsx | 2 +- src/components/AnchorForCommentsOnly/index.tsx | 2 +- src/components/AnchorForCommentsOnly/types.ts | 18 +++++++++++++++++- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx index 73bd48dcf316..78bfc502ea57 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx @@ -10,23 +10,7 @@ import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportA import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; -import type AnchorForCommentsOnlyProps from './types'; - -type BaseAnchorForCommentsOnlyProps = AnchorForCommentsOnlyProps & { - /** Press in handler for the link */ - onPressIn?: () => void; - - /** Press out handler for the link */ - onPressOut?: () => void; -}; - -type LinkProps = { - /** Press handler for the link, when not passed, default href is used to create a link like behaviour */ - onPress?: () => void; - - /** The URL to open */ - href?: string; -}; +import type {BaseAnchorForCommentsOnlyProps, LinkProps} from './types'; /* * This is a default anchor component for regular links. diff --git a/src/components/AnchorForCommentsOnly/index.native.tsx b/src/components/AnchorForCommentsOnly/index.native.tsx index 3942a10be0c4..8d9cc45c44b7 100644 --- a/src/components/AnchorForCommentsOnly/index.native.tsx +++ b/src/components/AnchorForCommentsOnly/index.native.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {Linking} from 'react-native'; import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; -import type AnchorForCommentsOnlyProps from './types'; +import type {AnchorForCommentsOnlyProps} from './types'; function AnchorForCommentsOnly({onPress, href, ...props}: AnchorForCommentsOnlyProps) { const onLinkPress = () => { diff --git a/src/components/AnchorForCommentsOnly/index.tsx b/src/components/AnchorForCommentsOnly/index.tsx index b76a8b6a3718..493697dc610f 100644 --- a/src/components/AnchorForCommentsOnly/index.tsx +++ b/src/components/AnchorForCommentsOnly/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import ControlSelection from '@libs/ControlSelection'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; -import type AnchorForCommentsOnlyProps from './types'; +import type {AnchorForCommentsOnlyProps} from './types'; function AnchorForCommentsOnly(props: AnchorForCommentsOnlyProps) { return ( diff --git a/src/components/AnchorForCommentsOnly/types.ts b/src/components/AnchorForCommentsOnly/types.ts index 7167ce320ada..005364c2077f 100644 --- a/src/components/AnchorForCommentsOnly/types.ts +++ b/src/components/AnchorForCommentsOnly/types.ts @@ -20,4 +20,20 @@ type AnchorForCommentsOnlyProps = ChildrenProps & { onPress?: () => void; }; -export default AnchorForCommentsOnlyProps; +type BaseAnchorForCommentsOnlyProps = AnchorForCommentsOnlyProps & { + /** Press in handler for the link */ + onPressIn?: () => void; + + /** Press out handler for the link */ + onPressOut?: () => void; +}; + +type LinkProps = { + /** Press handler for the link, when not passed, default href is used to create a link like behaviour */ + onPress?: () => void; + + /** The URL to open */ + href?: string; +}; + +export type {AnchorForCommentsOnlyProps, BaseAnchorForCommentsOnlyProps, LinkProps}; From 92e5ab894fe833b8e28a816f102812e26cd71c59 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Fri, 8 Dec 2023 17:27:25 +0100 Subject: [PATCH 8/9] Minor code improvement --- src/components/AnchorForCommentsOnly/index.native.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AnchorForCommentsOnly/index.native.tsx b/src/components/AnchorForCommentsOnly/index.native.tsx index 8d9cc45c44b7..e022ad611618 100644 --- a/src/components/AnchorForCommentsOnly/index.native.tsx +++ b/src/components/AnchorForCommentsOnly/index.native.tsx @@ -3,12 +3,12 @@ import {Linking} from 'react-native'; import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; import type {AnchorForCommentsOnlyProps} from './types'; -function AnchorForCommentsOnly({onPress, href, ...props}: AnchorForCommentsOnlyProps) { +function AnchorForCommentsOnly({onPress, href = '', ...props}: AnchorForCommentsOnlyProps) { const onLinkPress = () => { if (onPress) { onPress(); } else { - Linking.openURL(href ?? ''); + Linking.openURL(href); } }; From 2ba2598b389f39703fa4f531ff98dde8c4cfc1fe Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 13 Dec 2023 10:54:02 +0100 Subject: [PATCH 9/9] Fix lint error --- src/pages/ReferralDetailsPage.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/ReferralDetailsPage.js b/src/pages/ReferralDetailsPage.js index 73e1ac393615..5bc4bf66df4b 100644 --- a/src/pages/ReferralDetailsPage.js +++ b/src/pages/ReferralDetailsPage.js @@ -18,7 +18,6 @@ import * as Link from '@userActions/Link'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import SCREENS from '@src/SCREENS'; -import {CONTEXT_MENU_TYPES} from './home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from './home/report/ContextMenu/ReportActionContextMenu'; const propTypes = { @@ -96,7 +95,7 @@ function ReferralDetailsPage({route, account}) { disabled={isExecuting} shouldBlockSelection onPress={singleExecution(() => Link.openExternalLink(CONST.REFERRAL_PROGRAM.LEARN_MORE_LINK))} - onSecondaryInteraction={(e) => ReportActionContextMenu.showContextMenu(CONTEXT_MENU_TYPES.LINK, e, CONST.REFERRAL_PROGRAM.LEARN_MORE_LINK, popoverAnchor.current)} + onSecondaryInteraction={(e) => ReportActionContextMenu.showContextMenu(CONST.CONTEXT_MENU_TYPES.LINK, e, CONST.REFERRAL_PROGRAM.LEARN_MORE_LINK, popoverAnchor.current)} /> );