Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import {Pressable, StyleSheet} from 'react-native';
import lodashGet from 'lodash/get';
import Text from '../../Text';
import {propTypes, defaultProps} from '../anchorForCommentsOnlyPropTypes';
import * as anchorForCommentsOnlyPropTypes from '../anchorForCommentsOnlyPropTypes';
import PressableWithSecondaryInteraction from '../../PressableWithSecondaryInteraction';
import * as ReportActionContextMenu from '../../../pages/home/report/ContextMenu/ReportActionContextMenu';
import * as ContextMenuActions from '../../../pages/home/report/ContextMenu/ContextMenuActions';
Expand All @@ -15,7 +15,8 @@ import fileDownload from '../../../libs/fileDownload';
*/
const BaseAnchorForCommentsOnly = (props) => {
let linkRef;
const rest = _.omit(props, _.keys(propTypes));
// eslint-disable-next-line react/forbid-foreign-prop-types
const rest = _.omit(props, _.keys(anchorForCommentsOnlyPropTypes.propTypes));
return (
props.isAttachment
? (
Expand All @@ -32,16 +33,17 @@ const BaseAnchorForCommentsOnly = (props) => {
)
: (
<PressableWithSecondaryInteraction
inline
onSecondaryInteraction={
(event) => {
ReportActionContextMenu.showContextMenu(
ContextMenuActions.CONTEXT_MENU_TYPES.LINK,
event,
props.href,
lodashGet(linkRef, 'current'),
);
}
(event) => {
ReportActionContextMenu.showContextMenu(
ContextMenuActions.CONTEXT_MENU_TYPES.LINK,
event,
props.href,
lodashGet(linkRef, 'current'),
);
}
}
>
<Text
ref={el => linkRef = el}
Expand All @@ -63,8 +65,8 @@ const BaseAnchorForCommentsOnly = (props) => {
);
};

BaseAnchorForCommentsOnly.propTypes = propTypes;
BaseAnchorForCommentsOnly.defaultProps = defaultProps;
BaseAnchorForCommentsOnly.propTypes = anchorForCommentsOnlyPropTypes.propTypes;
BaseAnchorForCommentsOnly.defaultProps = anchorForCommentsOnlyPropTypes.defaultProps;
BaseAnchorForCommentsOnly.displayName = 'BaseAnchorForCommentsOnly';

export default BaseAnchorForCommentsOnly;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import _ from 'underscore';
import React from 'react';
import lodashGet from 'lodash/get';
import {Linking, StyleSheet, Pressable} from 'react-native';
import {propTypes, defaultProps} from '../anchorForCommentsOnlyPropTypes';
import * as anchorForCommentsOnlyPropTypes from '../anchorForCommentsOnlyPropTypes';
import fileDownload from '../../../libs/fileDownload';
import Text from '../../Text';
import PressableWithSecondaryInteraction from '../../PressableWithSecondaryInteraction';
Expand All @@ -16,7 +16,8 @@ import styles from '../../../styles/styles';
*/
const BaseAnchorForCommentsOnly = (props) => {
let linkRef;
const rest = _.omit(props, _.keys(propTypes));
// eslint-disable-next-line react/forbid-foreign-prop-types
const rest = _.omit(props, _.keys(anchorForCommentsOnlyPropTypes.propTypes));
return (
props.isAttachment
? (
Expand All @@ -35,16 +36,17 @@ const BaseAnchorForCommentsOnly = (props) => {
)
: (
<PressableWithSecondaryInteraction
inline
onSecondaryInteraction={
(event) => {
ReportActionContextMenu.showContextMenu(
ContextMenuActions.CONTEXT_MENU_TYPES.LINK,
event,
props.href,
lodashGet(linkRef, 'current'),
);
}
}
(event) => {
ReportActionContextMenu.showContextMenu(
ContextMenuActions.CONTEXT_MENU_TYPES.LINK,
event,
props.href,
lodashGet(linkRef, 'current'),
);
}
}
onPress={() => Linking.openURL(props.href)}
>
<Text
Expand All @@ -60,8 +62,8 @@ const BaseAnchorForCommentsOnly = (props) => {
);
};

BaseAnchorForCommentsOnly.propTypes = propTypes;
BaseAnchorForCommentsOnly.defaultProps = defaultProps;
BaseAnchorForCommentsOnly.propTypes = anchorForCommentsOnlyPropTypes.propTypes;
BaseAnchorForCommentsOnly.defaultProps = anchorForCommentsOnlyPropTypes.defaultProps;
BaseAnchorForCommentsOnly.displayName = 'BaseAnchorForCommentsOnly';

export default BaseAnchorForCommentsOnly;
10 changes: 4 additions & 6 deletions src/components/AnchorForCommentsOnly/index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import _ from 'underscore';
import React from 'react';
import PropTypes from 'prop-types';
import {
propTypes as anchorForCommentsOnlyPropTypes,
defaultProps as anchorForCommentsOnlyDefaultProps,
} from './anchorForCommentsOnlyPropTypes';
import * as anchorForCommentsOnlyPropTypes from './anchorForCommentsOnlyPropTypes';
import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly';
import addEncryptedAuthTokenToURL from '../../libs/addEncryptedAuthTokenToURL';

const propTypes = {
/** Do we need an auth token to view this link or download the remote resource? */
isAuthTokenRequired: PropTypes.bool,

...anchorForCommentsOnlyPropTypes,
// eslint-disable-next-line react/forbid-foreign-prop-types
...anchorForCommentsOnlyPropTypes.propTypes,
};

const defaultProps = {
isAuthTokenRequired: false,
...anchorForCommentsOnlyDefaultProps,
...anchorForCommentsOnlyPropTypes.defaultProps,
};

/*
Expand Down
38 changes: 21 additions & 17 deletions src/components/PressableWithSecondaryInteraction/index.android.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import _ from 'underscore';
import React, {forwardRef} from 'react';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import {Pressable, Platform} from 'react-native';
import {propTypes, defaultProps} from './pressableWithSecondaryInteractionPropTypes';
import {Pressable, Platform, Text as RNText} from 'react-native';
import * as pressableWithSecondaryInteractionPropTypes from './pressableWithSecondaryInteractionPropTypes';

/**
* Triggers haptic feedback, and calls onSecondaryInteraction
Expand Down Expand Up @@ -31,22 +31,26 @@ function handleLongPress(event, props) {
* @param {Object} props
* @returns {React.Component}
*/
const PressableWithSecondaryInteraction = props => (
<Pressable
ref={props.forwardedRef}
onPress={props.onPress}
onPressIn={props.onPressIn}
onLongPress={event => handleLongPress(event, props)}
onPressOut={props.onPressOut}
// eslint-disable-next-line react/jsx-props-no-spreading
{...(_.omit(props, 'onLongPress'))}
>
{props.children}
</Pressable>
);
const PressableWithSecondaryInteraction = (props) => {
// Use Text node for inline mode to prevent content overflow.
const Node = props.inline ? RNText : Pressable;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

return (
<Node
ref={props.forwardedRef}
onPress={props.onPress}
onPressIn={props.onPressIn}
onLongPress={event => handleLongPress(event, props)}
onPressOut={props.onPressOut}
// eslint-disable-next-line react/jsx-props-no-spreading
{...(_.omit(props, 'onLongPress'))}
>
{props.children}
</Node>
);
};

PressableWithSecondaryInteraction.propTypes = propTypes;
PressableWithSecondaryInteraction.defaultProps = defaultProps;
PressableWithSecondaryInteraction.propTypes = pressableWithSecondaryInteractionPropTypes.propTypes;
PressableWithSecondaryInteraction.defaultProps = pressableWithSecondaryInteractionPropTypes.defaultProps;
PressableWithSecondaryInteraction.displayName = 'PressableWithSecondaryInteraction';

export default forwardRef((props, ref) => (
Expand Down
50 changes: 27 additions & 23 deletions src/components/PressableWithSecondaryInteraction/index.ios.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
import _ from 'underscore';
import React, {forwardRef} from 'react';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import {Pressable} from 'react-native';
import {propTypes, defaultProps} from './pressableWithSecondaryInteractionPropTypes';
import {Pressable, Text as RNText} from 'react-native';
import * as pressableWithSecondaryInteractionPropTypes from './pressableWithSecondaryInteractionPropTypes';

/**
* This is a special Pressable that calls onSecondaryInteraction when LongPressed.
*
* @param {Object} props
* @returns {React.Component}
*/
const PressableWithSecondaryInteraction = props => (
<Pressable
ref={props.forwardedRef}
onPress={props.onPress}
onPressIn={props.onPressIn}
onLongPress={(e) => {
e.preventDefault();
ReactNativeHapticFeedback.trigger('selection', {
enableVibrateFallback: true,
});
props.onSecondaryInteraction(e);
}}
onPressOut={props.onPressOut}
// eslint-disable-next-line react/jsx-props-no-spreading
{...(_.omit(props, 'onLongPress'))}
>
{props.children}
</Pressable>
);
const PressableWithSecondaryInteraction = (props) => {
// Use Text node for inline mode to prevent content overflow.
const Node = props.inline ? RNText : Pressable;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@parasharrajat I think it might be worth adding a little comment explaining this option here as well. I know you have added the comment to the PropType, but one compact line in here would be handy. Can you please add one? Thank you 🙌

return (
<Node
ref={props.forwardedRef}
onPress={props.onPress}
onPressIn={props.onPressIn}
onLongPress={(e) => {
e.preventDefault();
ReactNativeHapticFeedback.trigger('selection', {
enableVibrateFallback: true,
});
props.onSecondaryInteraction(e);
}}
onPressOut={props.onPressOut}
// eslint-disable-next-line react/jsx-props-no-spreading
{...(_.omit(props, 'onLongPress'))}
>
{props.children}
</Node>
);
};

PressableWithSecondaryInteraction.propTypes = propTypes;
PressableWithSecondaryInteraction.defaultProps = defaultProps;
PressableWithSecondaryInteraction.propTypes = pressableWithSecondaryInteractionPropTypes.propTypes;
PressableWithSecondaryInteraction.defaultProps = pressableWithSecondaryInteractionPropTypes.defaultProps;
PressableWithSecondaryInteraction.displayName = 'PressableWithSecondaryInteraction';

export default forwardRef((props, ref) => (
Expand Down
11 changes: 7 additions & 4 deletions src/components/PressableWithSecondaryInteraction/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import _ from 'underscore';
import React, {Component} from 'react';
import {Pressable} from 'react-native';
import {propTypes, defaultProps} from './pressableWithSecondaryInteractionPropTypes';
import * as pressableWithSecondaryInteractionPropTypes from './pressableWithSecondaryInteractionPropTypes';
import styles from '../../styles/styles';

/**
* This is a special Pressable that calls onSecondaryInteraction when LongPressed, or right-clicked.
Expand Down Expand Up @@ -39,10 +40,12 @@ class PressableWithSecondaryInteraction extends Component {

render() {
const defaultPressableProps = _.omit(this.props, ['onSecondaryInteraction', 'children', 'onLongPress']);

// On Web, Text does not support LongPress events thus manage inline mode with styling instead of using Text.
return (
<Pressable
style={this.props.inline && styles.dInline}
onPressIn={this.props.onPressIn}
delayLongPress={200}
onLongPress={this.props.onSecondaryInteraction}
onPressOut={this.props.onPressOut}
onPress={this.props.onPress}
Expand All @@ -56,8 +59,8 @@ class PressableWithSecondaryInteraction extends Component {
}
}

PressableWithSecondaryInteraction.propTypes = propTypes;
PressableWithSecondaryInteraction.defaultProps = defaultProps;
PressableWithSecondaryInteraction.propTypes = pressableWithSecondaryInteractionPropTypes.propTypes;
PressableWithSecondaryInteraction.defaultProps = pressableWithSecondaryInteractionPropTypes.defaultProps;
export default React.forwardRef((props, ref) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<PressableWithSecondaryInteraction {...props} forwardedRef={ref} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,24 @@ const propTypes = {

/** Prevent the default ContextMenu on web/Desktop */
preventDefaultContentMenu: PropTypes.bool,

/** Use Text instead of Pressable to create inline layout.
* It has few limitations in comparison to Pressable.
*
* - No support for delayLongPress.
* - No support for pressIn and pressOut events.
*
* Note: Web uses styling instead of Text due to no support of LongPress. Thus above pointers are not valid for web.
*/
inline: PropTypes.bool,
};

const defaultProps = {
forwardedRef: () => {},
onPressIn: () => {},
onPressOut: () => {},
preventDefaultContentMenu: true,
inline: false,
};

export {propTypes, defaultProps};