[FIX] Long press gestures not working properly on Android (#2354)

This commit is contained in:
Diego Mello 2020-07-29 18:03:17 -03:00 committed by GitHub
parent c37eb99e55
commit a584e68bbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 97 deletions

View File

@ -1,13 +1,14 @@
import React from 'react'; import React from 'react';
import { Text, View, StyleSheet } from 'react-native'; import {
Text, View, StyleSheet, Pressable
} from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Avatar from '../containers/Avatar'; import Avatar from '../containers/Avatar';
import { CustomIcon } from '../lib/Icons'; import { CustomIcon } from '../lib/Icons';
import sharedStyles from '../views/Styles'; import sharedStyles from '../views/Styles';
import { themes } from '../constants/colors'; import { themes } from '../constants/colors';
import Touch from '../utils/touch'; import { isIOS } from '../utils/deviceInfo';
import LongPress from '../utils/longPress';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
button: { button: {
@ -43,23 +44,28 @@ const styles = StyleSheet.create({
const UserItem = ({ const UserItem = ({
name, username, onPress, testID, onLongPress, style, icon, baseUrl, user, theme name, username, onPress, testID, onLongPress, style, icon, baseUrl, user, theme
}) => ( }) => (
<LongPress onLongPress={onLongPress}> <Pressable
<Touch onPress={onPress}
onPress={onPress} onLongPress={onLongPress}
style={{ backgroundColor: themes[theme].backgroundColor }} testID={testID}
testID={testID} android_ripple={{
theme={theme} color: themes[theme].bannerBackground
> }}
<View style={[styles.container, styles.button, style]}> style={({ pressed }) => ({
<Avatar text={username} size={30} type='d' style={styles.avatar} baseUrl={baseUrl} userId={user.id} token={user.token} /> backgroundColor: isIOS && pressed
<View style={styles.textContainer}> ? themes[theme].bannerBackground
<Text style={[styles.name, { color: themes[theme].titleText }]} numberOfLines={1}>{name}</Text> : 'transparent'
<Text style={[styles.username, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>@{username}</Text> })}
</View> >
{icon ? <CustomIcon name={icon} size={22} style={[styles.icon, { color: themes[theme].actionTintColor }]} /> : null} <View style={[styles.container, styles.button, style]}>
<Avatar text={username} size={30} type='d' style={styles.avatar} baseUrl={baseUrl} userId={user.id} token={user.token} />
<View style={styles.textContainer}>
<Text style={[styles.name, { color: themes[theme].titleText }]} numberOfLines={1}>{name}</Text>
<Text style={[styles.username, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>@{username}</Text>
</View> </View>
</Touch> {icon ? <CustomIcon name={icon} size={22} style={[styles.icon, { color: themes[theme].actionTintColor }]} /> : null}
</LongPress> </View>
</Pressable>
); );
UserItem.propTypes = { UserItem.propTypes = {

View File

@ -1,44 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { State, LongPressGestureHandler } from 'react-native-gesture-handler';
class LongPress extends React.Component {
setNativeProps(props) {
this.ref.setNativeProps(props);
}
getRef = (ref) => {
this.ref = ref;
};
longPress = ({ nativeEvent }) => {
const { onLongPress } = this.props;
if (nativeEvent.state === State.ACTIVE) {
if (onLongPress) {
onLongPress();
}
}
};
render() {
const { children, ...props } = this.props;
return (
<LongPressGestureHandler
onHandlerStateChange={this.longPress}
minDurationMs={800}
ref={this.getRef}
{...props}
>
{children}
</LongPressGestureHandler>
);
}
}
LongPress.propTypes = {
children: PropTypes.node,
onLongPress: PropTypes.func
};
export default LongPress;

View File

@ -1,6 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { import {
View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList, Image View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList, Image, Pressable
} from 'react-native'; } from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect, batch } from 'react-redux'; import { connect, batch } from 'react-redux';
@ -12,7 +12,6 @@ import { toggleServerDropdown as toggleServerDropdownAction } from '../../action
import { selectServerRequest as selectServerRequestAction, serverInitAdd as serverInitAddAction } from '../../actions/server'; import { selectServerRequest as selectServerRequestAction, serverInitAdd as serverInitAddAction } from '../../actions/server';
import { appStart as appStartAction, ROOT_NEW_SERVER } from '../../actions/app'; import { appStart as appStartAction, ROOT_NEW_SERVER } from '../../actions/app';
import styles from './styles'; import styles from './styles';
import Touch from '../../utils/touch';
import RocketChat from '../../lib/rocketchat'; import RocketChat from '../../lib/rocketchat';
import I18n from '../../i18n'; import I18n from '../../i18n';
import EventEmitter from '../../utils/events'; import EventEmitter from '../../utils/events';
@ -21,10 +20,9 @@ import database from '../../lib/database';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { withTheme } from '../../theme'; import { withTheme } from '../../theme';
import { KEY_COMMAND, handleCommandSelectServer } from '../../commands'; import { KEY_COMMAND, handleCommandSelectServer } from '../../commands';
import { isTablet } from '../../utils/deviceInfo'; import { isTablet, isIOS } from '../../utils/deviceInfo';
import { localAuthenticate } from '../../utils/localAuthentication'; import { localAuthenticate } from '../../utils/localAuthentication';
import { showConfirmationAlert } from '../../utils/info'; import { showConfirmationAlert } from '../../utils/info';
import LongPress from '../../utils/longPress';
import { headerHeight } from '../../containers/Header'; import { headerHeight } from '../../containers/Header';
import { goRoom } from '../../utils/goRoom'; import { goRoom } from '../../utils/goRoom';
@ -201,37 +199,43 @@ class ServerDropdown extends Component {
const { server, theme } = this.props; const { server, theme } = this.props;
return ( return (
<LongPress onLongPress={() => (item.id === server || this.remove(item.id))}> <Pressable
<Touch onPress={() => this.select(item.id)}
onPress={() => this.select(item.id)} onLongPress={() => (item.id === server || this.remove(item.id))}
testID={`rooms-list-header-server-${ item.id }`} testID={`rooms-list-header-server-${ item.id }`}
theme={theme} android_ripple={{
> color: themes[theme].bannerBackground
<View style={styles.serverItemContainer}> }}
{item.iconURL style={({ pressed }) => ({
? ( backgroundColor: isIOS && pressed
<Image ? themes[theme].bannerBackground
source={{ uri: item.iconURL }} : 'transparent'
defaultSource={{ uri: 'logo' }} })}
style={styles.serverIcon} >
onError={() => console.warn('error loading serverIcon')} <View style={styles.serverItemContainer}>
/> {item.iconURL
) ? (
: ( <Image
<Image source={{ uri: item.iconURL }}
source={{ uri: 'logo' }} defaultSource={{ uri: 'logo' }}
style={styles.serverIcon} style={styles.serverIcon}
/> onError={() => console.warn('error loading serverIcon')}
) />
} )
<View style={styles.serverTextContainer}> : (
<Text style={[styles.serverName, { color: themes[theme].titleText }]} numberOfLines={1}>{item.name || item.id}</Text> <Image
<Text style={[styles.serverUrl, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>{item.id}</Text> source={{ uri: 'logo' }}
</View> style={styles.serverIcon}
{item.id === server ? <Check theme={theme} /> : null} />
)
}
<View style={styles.serverTextContainer}>
<Text style={[styles.serverName, { color: themes[theme].titleText }]} numberOfLines={1}>{item.name || item.id}</Text>
<Text style={[styles.serverUrl, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>{item.id}</Text>
</View> </View>
</Touch> {item.id === server ? <Check theme={theme} /> : null}
</LongPress> </View>
</Pressable>
); );
} }