MM-18236 Prevent the post menu from triggering when using the back gesture (#3319)

* MM-18236 Prevent the post menu from triggering when using the back gesture in the thread screen

* Update snapshots

* Update app/components/touchable_with_feedback/touchable_with_feedback.ios.js

Co-Authored-By: Miguel Alatzar <migbot@users.noreply.github.com>

* Update app/components/touchable_with_feedback/touchable_with_feedback.ios.js

Co-Authored-By: Miguel Alatzar <migbot@users.noreply.github.com>

* Update app/components/post/post.js

Co-Authored-By: Miguel Alatzar <migbot@users.noreply.github.com>

* Update app/components/touchable_with_feedback/touchable_with_feedback.ios.js

* Fix eslint
This commit is contained in:
Elias Nahum 2019-09-26 00:19:49 +03:00
parent 0818489b47
commit 5fafe376fa
No known key found for this signature in database
GPG key ID: E038DB71E0B61702
44 changed files with 379 additions and 251 deletions

View file

@ -37,8 +37,7 @@ exports[`SendButton should change theme backgroundColor to 0.3 opacity 1`] = `
`;
exports[`SendButton should match snapshot 1`] = `
<TouchableOpacity
activeOpacity={0.2}
<TouchableWithFeedbackIOS
onPress={[MockFunction]}
style={
Object {
@ -47,6 +46,7 @@ exports[`SendButton should match snapshot 1`] = `
"paddingVertical": 3,
}
}
type="opacity"
>
<View
style={
@ -66,12 +66,11 @@ exports[`SendButton should match snapshot 1`] = `
width={15}
/>
</View>
</TouchableOpacity>
</TouchableWithFeedbackIOS>
`;
exports[`SendButton should render theme backgroundColor 1`] = `
<TouchableOpacity
activeOpacity={0.2}
<TouchableWithFeedbackIOS
onPress={[MockFunction]}
style={
Object {
@ -80,6 +79,7 @@ exports[`SendButton should render theme backgroundColor 1`] = `
"paddingVertical": 3,
}
}
type="opacity"
>
<View
style={
@ -99,5 +99,5 @@ exports[`SendButton should render theme backgroundColor 1`] = `
width={15}
/>
</View>
</TouchableOpacity>
</TouchableWithFeedbackIOS>
`;

View file

@ -1,8 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AttachmentButton should match snapshot 1`] = `
<TouchableOpacity
activeOpacity={0.2}
<TouchableWithFeedbackIOS
onPress={[Function]}
style={
Object {
@ -12,6 +11,7 @@ exports[`AttachmentButton should match snapshot 1`] = `
"width": 45,
}
}
type="opacity"
>
<Icon
allowFontScaling={false}
@ -24,5 +24,5 @@ exports[`AttachmentButton should match snapshot 1`] = `
}
}
/>
</TouchableOpacity>
</TouchableWithFeedbackIOS>
`;

View file

@ -8,7 +8,6 @@ import {
NativeModules,
Platform,
StyleSheet,
TouchableOpacity,
} from 'react-native';
import RNFetchBlob from 'rn-fetch-blob';
import DeviceInfo from 'react-native-device-info';
@ -21,6 +20,7 @@ import Permissions from 'react-native-permissions';
import {lookupMimeType} from 'mattermost-redux/utils/file_utils';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {PermissionTypes} from 'app/constants';
import {changeOpacity} from 'app/utils/theme';
import {t} from 'app/utils/i18n';
@ -493,18 +493,20 @@ export default class AttachmentButton extends PureComponent {
if (wrapper) {
return (
<TouchableOpacity
<TouchableWithFeedback
onPress={this.showFileAttachmentOptions}
type={'opacity'}
>
{children}
</TouchableOpacity>
</TouchableWithFeedback>
);
}
return (
<TouchableOpacity
<TouchableWithFeedback
onPress={this.showFileAttachmentOptions}
style={style.buttonContainer}
type={'opacity'}
>
<Icon
size={30}
@ -512,7 +514,7 @@ export default class AttachmentButton extends PureComponent {
color={changeOpacity(theme.centerChannelColor, 0.9)}
name='md-add'
/>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -5,13 +5,13 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Text,
TouchableOpacity,
View,
} from 'react-native';
import ProfilePicture from 'app/components/profile_picture';
import BotTag from 'app/components/bot_tag';
import GuestTag from 'app/components/guest_tag';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {makeStyleSheetFromTheme} from 'app/utils/theme';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
@ -54,10 +54,11 @@ export default class AtMentionItem extends PureComponent {
const hasFullName = firstName.length > 0 && lastName.length > 0;
return (
<TouchableOpacity
<TouchableWithFeedback
key={userId}
onPress={this.completeMention}
style={[style.row, padding(isLandscape)]}
type={'opacity'}
>
<View style={style.rowPicture}>
<ProfilePicture
@ -78,7 +79,7 @@ export default class AtMentionItem extends PureComponent {
/>
{hasFullName && <Text style={style.rowUsername}>{' - '}</Text>}
{hasFullName && <Text style={style.rowFullname}>{`${firstName} ${lastName}`}</Text>}
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -5,14 +5,13 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Text,
TouchableOpacity,
} from 'react-native';
import {General} from 'mattermost-redux/constants';
import BotTag from 'app/components/bot_tag';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import GuestTag from 'app/components/guest_tag';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {makeStyleSheetFromTheme} from 'app/utils/theme';
export default class ChannelMentionItem extends PureComponent {
@ -56,10 +55,11 @@ export default class ChannelMentionItem extends PureComponent {
return null;
}
return (
<TouchableOpacity
<TouchableWithFeedback
key={channelId}
onPress={this.completeMention}
style={[style.row, padding(isLandscape)]}
type={'opacity'}
>
<Text style={style.rowDisplayName}>{'@' + displayName}</Text>
<BotTag
@ -70,18 +70,19 @@ export default class ChannelMentionItem extends PureComponent {
show={isGuest}
theme={theme}
/>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
return (
<TouchableOpacity
<TouchableWithFeedback
key={channelId}
onPress={this.completeMention}
style={[style.row, padding(isLandscape)]}
type={'opacity'}
>
<Text style={style.rowDisplayName}>{displayName}</Text>
<Text style={style.rowName}>{` (~${name})`}</Text>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -7,7 +7,6 @@ import {
FlatList,
Platform,
Text,
TouchableOpacity,
View,
} from 'react-native';
@ -15,6 +14,7 @@ import {isMinimumServerVersion} from 'mattermost-redux/utils/helpers';
import AutocompleteDivider from 'app/components/autocomplete/autocomplete_divider';
import Emoji from 'app/components/emoji';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {makeStyleSheetFromTheme} from 'app/utils/theme';
const EMOJI_REGEX = /(^|\s|^\+|^-)(:([^:\s]*))$/i;
@ -171,9 +171,10 @@ export default class EmojiSuggestion extends Component {
const style = getStyleFromTheme(this.props.theme);
return (
<TouchableOpacity
<TouchableWithFeedback
onPress={() => this.completeSuggestion(item)}
style={style.row}
type={'opacity'}
>
<View style={style.emoji}>
<Emoji
@ -182,7 +183,7 @@ export default class EmojiSuggestion extends Component {
/>
</View>
<Text style={style.emojiName}>{`:${item}:`}</Text>
</TouchableOpacity>
</TouchableWithFeedback>
);
};

View file

@ -3,13 +3,11 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Text,
TouchableOpacity,
} from 'react-native';
import {Text} from 'react-native';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
export default class SlashSuggestionItem extends PureComponent {
static propTypes = {
@ -38,13 +36,14 @@ export default class SlashSuggestionItem extends PureComponent {
const style = getStyleFromTheme(theme);
return (
<TouchableOpacity
<TouchableWithFeedback
onPress={this.completeSuggestion}
style={[style.row, padding(isLandscape)]}
type={'opacity'}
>
<Text style={style.suggestionName}>{`/${trigger} ${hint}`}</Text>
<Text style={style.suggestionDescription}>{description}</Text>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -5,12 +5,12 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Text,
TouchableOpacity,
View,
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import FormattedText from 'app/components/formatted_text';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
export default class SpecialMentionItem extends PureComponent {
@ -40,9 +40,10 @@ export default class SpecialMentionItem extends PureComponent {
const style = getStyleFromTheme(theme);
return (
<TouchableOpacity
<TouchableWithFeedback
onPress={this.completeMention}
style={style.row}
type={'opacity'}
>
<View style={style.rowPicture}>
<Icon
@ -60,7 +61,7 @@ export default class SpecialMentionItem extends PureComponent {
style={style.rowFullname}
/>
</Text>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import React, {PureComponent} from 'react';
import {Text, TouchableOpacity, View} from 'react-native';
import {Text, View} from 'react-native';
import PropTypes from 'prop-types';
import {intlShape} from 'react-intl';
import Icon from 'react-native-vector-icons/FontAwesome';
@ -10,6 +10,7 @@ import Icon from 'react-native-vector-icons/FontAwesome';
import {displayUsername} from 'mattermost-redux/utils/user_utils';
import FormattedText from 'app/components/formatted_text';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {preventDoubleTap} from 'app/utils/tap';
import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
import {ViewTypes} from 'app/constants';
@ -181,9 +182,10 @@ export default class AutocompleteSelector extends PureComponent {
return (
<View style={style.container}>
{labelContent}
<TouchableOpacity
<TouchableWithFeedback
style={style.flex}
onPress={this.goToSelectorScreen}
type={'opacity'}
>
<View style={inputStyle}>
<Text
@ -198,7 +200,7 @@ export default class AutocompleteSelector extends PureComponent {
style={style.icon}
/>
</View>
</TouchableOpacity>
</TouchableWithFeedback>
{helpTextContent}
{errorTextContent}
</View>

View file

@ -1,60 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {ActivityIndicator, StyleSheet, TouchableHighlight, View} from 'react-native';
import {GlobalStyles} from 'app/styles';
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
},
loading: {
marginLeft: 3,
},
});
export default class Button extends PureComponent {
static propTypes = {
children: PropTypes.node,
loading: PropTypes.bool,
onPress: PropTypes.func.isRequired,
};
onPress = () => {
if (!this.props.loading) {
this.props.onPress();
}
};
render() {
let loading = null;
if (this.props.loading) {
loading = (
<ActivityIndicator
style={styles.loading}
animating={true}
size='small'
/>
);
}
return (
<TouchableHighlight
style={GlobalStyles.button}
underlayColor='#B5B5B5'
onPress={this.onPress}
>
<View style={styles.container}>
{this.props.children}
{loading}
</View>
</TouchableHighlight>
);
}
}

View file

@ -5,16 +5,17 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Text,
TouchableOpacity,
View,
} from 'react-native';
import {getFullName} from 'mattermost-redux/utils/user_utils';
import {General} from 'mattermost-redux/constants';
import {injectIntl, intlShape} from 'react-intl';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import ProfilePicture from 'app/components/profile_picture';
import BotTag from 'app/components/bot_tag';
import GuestTag from 'app/components/guest_tag';
import ProfilePicture from 'app/components/profile_picture';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {preventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import {t} from 'app/utils/i18n';
@ -67,10 +68,11 @@ class ChannelIntro extends PureComponent {
const style = getStyleSheet(theme);
return currentChannelMembers.map((member) => (
<TouchableOpacity
<TouchableWithFeedback
key={member.id}
onPress={preventDoubleTap(() => this.goToUserProfile(member.id))}
style={style.profile}
type={'opacity'}
>
<ProfilePicture
userId={member.id}
@ -78,7 +80,7 @@ class ChannelIntro extends PureComponent {
statusBorderWidth={2}
statusSize={25}
/>
</TouchableOpacity>
</TouchableWithFeedback>
));
};
@ -88,9 +90,10 @@ class ChannelIntro extends PureComponent {
return currentChannelMembers.map((member, index) => {
return (
<TouchableOpacity
<TouchableWithFeedback
key={member.id}
onPress={preventDoubleTap(() => this.goToUserProfile(member.id))}
type={'opacity'}
>
<View style={style.indicatorContainer}>
<Text style={style.displayName}>
@ -108,7 +111,7 @@ class ChannelIntro extends PureComponent {
{index === currentChannelMembers.length - 1 ? '' : ', '}
</Text>
</View>
</TouchableOpacity>
</TouchableWithFeedback>
);
});
};

View file

@ -5,12 +5,12 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Text,
TouchableOpacity,
View,
} from 'react-native';
import * as Utils from 'mattermost-redux/utils/file_utils.js';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {isDocument, isGif} from 'app/utils/file';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
@ -98,17 +98,18 @@ export default class FileAttachment extends PureComponent {
let fileAttachmentComponent;
if ((data && data.has_preview_image) || file.loading || isGif(data)) {
fileAttachmentComponent = (
<TouchableOpacity
<TouchableWithFeedback
key={`${this.props.id}${file.loading}`}
onPress={this.handlePreviewPress}
onLongPress={onLongPress}
type={'opacity'}
>
<FileAttachmentImage
file={data || {}}
onCaptureRef={this.handleCaptureRef}
theme={theme}
/>
</TouchableOpacity>
</TouchableWithFeedback>
);
} else if (isDocument(data)) {
fileAttachmentComponent = (
@ -122,29 +123,32 @@ export default class FileAttachment extends PureComponent {
);
} else {
fileAttachmentComponent = (
<TouchableOpacity
<TouchableWithFeedback
onPress={this.handlePreviewPress}
onLongPress={onLongPress}
type={'opacity'}
>
<FileAttachmentIcon
file={data}
onCaptureRef={this.handleCaptureRef}
theme={theme}
/>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
return (
<View style={[style.fileWrapper]}>
{fileAttachmentComponent}
<TouchableOpacity
onLongPress={onLongPress}
onPress={this.handlePreviewPress}
style={style.fileInfoContainer}
>
{this.renderFileInfo()}
</TouchableOpacity>
<View style={style.fileInfoContainer}>
<TouchableWithFeedback
onLongPress={onLongPress}
onPress={this.handlePreviewPress}
type={'opacity'}
>
{this.renderFileInfo()}
</TouchableWithFeedback>
</View>
</View>
);
}

View file

@ -10,7 +10,6 @@ import {
Platform,
StatusBar,
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import OpenFile from 'react-native-doc-viewer';
@ -21,12 +20,12 @@ import tinyColor from 'tinycolor2';
import {getFileUrl} from 'mattermost-redux/utils/file_utils.js';
import FileAttachmentIcon from 'app/components/file_attachment_list/file_attachment_icon';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {DeviceTypes} from 'app/constants/';
import mattermostBucket from 'app/mattermost_bucket';
import {changeOpacity} from 'app/utils/theme';
import FileAttachmentIcon from 'app/components/file_attachment_list/file_attachment_icon';
const {DOCUMENTS_PATH} = DeviceTypes;
const DOWNLOADING_OFFSET = 28;
const TEXT_PREVIEW_FORMATS = [
@ -386,12 +385,13 @@ export default class FileAttachmentDocument extends PureComponent {
}
return (
<TouchableOpacity
<TouchableWithFeedback
onPress={this.handlePreviewPress}
onLongPress={onLongPress}
type={'opacity'}
>
{fileAttachmentComponent}
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -3,9 +3,11 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Platform, StyleSheet, TouchableOpacity} from 'react-native';
import {Platform, StyleSheet} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
export default class FileUploadRemove extends PureComponent {
static propTypes = {
channelId: PropTypes.string,
@ -22,9 +24,10 @@ export default class FileUploadRemove extends PureComponent {
render() {
return (
<TouchableOpacity
<TouchableWithFeedback
style={style.removeButtonWrapper}
onPress={this.handleOnPress}
type={'opacity'}
>
<Icon
name='md-close'
@ -32,7 +35,7 @@ export default class FileUploadRemove extends PureComponent {
size={18}
style={style.removeButtonIcon}
/>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -3,9 +3,11 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {StyleSheet, TouchableOpacity} from 'react-native';
import {StyleSheet} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
export default class FileUploadRetry extends PureComponent {
static propTypes = {
file: PropTypes.object.isRequired,
@ -20,16 +22,17 @@ export default class FileUploadRetry extends PureComponent {
render() {
return (
<TouchableOpacity
<TouchableWithFeedback
style={style.failed}
onPress={this.handleOnPress}
type={'opacity'}
>
<Icon
name='md-refresh'
size={50}
color='#fff'
/>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -5,16 +5,15 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
ActivityIndicator,
TouchableOpacity,
View,
ViewPropTypes,
} from 'react-native';
import FormattedText from 'app/components/formatted_text';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {makeStyleSheetFromTheme} from 'app/utils/theme';
import {t} from 'app/utils/i18n';
import FormattedText from 'app/components/formatted_text';
export default class LoadMorePosts extends PureComponent {
static propTypes = {
channelId: PropTypes.string.isRequired, // eslint-disable-line react/no-unused-prop-types
@ -56,9 +55,12 @@ export default class LoadMorePosts extends PureComponent {
const style = getStyleSheet(this.props.theme);
return (
<View style={[style.container, this.props.style]}>
<TouchableOpacity onPress={this.loadMore}>
<TouchableWithFeedback
onPress={this.loadMore}
type={'opacity'}
>
{this.renderText(style)}
</TouchableOpacity>
</TouchableWithFeedback>
</View>
);
}

View file

@ -8,12 +8,12 @@ import {
Clipboard,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import CustomPropTypes from 'app/constants/custom_prop_types';
import FormattedText from 'app/components/formatted_text';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import BottomSheet from 'app/utils/bottom_sheet';
import {getDisplayNameForLanguage} from 'app/utils/markdown';
import {preventDoubleTap} from 'app/utils/tap';
@ -153,9 +153,10 @@ export default class MarkdownCodeBlock extends React.PureComponent {
}
return (
<TouchableOpacity
<TouchableWithFeedback
onPress={this.handlePress}
onLongPress={this.handleLongPress}
type={'opacity'}
>
<View style={style.container}>
<View style={style.lineNumbers}>
@ -173,7 +174,7 @@ export default class MarkdownCodeBlock extends React.PureComponent {
</View>
{language}
</View>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -11,12 +11,12 @@ import {
Platform,
StyleSheet,
Text,
TouchableHighlight,
View,
} from 'react-native';
import FormattedText from 'app/components/formatted_text';
import ProgressiveImage from 'app/components/progressive_image';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import CustomPropTypes from 'app/constants/custom_prop_types';
import EphemeralStore from 'app/store/ephemeral_store';
import mattermostManaged from 'app/mattermost_managed';
@ -250,7 +250,7 @@ export default class MarkdownImage extends React.Component {
}
image = (
<TouchableHighlight
<TouchableWithFeedback
onLongPress={this.handleLinkLongPress}
onPress={this.handlePreviewImage}
style={{width, height}}
@ -261,7 +261,7 @@ export default class MarkdownImage extends React.Component {
resizeMode='contain'
style={{width, height}}
/>
</TouchableHighlight>
</TouchableWithFeedback>
);
}
} else if (this.state.failed) {
@ -275,12 +275,12 @@ export default class MarkdownImage extends React.Component {
if (image && this.props.linkDestination) {
image = (
<TouchableHighlight
<TouchableWithFeedback
onPress={this.handleLinkPress}
onLongPress={this.handleLinkLongPress}
>
{image}
</TouchableHighlight>
</TouchableWithFeedback>
);
}

View file

@ -6,14 +6,14 @@ import React from 'react';
import {intlShape} from 'react-intl';
import {
ScrollView,
TouchableOpacity,
View,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {CELL_WIDTH} from 'app/components/markdown/markdown_table_cell/markdown_table_cell';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {preventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import {CELL_WIDTH} from 'app/components/markdown/markdown_table_cell/markdown_table_cell';
const MAX_HEIGHT = 300;
@ -128,7 +128,10 @@ export default class MarkdownTable extends React.PureComponent {
}
return (
<TouchableOpacity onPress={this.handlePress}>
<TouchableWithFeedback
onPress={this.handlePress}
type={'opacity'}
>
<ScrollView
contentContainerStyle={{width: this.getTableWidth()}}
onContentSizeChange={this.handleContentSizeChange}
@ -141,7 +144,7 @@ export default class MarkdownTable extends React.PureComponent {
</ScrollView>
{moreRight}
{moreBelow}
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AttachmentImage it matches snapshot 1`] = `
<TouchableWithoutFeedback
<TouchableWithFeedbackIOS
onPress={[Function]}
style={
Array [
@ -13,6 +13,7 @@ exports[`AttachmentImage it matches snapshot 1`] = `
},
]
}
type="none"
>
<View
style={
@ -42,5 +43,5 @@ exports[`AttachmentImage it matches snapshot 1`] = `
}
/>
</View>
</TouchableWithoutFeedback>
</TouchableWithFeedbackIOS>
`;

View file

@ -3,9 +3,10 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Image, TouchableWithoutFeedback, View} from 'react-native';
import {Image, View} from 'react-native';
import ProgressiveImage from 'app/components/progressive_image';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {isGifTooLarge, previewImageAtIndex, calculateDimensions} from 'app/utils/images';
import ImageCacheManager from 'app/utils/image_cache_manager';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
@ -145,9 +146,10 @@ export default class AttachmentImage extends PureComponent {
}
return (
<TouchableWithoutFeedback
<TouchableWithFeedback
onPress={this.handlePreviewImage}
style={[style.container, {width: this.maxImageWidth + VIEWPORT_IMAGE_CONTAINER_OFFSET}]}
type={'none'}
>
<View
ref='item'
@ -155,7 +157,7 @@ export default class AttachmentImage extends PureComponent {
>
{progressiveImage}
</View>
</TouchableWithoutFeedback>
</TouchableWithFeedback>
);
}
}

View file

@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
import {
Keyboard,
Platform,
TouchableHighlight,
View,
ViewPropTypes,
} from 'react-native';
@ -16,6 +15,7 @@ import PostBody from 'app/components/post_body';
import PostHeader from 'app/components/post_header';
import PostPreHeader from 'app/components/post_header/post_pre_header';
import PostProfilePicture from 'app/components/post_profile_picture';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {NavigationTypes} from 'app/constants';
import {fromAutoResponder} from 'app/utils/general';
import {preventDoubleTap} from 'app/utils/tap';
@ -145,6 +145,7 @@ export default class Post extends PureComponent {
};
handlePress = preventDoubleTap(() => {
this.onPressDetected = true;
const {
onPress,
post,
@ -157,6 +158,10 @@ export default class Post extends PureComponent {
} else if ((isPostEphemeral(post) || post.state === Posts.POST_DELETED) && !showLongPost) {
this.onRemovePost(post);
}
setTimeout(() => {
this.onPressDetected = false;
}, 300);
});
handleReply = preventDoubleTap(() => {
@ -214,7 +219,7 @@ export default class Post extends PureComponent {
});
showPostOptions = () => {
if (this.postBodyRef?.current) {
if (this.postBodyRef?.current && !this.onPressDetected) {
this.postBodyRef.current.showPostOptions();
}
};
@ -302,12 +307,13 @@ export default class Post extends PureComponent {
const rightColumnStyle = [style.rightColumn, (commentedOnPost && isLastReply && style.rightColumnPadding)];
return (
<TouchableHighlight
<TouchableWithFeedback
style={[style.postStyle, highlighted, padding(isLandscape)]}
onPress={this.handlePress}
onLongPress={this.showPostOptions}
delayLongPress={75}
delayLongPress={100}
underlayColor={changeOpacity(theme.centerChannelColor, 0.1)}
cancelTouchOnPanning={true}
>
<React.Fragment>
<PostPreHeader
@ -345,7 +351,7 @@ export default class Post extends PureComponent {
</View>
</View>
</React.Fragment>
</TouchableHighlight>
</TouchableWithFeedback>
);
}
}

View file

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PostAttachmentImage should match snapshot 1`] = `
<TouchableWithoutFeedback
<TouchableWithFeedbackIOS
onPress={[Function]}
style={
Array [
@ -16,6 +16,7 @@ exports[`PostAttachmentImage should match snapshot 1`] = `
},
]
}
type="none"
>
<View>
<ForwardRef(forwardConnectRef)
@ -38,5 +39,5 @@ exports[`PostAttachmentImage should match snapshot 1`] = `
}
/>
</View>
</TouchableWithoutFeedback>
</TouchableWithFeedbackIOS>
`;

View file

@ -3,9 +3,10 @@
import PropTypes from 'prop-types';
import React from 'react';
import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native';
import {StyleSheet, View} from 'react-native';
import ProgressiveImage from 'app/components/progressive_image';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {isGifTooLarge} from 'app/utils/images';
export default class PostAttachmentImage extends React.PureComponent {
@ -40,9 +41,10 @@ export default class PostAttachmentImage extends React.PureComponent {
// Note that TouchableWithoutFeedback only works if its child is a View
return (
<TouchableWithoutFeedback
<TouchableWithFeedback
onPress={this.handlePress}
style={[styles.imageContainer, {height: this.props.height}]}
type={'none'}
>
<View ref={this.image}>
<ProgressiveImage
@ -52,7 +54,7 @@ export default class PostAttachmentImage extends React.PureComponent {
onError={this.props.onError}
/>
</View>
</TouchableWithoutFeedback>
</TouchableWithFeedback>
);
}
}

View file

@ -44,14 +44,14 @@ exports[`PostAttachmentOpenGraph should match snapshot, without image and descri
}
}
>
<TouchableOpacity
activeOpacity={0.2}
<TouchableWithFeedbackIOS
onPress={[Function]}
style={
Object {
"flex": 1,
}
}
type="opacity"
>
<Text
ellipsizeMode="tail"
@ -71,7 +71,7 @@ exports[`PostAttachmentOpenGraph should match snapshot, without image and descri
>
Title
</Text>
</TouchableOpacity>
</TouchableWithFeedbackIOS>
</View>
<View
style={
@ -90,8 +90,9 @@ exports[`PostAttachmentOpenGraph should match snapshot, without image and descri
]
}
>
<TouchableWithoutFeedback
<TouchableWithFeedbackIOS
onPress={[Function]}
type="none"
>
<Image
resizeMode="contain"
@ -107,7 +108,7 @@ exports[`PostAttachmentOpenGraph should match snapshot, without image and descri
]
}
/>
</TouchableWithoutFeedback>
</TouchableWithFeedbackIOS>
</View>
</View>
`;
@ -133,14 +134,14 @@ exports[`PostAttachmentOpenGraph should match snapshot, without site_name 1`] =
}
}
>
<TouchableOpacity
activeOpacity={0.2}
<TouchableWithFeedbackIOS
onPress={[Function]}
style={
Object {
"flex": 1,
}
}
type="opacity"
>
<Text
ellipsizeMode="tail"
@ -160,7 +161,7 @@ exports[`PostAttachmentOpenGraph should match snapshot, without site_name 1`] =
>
Title
</Text>
</TouchableOpacity>
</TouchableWithFeedbackIOS>
</View>
</View>
`;
@ -186,14 +187,14 @@ exports[`PostAttachmentOpenGraph should match snapshot, without title and url 1`
}
}
>
<TouchableOpacity
activeOpacity={0.2}
<TouchableWithFeedbackIOS
onPress={[Function]}
style={
Object {
"flex": 1,
}
}
type="opacity"
>
<Text
ellipsizeMode="tail"
@ -213,7 +214,7 @@ exports[`PostAttachmentOpenGraph should match snapshot, without title and url 1`
>
https://mattermost.com/
</Text>
</TouchableOpacity>
</TouchableWithFeedbackIOS>
</View>
</View>
`;
@ -264,8 +265,9 @@ exports[`PostAttachmentOpenGraph should match state and snapshot, on renderImage
]
}
>
<TouchableWithoutFeedback
<TouchableWithFeedbackIOS
onPress={[Function]}
type="none"
>
<Image
resizeMode="contain"
@ -281,6 +283,6 @@ exports[`PostAttachmentOpenGraph should match state and snapshot, on renderImage
]
}
/>
</TouchableWithoutFeedback>
</TouchableWithFeedbackIOS>
</View>
`;

View file

@ -7,12 +7,11 @@ import {
Image,
Linking,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from 'react-native';
import {TABLET_WIDTH} from 'app/components/sidebars/drawer_layout';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {DeviceTypes} from 'app/constants';
import ImageCacheManager from 'app/utils/image_cache_manager';
@ -255,15 +254,16 @@ export default class PostAttachmentOpenGraph extends PureComponent {
ref='item'
style={[style.imageContainer, {width, height}]}
>
<TouchableWithoutFeedback
<TouchableWithFeedback
onPress={this.handlePreviewImage}
type={'none'}
>
<Image
style={[style.image, {width, height}]}
source={source}
resizeMode='contain'
/>
</TouchableWithoutFeedback>
</TouchableWithFeedback>
</View>
);
};
@ -302,9 +302,10 @@ export default class PostAttachmentOpenGraph extends PureComponent {
if (title) {
siteTitle = (
<View style={style.wrapper}>
<TouchableOpacity
<TouchableWithFeedback
style={style.flex}
onPress={this.goToLink}
type={'opacity'}
>
<Text
style={[style.siteSubtitle, {marginRight: isReplyPost ? 10 : 0}]}
@ -313,7 +314,7 @@ export default class PostAttachmentOpenGraph extends PureComponent {
>
{title}
</Text>
</TouchableOpacity>
</TouchableWithFeedback>
</View>
);
}

View file

@ -3,12 +3,9 @@
import React from 'react';
import {shallow} from 'enzyme';
import {
Image,
TouchableWithoutFeedback,
TouchableOpacity,
} from 'react-native';
import {Image} from 'react-native';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import Preferences from 'mattermost-redux/constants/preferences';
import PostAttachmentOpenGraph from './post_attachment_opengraph';
@ -50,7 +47,7 @@ describe('PostAttachmentOpenGraph', () => {
wrapper.setProps({openGraphData});
expect(wrapper.getElement()).toMatchSnapshot();
expect(wrapper.find(TouchableOpacity).exists()).toEqual(true);
expect(wrapper.find(TouchableWithFeedback).exists()).toEqual(true);
});
test('should match snapshot, without site_name', () => {
@ -86,7 +83,7 @@ describe('PostAttachmentOpenGraph', () => {
expect(wrapper.instance().renderImage()).toMatchSnapshot();
expect(wrapper.state('hasImage')).toEqual(false);
expect(wrapper.find(Image).exists()).toEqual(false);
expect(wrapper.find(TouchableWithoutFeedback).exists()).toEqual(false);
expect(wrapper.find(TouchableWithFeedback).exists()).toEqual(false);
const images = [{height: 440, width: 1200, url: 'https://mattermost.com/logo.png'}];
const openGraphDataWithImage = {...openGraphData, images};
@ -95,7 +92,7 @@ describe('PostAttachmentOpenGraph', () => {
expect(wrapper.instance().renderImage()).toMatchSnapshot();
expect(wrapper.state('hasImage')).toEqual(true);
expect(wrapper.find(Image).exists()).toEqual(true);
expect(wrapper.find(TouchableWithoutFeedback).exists()).toEqual(true);
expect(wrapper.find(TouchableWithFeedback).exists()).toEqual(true);
});
test('should match state and snapshot, on renderDescription', () => {

View file

@ -5,13 +5,10 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Keyboard,
ScrollView,
TouchableOpacity,
View,
} from 'react-native';
import {intlShape} from 'react-intl';
import Icon from 'react-native-vector-icons/Ionicons';
import {Posts} from 'mattermost-redux/constants';
import CombinedSystemMessage from 'app/components/combined_system_message';
@ -19,6 +16,7 @@ import FormattedText from 'app/components/formatted_text';
import Markdown from 'app/components/markdown';
import MarkdownEmoji from 'app/components/markdown/markdown_emoji';
import ShowMoreButton from 'app/components/show_more_button';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {emptyFunction} from 'app/utils/general';
import {getMarkdownTextStyles, getMarkdownBlockStyles} from 'app/utils/markdown';
@ -414,15 +412,11 @@ export default class PostBody extends PureComponent {
if (!hasBeenDeleted) {
body = (
<View style={style.messageBody}>
<ScrollView
<View
style={{maxHeight: (showLongPost ? null : maxHeight), overflow: 'hidden'}}
scrollEnabled={false}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
keyboardShouldPersistTaps={'always'}
>
{messageComponent}
</ScrollView>
</View>
{isLongPost &&
<ShowMoreButton
highlight={highlight}
@ -441,16 +435,17 @@ export default class PostBody extends PureComponent {
<View style={replyBarStyle}/>
{body}
{isFailed &&
<TouchableOpacity
<TouchableWithFeedback
onPress={onFailedPostPress}
style={style.retry}
type={'opacity'}
>
<Icon
name='ios-information-circle-outline'
size={26}
color={theme.errorTextColor}
/>
</TouchableOpacity>
</TouchableWithFeedback>
}
</View>
);

View file

@ -9,7 +9,6 @@ import {
Linking,
Platform,
StyleSheet,
TouchableOpacity,
StatusBar,
} from 'react-native';
import {YouTubeStandaloneAndroid, YouTubeStandaloneIOS} from 'react-native-youtube';
@ -20,6 +19,7 @@ import EventEmitter from 'mattermost-redux/utils/event_emitter';
import {TABLET_WIDTH} from 'app/components/sidebars/drawer_layout';
import PostAttachmentImage from 'app/components/post_attachment_image';
import ProgressiveImage from 'app/components/progressive_image';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {DeviceTypes} from 'app/constants';
import CustomPropTypes from 'app/constants/custom_prop_types';
@ -231,9 +231,10 @@ export default class PostBodyAdditionalContent extends PureComponent {
const thumbUrl = `https://i.ytimg.com/vi/${videoId}/default.jpg`;
return (
<TouchableOpacity
<TouchableWithFeedback
style={[styles.imageContainer, {height: height || MAX_YOUTUBE_IMAGE_HEIGHT}]}
onPress={this.playYouTubeVideo}
type={'opacity'}
>
<ProgressiveImage
isBackgroundImage={true}
@ -243,17 +244,18 @@ export default class PostBodyAdditionalContent extends PureComponent {
resizeMode='cover'
onError={this.handleLinkLoadError}
>
<TouchableOpacity
<TouchableWithFeedback
style={styles.playButton}
onPress={this.playYouTubeVideo}
type={'opacity'}
>
<Image
source={require('assets/images/icons/youtube-play-icon.png')}
onPress={this.playYouTubeVideo}
/>
</TouchableOpacity>
</TouchableWithFeedback>
</ProgressiveImage>
</TouchableOpacity>
</TouchableWithFeedback>
);
}

View file

@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
import {
Platform,
Text,
TouchableOpacity,
View,
} from 'react-native';
@ -16,6 +15,7 @@ import FormattedDate from 'app/components/formatted_date';
import ReplyIcon from 'app/components/reply_icon';
import BotTag from 'app/components/bot_tag';
import GuestTag from 'app/components/guest_tag';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {emptyFunction} from 'app/utils/general';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
@ -87,7 +87,10 @@ export default class PostHeader extends PureComponent {
);
} else if (isBot) {
return (
<TouchableOpacity onPress={this.handleUsernamePress}>
<TouchableWithFeedback
onPress={this.handleUsernamePress}
type={'opacity'}
>
<View style={style.indicatorContainer}>
<Text style={style.displayName}>
{this.props.displayName}
@ -96,11 +99,14 @@ export default class PostHeader extends PureComponent {
theme={this.props.theme}
/>
</View>
</TouchableOpacity>
</TouchableWithFeedback>
);
} else if (isGuest) {
return (
<TouchableOpacity onPress={this.handleUsernamePress}>
<TouchableWithFeedback
onPress={this.handleUsernamePress}
type={'opacity'}
>
<View style={style.indicatorContainer}>
<Text style={style.displayName}>
{this.props.displayName}
@ -109,7 +115,7 @@ export default class PostHeader extends PureComponent {
theme={this.props.theme}
/>
</View>
</TouchableOpacity>
</TouchableWithFeedback>
);
} else if (fromAutoResponder) {
let name = this.props.displayName;
@ -139,11 +145,14 @@ export default class PostHeader extends PureComponent {
);
} else if (this.props.displayName) {
return (
<TouchableOpacity onPress={this.handleUsernamePress}>
<TouchableWithFeedback
onPress={this.handleUsernamePress}
type={'opacity'}
>
<Text style={style.displayName}>
{this.props.displayName}
</Text>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
@ -254,9 +263,10 @@ export default class PostHeader extends PureComponent {
</View>
</View>
{showReply &&
<TouchableOpacity
<TouchableWithFeedback
onPress={onPress}
style={style.replyIconContainer}
type={'opacity'}
>
<ReplyIcon
height={16}
@ -266,7 +276,7 @@ export default class PostHeader extends PureComponent {
{!isSearchResult &&
<Text style={style.replyText}>{commentCount}</Text>
}
</TouchableOpacity>
</TouchableWithFeedback>
}
</View>
{commentedOnDisplayName !== '' &&

View file

@ -5,12 +5,12 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Platform,
TouchableOpacity,
View,
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import FormattedText from 'app/components/formatted_text';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {makeStyleSheetFromTheme} from 'app/utils/theme';
export default class PostListRetry extends PureComponent {
@ -25,9 +25,10 @@ export default class PostListRetry extends PureComponent {
return (
<View style={style.container}>
<TouchableOpacity
<TouchableWithFeedback
onPress={retry}
style={style.buttonContainer}
type={'opacity'}
>
<View style={style.buttonWrapper}>
<Icon
@ -41,7 +42,7 @@ export default class PostListRetry extends PureComponent {
defaultMessage='Refresh'
style={style.text}
/>
</TouchableOpacity>
</TouchableWithFeedback>
</View>
);
}

View file

@ -3,10 +3,11 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Image, TouchableOpacity, View} from 'react-native';
import {Image, View} from 'react-native';
import AppIcon from 'app/components/app_icon';
import ProfilePicture from 'app/components/profile_picture';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {emptyFunction} from 'app/utils/general';
import webhookIcon from 'assets/images/icons/webhook.jpg';
import {ViewTypes} from 'app/constants';
@ -94,9 +95,12 @@ export default class PostProfilePicture extends PureComponent {
if (!fromWebHook) {
component = (
<TouchableOpacity onPress={onViewUserProfile}>
<TouchableWithFeedback
onPress={onViewUserProfile}
type={'opacity'}
>
{component}
</TouchableOpacity>
</TouchableWithFeedback>
);
}

View file

@ -5,10 +5,10 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
Text,
TouchableOpacity,
} from 'react-native';
import Emoji from 'app/components/emoji';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
export default class Reaction extends PureComponent {
@ -37,11 +37,12 @@ export default class Reaction extends PureComponent {
const styles = getStyleSheet(theme);
return (
<TouchableOpacity
<TouchableWithFeedback
onPress={this.handlePress}
onLongPress={onLongPress}
delayLongPress={350}
style={[styles.reaction, (highlight && styles.highlight)]}
type={'opacity'}
>
<Emoji
emojiName={emojiName}
@ -49,7 +50,7 @@ export default class Reaction extends PureComponent {
padding={5}
/>
<Text style={styles.count}>{count}</Text>
</TouchableOpacity>
</TouchableWithFeedback>
);
}
}

View file

@ -6,11 +6,11 @@ import PropTypes from 'prop-types';
import {
Image,
ScrollView,
TouchableOpacity,
} from 'react-native';
import {intlShape} from 'react-intl';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {preventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import addReactionIcon from 'assets/images/icons/reaction.png';
@ -72,12 +72,17 @@ export default class Reactions extends PureComponent {
};
handleReactionPress = (emoji, remove) => {
this.onPressDetected = true;
const {actions, postId} = this.props;
if (remove && this.props.canRemoveReaction) {
actions.removeReaction(postId, emoji);
} else if (!remove && this.props.canAddReaction) {
actions.addReaction(postId, emoji);
}
setTimeout(() => {
this.onPressDetected = false;
}, 300);
};
showReactionList = () => {
@ -88,8 +93,10 @@ export default class Reactions extends PureComponent {
postId,
};
actions.showModalOverCurrentContext(screen, passProps);
}
if (!this.onPressDetected) {
actions.showModalOverCurrentContext(screen, passProps);
}
};
renderReactions = () => {
const {currentUserId, reactions, theme, postId} = this.props;
@ -135,16 +142,17 @@ export default class Reactions extends PureComponent {
let addMoreReactions = null;
if (canAddReaction) {
addMoreReactions = (
<TouchableOpacity
<TouchableWithFeedback
key='addReaction'
onPress={this.handleAddReaction}
style={[styles.reaction]}
type={'opacity'}
>
<Image
source={addReactionIcon}
style={styles.addReaction}
/>
</TouchableOpacity>
</TouchableWithFeedback>
);
}

View file

@ -2,10 +2,10 @@
// See LICENSE.txt for license information.
import React, {memo} from 'react';
import {TouchableOpacity, View} from 'react-native';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
let PaperPlane = null;
@ -37,14 +37,15 @@ function SendButton(props) {
}
return (
<TouchableOpacity
<TouchableWithFeedback
onPress={props.handleSendMessage}
style={style.sendButtonContainer}
type={'opacity'}
>
<View style={style.sendButton}>
{icon}
</View>
</TouchableOpacity>
</TouchableWithFeedback>
);
}

View file

@ -96,8 +96,7 @@ exports[`ShowMoreButton should match, full snapshot 1`] = `
}
}
/>
<TouchableOpacity
activeOpacity={0.2}
<TouchableWithFeedbackIOS
onPress={[MockFunction]}
style={
Object {
@ -109,6 +108,7 @@ exports[`ShowMoreButton should match, full snapshot 1`] = `
"paddingHorizontal": 10,
}
}
type="opacity"
>
<View
style={
@ -143,7 +143,7 @@ exports[`ShowMoreButton should match, full snapshot 1`] = `
}
/>
</View>
</TouchableOpacity>
</TouchableWithFeedbackIOS>
<View
style={
Object {

View file

@ -3,12 +3,12 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Text, TouchableOpacity, View} from 'react-native';
import {Text, View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import FormattedText from 'app/components/formatted_text';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {t} from 'app/utils/i18n';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
export default class ShowMoreButton extends PureComponent {
@ -73,12 +73,13 @@ export default class ShowMoreButton extends PureComponent {
}
<View style={style.container}>
<View style={style.dividerLeft}/>
<TouchableOpacity
<TouchableWithFeedback
onPress={this.props.onPress}
style={style.buttonContainer}
type={'opacity'}
>
{this.renderButton(showMore, style)}
</TouchableOpacity>
</TouchableWithFeedback>
<View style={style.dividerRight}/>
</View>
</View>

View file

@ -2,13 +2,12 @@
// See LICENSE.txt for license information.
import React from 'react';
import {TouchableOpacity} from 'react-native';
import {shallow} from 'enzyme';
import LinearGradient from 'react-native-linear-gradient';
import Preferences from 'mattermost-redux/constants/preferences';
import LinearGradient from 'react-native-linear-gradient';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import ShowMoreButton from './show_more_button';
describe('ShowMoreButton', () => {
@ -55,7 +54,7 @@ describe('ShowMoreButton', () => {
/>
);
wrapper.find(TouchableOpacity).props().onPress();
wrapper.find(TouchableWithFeedback).props().onPress();
expect(onPress).toHaveBeenCalledTimes(1);
});
});

View file

@ -0,0 +1,5 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import TouchableWithFeedback from './touchable_with_feedback';
export default TouchableWithFeedback;

View file

@ -0,0 +1,58 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/* eslint-disable new-cap */
import React, {PureComponent} from 'react';
import {TouchableNativeFeedback, TouchableOpacity, TouchableWithoutFeedback, View} from 'react-native';
import PropTypes from 'prop-types';
import CustomPropTypes from 'app/constants/custom_prop_types';
export default class TouchableWithFeedbackAndroid extends PureComponent {
static propTypes = {
children: CustomPropTypes.Children,
underlayColor: PropTypes.string,
type: PropTypes.oneOf(['native', 'opacity', 'none']),
};
static defaultProps = {
type: 'native',
};
render() {
const {children, underlayColor, type, ...props} = this.props;
switch (type) {
case 'native':
return (
<TouchableNativeFeedback
{...props}
background={TouchableNativeFeedback.Ripple(underlayColor || '#000', false)}
>
<View>
{children}
</View>
</TouchableNativeFeedback>
);
case 'opacity':
return (
<TouchableOpacity
{...props}
>
{children}
</TouchableOpacity>
);
case 'none':
return (
<TouchableWithoutFeedback
{...props}
>
{children}
</TouchableWithoutFeedback>
);
}
return null;
}
}

View file

@ -0,0 +1,65 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {PureComponent} from 'react';
import {PanResponder, TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback, View} from 'react-native';
import PropTypes from 'prop-types';
import CustomPropTypes from 'app/constants/custom_prop_types';
export default class TouchableWithFeedbackIOS extends PureComponent {
static propTypes = {
children: CustomPropTypes.Children,
cancelTouchOnPanning: PropTypes.bool,
type: PropTypes.oneOf(['native', 'opacity', 'none']),
};
static defaultProps = {
type: 'native',
};
constructor(props) {
super(props);
this.panResponder = PanResponder.create({
onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
return this.props.cancelTouchOnPanning && (gestureState.dx >= 5 || gestureState.dy >= 5 || gestureState.vx > 5);
},
});
}
render() {
const {children, type, ...props} = this.props;
switch (type) {
case 'native':
return (
<View {...this.panResponder.panHandlers}>
<TouchableHighlight
{...props}
>
{children}
</TouchableHighlight>
</View>
);
case 'opacity':
return (
<TouchableOpacity
{...props}
>
{children}
</TouchableOpacity>
);
case 'none':
return (
<TouchableWithoutFeedback
{...props}
>
{children}
</TouchableWithoutFeedback>
);
}
return null;
}
}

View file

@ -6,14 +6,14 @@ import PropTypes from 'prop-types';
import {
Switch,
Text,
TouchableHighlight,
View,
} from 'react-native';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import FormattedText from 'app/components/formatted_text';
import VectorIcon from 'app/components/vector_icon.js';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import VectorIcon from 'app/components/vector_icon';
const createStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
@ -55,9 +55,9 @@ const createStyleSheet = makeStyleSheetFromTheme((theme) => {
function createTouchableComponent(children, action) {
return (
<TouchableHighlight onPress={action}>
<TouchableWithFeedback onPress={action}>
{children}
</TouchableHighlight>
</TouchableWithFeedback>
);
}

6
package-lock.json generated
View file

@ -16537,9 +16537,9 @@
"integrity": "sha512-e2zv0BiP9SRdr1vLDUyC2WbWHfgNV1a3BhRxK1ENjXVRY8mu+dfaaIHhFXdvYue//MEuGUQstu61NZoiO1u2KA=="
},
"react-native-gesture-handler": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.2.1.tgz",
"integrity": "sha512-c1+L72Vjc/bwHKcIJ8a2/88SW9l3/axcAIpg3zB1qTzwdCxHZJeQn6d58cQXHPepxFBbgfTCo60B7SipSfo+zw==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.3.0.tgz",
"integrity": "sha512-ASRFIXBuKRvqlmwkWJhV8yP2dTpvcqVrLNpd7FKVBFHYWr6SAxjGyO9Ik8w1lAxDhMlRP2IcJ9p9eq5X2WWeLQ==",
"requires": {
"hoist-non-react-statics": "^2.3.1",
"invariant": "^2.2.2",

View file

@ -38,7 +38,7 @@
"react-native-doc-viewer": "2.7.8",
"react-native-document-picker": "2.3.0",
"react-native-exception-handler": "2.10.7",
"react-native-gesture-handler": "1.2.1",
"react-native-gesture-handler": "1.3.0",
"react-native-haptic-feedback": "1.8.2",
"react-native-image-gallery": "github:mattermost/react-native-image-gallery#c1a9f7118e90cc87d47620bc0584c9cac4b0cf38",
"react-native-image-picker": "0.28.1",