[FIX] Better message actions (#567)

This commit is contained in:
Pranay Ankit 2019-01-30 17:41:02 +05:30 committed by Diego Mello
parent 754508c2d9
commit e416fe0c68
11 changed files with 118 additions and 111 deletions

View File

@ -190,6 +190,7 @@ configurations.all {
} }
dependencies { dependencies {
implementation project(':react-native-action-sheet')
implementation project(':react-native-device-info') implementation project(':react-native-device-info')
implementation project(':react-native-gesture-handler') implementation project(':react-native-gesture-handler')
implementation project(':react-native-image-crop-picker') implementation project(':react-native-image-crop-picker')

View File

@ -28,6 +28,7 @@ import com.wix.reactnativenotifications.core.notification.INotificationsApplicat
import com.wix.reactnativenotifications.core.notification.IPushNotification; import com.wix.reactnativenotifications.core.notification.IPushNotification;
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage; import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
import com.learnium.RNDeviceInfo.RNDeviceInfo; import com.learnium.RNDeviceInfo.RNDeviceInfo;
import com.actionsheet.ActionSheetPackage;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -71,6 +72,7 @@ public class MainApplication extends NavigationApplication implements INotificat
public List<ReactPackage> createAdditionalReactPackages() { public List<ReactPackage> createAdditionalReactPackages() {
return Arrays.<ReactPackage>asList( return Arrays.<ReactPackage>asList(
new MainReactPackage(), new MainReactPackage(),
new ActionSheetPackage(),
new RNDeviceInfo(), new RNDeviceInfo(),
new RNGestureHandlerPackage(), new RNGestureHandlerPackage(),
new PickerPackage(), new PickerPackage(),

View File

@ -1,4 +1,6 @@
rootProject.name = 'RocketChatRN' rootProject.name = 'RocketChatRN'
include ':react-native-action-sheet'
project(':react-native-action-sheet').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-action-sheet/android')
include ':react-native-device-info' include ':react-native-device-info'
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android') project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
include ':react-native-gesture-handler' include ':react-native-gesture-handler'

View File

@ -4,7 +4,7 @@ import {
Alert, Clipboard, Vibration, Share Alert, Clipboard, Vibration, Share
} from 'react-native'; } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ActionSheet from 'react-native-actionsheet'; import ActionSheet from 'react-native-action-sheet';
import * as moment from 'moment'; import * as moment from 'moment';
import { import {
@ -125,9 +125,7 @@ export default class MessageActions extends React.Component {
this.DELETE_INDEX = this.options.length - 1; this.DELETE_INDEX = this.options.length - 1;
} }
setTimeout(() => { setTimeout(() => {
if (this.actionSheet && this.actionSheet.show) { this.showActionSheet();
this.actionSheet.show();
}
Vibration.vibrate(50); Vibration.vibrate(50);
}); });
} }
@ -141,6 +139,17 @@ export default class MessageActions extends React.Component {
this.hasForceDeletePermission = result[permissions[2]]; this.hasForceDeletePermission = result[permissions[2]];
} }
showActionSheet = () => {
ActionSheet.showActionSheetWithOptions({
options: this.options,
cancelButtonIndex: this.CANCEL_INDEX,
destructiveButtonIndex: this.DELETE_INDEX,
title: I18n.t('Message_actions')
}, (actionIndex) => {
this.handleActionPress(actionIndex);
});
}
getPermalink = async(message) => { getPermalink = async(message) => {
try { try {
return await RocketChat.getPermalink(message); return await RocketChat.getPermalink(message);
@ -326,15 +335,7 @@ export default class MessageActions extends React.Component {
render() { render() {
return ( return (
<ActionSheet null
ref={o => this.actionSheet = o}
title={I18n.t('Message_actions')}
testID='message-actions'
options={this.options}
cancelButtonIndex={this.CANCEL_INDEX}
destructiveButtonIndex={this.DELETE_INDEX}
onPress={this.handleActionPress}
/>
); );
} }
} }

View File

@ -1,6 +1,6 @@
import React, { PureComponent } from 'react'; import { PureComponent } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ActionSheet from 'react-native-actionsheet'; import ActionSheet from 'react-native-action-sheet';
import I18n from '../../i18n'; import I18n from '../../i18n';
@ -27,9 +27,16 @@ export default class FilesActions extends PureComponent {
this.LIBRARY_INDEX = 2; this.LIBRARY_INDEX = 2;
setTimeout(() => { setTimeout(() => {
if (this.actionSheet && this.actionSheet.show) { this.showActionSheet();
this.actionSheet.show(); });
} }
showActionSheet = () => {
ActionSheet.showActionSheetWithOptions({
options: this.options,
cancelButtonIndex: this.CANCEL_INDEX
}, (actionIndex) => {
this.handleActionPress(actionIndex);
}); });
} }
@ -50,12 +57,7 @@ export default class FilesActions extends PureComponent {
render() { render() {
return ( return (
<ActionSheet null
ref={o => this.actionSheet = o}
options={this.options}
cancelButtonIndex={this.CANCEL_INDEX}
onPress={this.handleActionPress}
/>
); );
} }
} }

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ActionSheet from 'react-native-actionsheet'; import ActionSheet from 'react-native-action-sheet';
import { errorActionsHide as errorActionsHideAction } from '../actions/messages'; import { errorActionsHide as errorActionsHideAction } from '../actions/messages';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
@ -23,21 +23,6 @@ export default class MessageErrorActions extends React.Component {
actionMessage: PropTypes.object actionMessage: PropTypes.object
}; };
// eslint-disable-next-line react/sort-comp
constructor(props) {
super(props);
this.handleActionPress = this.handleActionPress.bind(this);
this.options = [I18n.t('Cancel'), I18n.t('Delete'), I18n.t('Resend')];
this.CANCEL_INDEX = 0;
this.DELETE_INDEX = 1;
this.RESEND_INDEX = 2;
setTimeout(() => {
if (this.actionSheet && this.actionSheet.show) {
this.actionSheet.show();
}
});
}
handleResend = protectedFunction(() => { handleResend = protectedFunction(() => {
const { actionMessage } = this.props; const { actionMessage } = this.props;
RocketChat.resendMessage(actionMessage._id); RocketChat.resendMessage(actionMessage._id);
@ -51,6 +36,30 @@ export default class MessageErrorActions extends React.Component {
}); });
}) })
// eslint-disable-next-line react/sort-comp
constructor(props) {
super(props);
this.handleActionPress = this.handleActionPress.bind(this);
this.options = [I18n.t('Cancel'), I18n.t('Delete'), I18n.t('Resend')];
this.CANCEL_INDEX = 0;
this.DELETE_INDEX = 1;
this.RESEND_INDEX = 2;
setTimeout(() => {
this.showActionSheet();
});
}
showActionSheet = () => {
ActionSheet.showActionSheetWithOptions({
options: this.options,
cancelButtonIndex: this.CANCEL_INDEX,
destructiveButtonIndex: this.DELETE_INDEX,
title: I18n.t('Message_actions')
}, (actionIndex) => {
this.handleActionPress(actionIndex);
});
}
handleActionPress = (actionIndex) => { handleActionPress = (actionIndex) => {
const { errorActionsHide } = this.props; const { errorActionsHide } = this.props;
switch (actionIndex) { switch (actionIndex) {
@ -68,14 +77,7 @@ export default class MessageErrorActions extends React.Component {
render() { render() {
return ( return (
<ActionSheet null
ref={o => this.actionSheet = o}
title={I18n.t('Message_actions')}
options={this.options}
cancelButtonIndex={this.CANCEL_INDEX}
destructiveButtonIndex={this.DELETE_INDEX}
onPress={this.handleActionPress}
/>
); );
} }
} }

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FlatList, View, Text } from 'react-native'; import { FlatList, View, Text } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ActionSheet from 'react-native-actionsheet'; import ActionSheet from 'react-native-action-sheet';
import SafeAreaView from 'react-native-safe-area-view'; import SafeAreaView from 'react-native-safe-area-view';
import equal from 'deep-equal'; import equal from 'deep-equal';
@ -71,9 +71,17 @@ export default class PinnedMessagesView extends LoggedView {
onLongPress = (message) => { onLongPress = (message) => {
this.setState({ message }); this.setState({ message });
if (this.actionSheet && this.actionSheet.show) { this.showActionSheet();
this.actionSheet.show();
} }
showActionSheet = () => {
ActionSheet.showActionSheetWithOptions({
options,
cancelButtonIndex: CANCEL_INDEX,
title: I18n.t('Actions')
}, (actionIndex) => {
this.handleActionPress(actionIndex);
});
} }
handleActionPress = (actionIndex) => { handleActionPress = (actionIndex) => {
@ -169,13 +177,6 @@ export default class PinnedMessagesView extends LoggedView {
onEndReached={this.load} onEndReached={this.load}
ListFooterComponent={loading ? <RCActivityIndicator /> : null} ListFooterComponent={loading ? <RCActivityIndicator /> : null}
/> />
<ActionSheet
ref={o => this.actionSheet = o}
title={I18n.t('Actions')}
options={options}
cancelButtonIndex={CANCEL_INDEX}
onPress={this.handleActionPress}
/>
</SafeAreaView> </SafeAreaView>
); );
} }

View File

@ -1,7 +1,9 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FlatList, View, Vibration } from 'react-native'; import {
import ActionSheet from 'react-native-actionsheet'; FlatList, View, Vibration
} from 'react-native';
import ActionSheet from 'react-native-action-sheet';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Navigation } from 'react-native-navigation'; import { Navigation } from 'react-native-navigation';
import SafeAreaView from 'react-native-safe-area-view'; import SafeAreaView from 'react-native-safe-area-view';
@ -161,26 +163,30 @@ export default class RoomMembersView extends LoggedView {
if (!this.permissions['mute-user']) { if (!this.permissions['mute-user']) {
return; return;
} }
try {
const { room } = this.state; const { room } = this.state;
const { muted } = room; const { muted } = room;
const options = [I18n.t('Cancel')]; this.actionSheetOptions = [I18n.t('Cancel')];
const userIsMuted = !!muted.find(m => m.value === user.username); const userIsMuted = !!muted.find(m => m.value === user.username);
user.muted = userIsMuted; user.muted = userIsMuted;
if (userIsMuted) { if (userIsMuted) {
options.push(I18n.t('Unmute')); this.actionSheetOptions.push(I18n.t('Unmute'));
} else { } else {
options.push(I18n.t('Mute')); this.actionSheetOptions.push(I18n.t('Mute'));
} }
this.setState({ userLongPressed: user, options }); this.setState({ userLongPressed: user });
Vibration.vibrate(50); Vibration.vibrate(50);
if (this.actionSheet && this.actionSheet.show) { this.showActionSheet();
this.actionSheet.show();
}
} catch (error) {
console.log('onLongPressUser -> catch -> error', error);
} }
showActionSheet = () => {
ActionSheet.showActionSheetWithOptions({
options: this.actionSheetOptions,
cancelButtonIndex: this.CANCEL_INDEX,
title: I18n.t('Actions')
}, (actionIndex) => {
this.handleActionPress(actionIndex);
});
} }
fetchMembers = async(status) => { fetchMembers = async(status) => {
@ -253,7 +259,7 @@ export default class RoomMembersView extends LoggedView {
render() { render() {
const { const {
filtering, members, membersFiltered, options filtering, members, membersFiltered
} = this.state; } = this.state;
return ( return (
<SafeAreaView style={styles.list} testID='room-members-view' forceInset={{ bottom: 'never' }}> <SafeAreaView style={styles.list} testID='room-members-view' forceInset={{ bottom: 'never' }}>
@ -266,13 +272,6 @@ export default class RoomMembersView extends LoggedView {
ListHeaderComponent={this.renderSearchBar} ListHeaderComponent={this.renderSearchBar}
{...scrollPersistTaps} {...scrollPersistTaps}
/> />
<ActionSheet
ref={o => this.actionSheet = o}
title={I18n.t('Actions')}
options={options}
cancelButtonIndex={this.CANCEL_INDEX}
onPress={this.handleActionPress}
/>
</SafeAreaView> </SafeAreaView>
); );
} }

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FlatList, View, Text } from 'react-native'; import { FlatList, View, Text } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ActionSheet from 'react-native-actionsheet'; import ActionSheet from 'react-native-action-sheet';
import SafeAreaView from 'react-native-safe-area-view'; import SafeAreaView from 'react-native-safe-area-view';
import equal from 'deep-equal'; import equal from 'deep-equal';
@ -71,9 +71,17 @@ export default class StarredMessagesView extends LoggedView {
onLongPress = (message) => { onLongPress = (message) => {
this.setState({ message }); this.setState({ message });
if (this.actionSheet && this.actionSheet.show) { this.showActionSheet();
this.actionSheet.show();
} }
showActionSheet = () => {
ActionSheet.showActionSheetWithOptions({
options,
cancelButtonIndex: CANCEL_INDEX,
title: I18n.t('Actions')
}, (actionIndex) => {
this.handleActionPress(actionIndex);
});
} }
handleActionPress = (actionIndex) => { handleActionPress = (actionIndex) => {
@ -175,13 +183,6 @@ export default class StarredMessagesView extends LoggedView {
onEndReached={this.load} onEndReached={this.load}
ListFooterComponent={loading ? <RCActivityIndicator /> : null} ListFooterComponent={loading ? <RCActivityIndicator /> : null}
/> />
<ActionSheet
ref={o => this.actionSheet = o}
title={I18n.t('Actions')}
options={options}
cancelButtonIndex={CANCEL_INDEX}
onPress={this.handleActionPress}
/>
</SafeAreaView> </SafeAreaView>
); );
} }

20
package-lock.json generated
View File

@ -6710,7 +6710,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
"optional": true,
"requires": { "requires": {
"tweetnacl": "^0.14.3" "tweetnacl": "^0.14.3"
} }
@ -9403,7 +9402,6 @@
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
"optional": true,
"requires": { "requires": {
"jsbn": "~0.1.0" "jsbn": "~0.1.0"
} }
@ -15346,8 +15344,7 @@
"jsbn": { "jsbn": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
"optional": true
}, },
"jsc-android": { "jsc-android": {
"version": "236355.1.1", "version": "236355.1.1",
@ -20543,12 +20540,11 @@
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
"dev": true
}, },
"sane": { "sane": {
"version": "2.5.0", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/sane/-/sane-2.5.0.tgz", "resolved": "http://registry.npmjs.org/sane/-/sane-2.5.0.tgz",
"integrity": "sha512-glfKd7YH4UCrh/7dD+UESsr8ylKWRE7UQPoXuz28FgmcF0ViJQhCTCCZHICRKxf8G8O1KdLEn20dcICK54c7ew==", "integrity": "sha512-glfKd7YH4UCrh/7dD+UESsr8ylKWRE7UQPoXuz28FgmcF0ViJQhCTCCZHICRKxf8G8O1KdLEn20dcICK54c7ew==",
"requires": { "requires": {
"anymatch": "^2.0.0", "anymatch": "^2.0.0",
@ -21846,9 +21842,9 @@
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
}, },
"sshpk": { "sshpk": {
"version": "1.13.1", "version": "1.15.2",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz",
"integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==",
"requires": { "requires": {
"asn1": "~0.2.3", "asn1": "~0.2.3",
"assert-plus": "^1.0.0", "assert-plus": "^1.0.0",
@ -21857,6 +21853,7 @@
"ecc-jsbn": "~0.1.1", "ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1", "getpass": "^0.1.1",
"jsbn": "~0.1.0", "jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0" "tweetnacl": "~0.14.0"
} }
}, },
@ -22904,8 +22901,7 @@
"tweetnacl": { "tweetnacl": {
"version": "0.14.5", "version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
"optional": true
}, },
"type-check": { "type-check": {
"version": "0.3.2", "version": "0.3.2",

View File

@ -36,7 +36,7 @@
"react": "16.6.3", "react": "16.6.3",
"react-emojione": "^5.0.1", "react-emojione": "^5.0.1",
"react-native": "^0.57.8", "react-native": "^0.57.8",
"react-native-actionsheet": "^2.4.2", "react-native-action-sheet": "^2.1.0",
"react-native-audio": "^4.3.0", "react-native-audio": "^4.3.0",
"react-native-device-info": "^0.25.1", "react-native-device-info": "^0.25.1",
"react-native-dialog": "^5.5.0", "react-native-dialog": "^5.5.0",