From e416fe0c68896af108f9bb8e410d011ff655fbf2 Mon Sep 17 00:00:00 2001 From: Pranay Ankit Date: Wed, 30 Jan 2019 17:41:02 +0530 Subject: [PATCH] [FIX] Better message actions (#567) --- android/app/build.gradle | 1 + .../rocket/reactnative/MainApplication.java | 2 + android/settings.gradle | 2 + app/containers/MessageActions.js | 27 ++++----- app/containers/MessageBox/FilesActions.js | 24 ++++---- app/containers/MessageErrorActions.js | 50 +++++++++-------- app/views/PinnedMessagesView/index.js | 23 ++++---- app/views/RoomMembersView/index.js | 55 +++++++++---------- app/views/StarredMessagesView/index.js | 23 ++++---- package-lock.json | 20 +++---- package.json | 2 +- 11 files changed, 118 insertions(+), 111 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index be575bdf..0cb7c0ad 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -190,6 +190,7 @@ configurations.all { } dependencies { + implementation project(':react-native-action-sheet') implementation project(':react-native-device-info') implementation project(':react-native-gesture-handler') implementation project(':react-native-image-crop-picker') diff --git a/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java b/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java index 48a05a70..e5865755 100644 --- a/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java +++ b/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java @@ -28,6 +28,7 @@ import com.wix.reactnativenotifications.core.notification.INotificationsApplicat import com.wix.reactnativenotifications.core.notification.IPushNotification; import com.swmansion.gesturehandler.react.RNGestureHandlerPackage; import com.learnium.RNDeviceInfo.RNDeviceInfo; +import com.actionsheet.ActionSheetPackage; import java.util.Arrays; import java.util.List; @@ -71,6 +72,7 @@ public class MainApplication extends NavigationApplication implements INotificat public List createAdditionalReactPackages() { return Arrays.asList( new MainReactPackage(), + new ActionSheetPackage(), new RNDeviceInfo(), new RNGestureHandlerPackage(), new PickerPackage(), diff --git a/android/settings.gradle b/android/settings.gradle index 1a592d3b..4a6e6fa6 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,6 @@ 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' project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android') include ':react-native-gesture-handler' diff --git a/app/containers/MessageActions.js b/app/containers/MessageActions.js index 36f257b7..2527d052 100644 --- a/app/containers/MessageActions.js +++ b/app/containers/MessageActions.js @@ -4,7 +4,7 @@ import { Alert, Clipboard, Vibration, Share } from 'react-native'; import { connect } from 'react-redux'; -import ActionSheet from 'react-native-actionsheet'; +import ActionSheet from 'react-native-action-sheet'; import * as moment from 'moment'; import { @@ -125,9 +125,7 @@ export default class MessageActions extends React.Component { this.DELETE_INDEX = this.options.length - 1; } setTimeout(() => { - if (this.actionSheet && this.actionSheet.show) { - this.actionSheet.show(); - } + this.showActionSheet(); Vibration.vibrate(50); }); } @@ -141,6 +139,17 @@ export default class MessageActions extends React.Component { 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) => { try { return await RocketChat.getPermalink(message); @@ -326,15 +335,7 @@ export default class MessageActions extends React.Component { render() { return ( - 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} - /> + null ); } } diff --git a/app/containers/MessageBox/FilesActions.js b/app/containers/MessageBox/FilesActions.js index 8973595f..1850bacf 100644 --- a/app/containers/MessageBox/FilesActions.js +++ b/app/containers/MessageBox/FilesActions.js @@ -1,6 +1,6 @@ -import React, { PureComponent } from 'react'; +import { PureComponent } from 'react'; import PropTypes from 'prop-types'; -import ActionSheet from 'react-native-actionsheet'; +import ActionSheet from 'react-native-action-sheet'; import I18n from '../../i18n'; @@ -27,9 +27,16 @@ export default class FilesActions extends PureComponent { this.LIBRARY_INDEX = 2; setTimeout(() => { - if (this.actionSheet && this.actionSheet.show) { - this.actionSheet.show(); - } + this.showActionSheet(); + }); + } + + 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() { return ( - this.actionSheet = o} - options={this.options} - cancelButtonIndex={this.CANCEL_INDEX} - onPress={this.handleActionPress} - /> + null ); } } diff --git a/app/containers/MessageErrorActions.js b/app/containers/MessageErrorActions.js index e8775365..9fc56355 100644 --- a/app/containers/MessageErrorActions.js +++ b/app/containers/MessageErrorActions.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; 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 RocketChat from '../lib/rocketchat'; @@ -23,21 +23,6 @@ export default class MessageErrorActions extends React.Component { 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(() => { const { actionMessage } = this.props; 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) => { const { errorActionsHide } = this.props; switch (actionIndex) { @@ -68,14 +77,7 @@ export default class MessageErrorActions extends React.Component { render() { return ( - this.actionSheet = o} - title={I18n.t('Message_actions')} - options={this.options} - cancelButtonIndex={this.CANCEL_INDEX} - destructiveButtonIndex={this.DELETE_INDEX} - onPress={this.handleActionPress} - /> + null ); } } diff --git a/app/views/PinnedMessagesView/index.js b/app/views/PinnedMessagesView/index.js index 80ede9b3..2a3dc112 100644 --- a/app/views/PinnedMessagesView/index.js +++ b/app/views/PinnedMessagesView/index.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FlatList, View, Text } from 'react-native'; 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 equal from 'deep-equal'; @@ -71,9 +71,17 @@ export default class PinnedMessagesView extends LoggedView { onLongPress = (message) => { this.setState({ message }); - if (this.actionSheet && this.actionSheet.show) { - this.actionSheet.show(); - } + this.showActionSheet(); + } + + showActionSheet = () => { + ActionSheet.showActionSheetWithOptions({ + options, + cancelButtonIndex: CANCEL_INDEX, + title: I18n.t('Actions') + }, (actionIndex) => { + this.handleActionPress(actionIndex); + }); } handleActionPress = (actionIndex) => { @@ -169,13 +177,6 @@ export default class PinnedMessagesView extends LoggedView { onEndReached={this.load} ListFooterComponent={loading ? : null} /> - this.actionSheet = o} - title={I18n.t('Actions')} - options={options} - cancelButtonIndex={CANCEL_INDEX} - onPress={this.handleActionPress} - /> ); } diff --git a/app/views/RoomMembersView/index.js b/app/views/RoomMembersView/index.js index 8286480f..cdca9e2b 100644 --- a/app/views/RoomMembersView/index.js +++ b/app/views/RoomMembersView/index.js @@ -1,7 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FlatList, View, Vibration } from 'react-native'; -import ActionSheet from 'react-native-actionsheet'; +import { + FlatList, View, Vibration +} from 'react-native'; +import ActionSheet from 'react-native-action-sheet'; import { connect } from 'react-redux'; import { Navigation } from 'react-native-navigation'; import SafeAreaView from 'react-native-safe-area-view'; @@ -161,26 +163,30 @@ export default class RoomMembersView extends LoggedView { if (!this.permissions['mute-user']) { return; } - try { - const { room } = this.state; - const { muted } = room; + const { room } = this.state; + const { muted } = room; - const options = [I18n.t('Cancel')]; - const userIsMuted = !!muted.find(m => m.value === user.username); - user.muted = userIsMuted; - if (userIsMuted) { - options.push(I18n.t('Unmute')); - } else { - options.push(I18n.t('Mute')); - } - this.setState({ userLongPressed: user, options }); - Vibration.vibrate(50); - if (this.actionSheet && this.actionSheet.show) { - this.actionSheet.show(); - } - } catch (error) { - console.log('onLongPressUser -> catch -> error', error); + this.actionSheetOptions = [I18n.t('Cancel')]; + const userIsMuted = !!muted.find(m => m.value === user.username); + user.muted = userIsMuted; + if (userIsMuted) { + this.actionSheetOptions.push(I18n.t('Unmute')); + } else { + this.actionSheetOptions.push(I18n.t('Mute')); } + this.setState({ userLongPressed: user }); + Vibration.vibrate(50); + this.showActionSheet(); + } + + showActionSheet = () => { + ActionSheet.showActionSheetWithOptions({ + options: this.actionSheetOptions, + cancelButtonIndex: this.CANCEL_INDEX, + title: I18n.t('Actions') + }, (actionIndex) => { + this.handleActionPress(actionIndex); + }); } fetchMembers = async(status) => { @@ -253,7 +259,7 @@ export default class RoomMembersView extends LoggedView { render() { const { - filtering, members, membersFiltered, options + filtering, members, membersFiltered } = this.state; return ( @@ -266,13 +272,6 @@ export default class RoomMembersView extends LoggedView { ListHeaderComponent={this.renderSearchBar} {...scrollPersistTaps} /> - this.actionSheet = o} - title={I18n.t('Actions')} - options={options} - cancelButtonIndex={this.CANCEL_INDEX} - onPress={this.handleActionPress} - /> ); } diff --git a/app/views/StarredMessagesView/index.js b/app/views/StarredMessagesView/index.js index 45be568d..fe2ba86c 100644 --- a/app/views/StarredMessagesView/index.js +++ b/app/views/StarredMessagesView/index.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FlatList, View, Text } from 'react-native'; 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 equal from 'deep-equal'; @@ -71,9 +71,17 @@ export default class StarredMessagesView extends LoggedView { onLongPress = (message) => { this.setState({ message }); - if (this.actionSheet && this.actionSheet.show) { - this.actionSheet.show(); - } + this.showActionSheet(); + } + + showActionSheet = () => { + ActionSheet.showActionSheetWithOptions({ + options, + cancelButtonIndex: CANCEL_INDEX, + title: I18n.t('Actions') + }, (actionIndex) => { + this.handleActionPress(actionIndex); + }); } handleActionPress = (actionIndex) => { @@ -175,13 +183,6 @@ export default class StarredMessagesView extends LoggedView { onEndReached={this.load} ListFooterComponent={loading ? : null} /> - this.actionSheet = o} - title={I18n.t('Actions')} - options={options} - cancelButtonIndex={CANCEL_INDEX} - onPress={this.handleActionPress} - /> ); } diff --git a/package-lock.json b/package-lock.json index ee0ff10c..0824cfb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6710,7 +6710,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "optional": true, "requires": { "tweetnacl": "^0.14.3" } @@ -9403,7 +9402,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "optional": true, "requires": { "jsbn": "~0.1.0" } @@ -15346,8 +15344,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsc-android": { "version": "236355.1.1", @@ -20543,12 +20540,11 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sane": { "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==", "requires": { "anymatch": "^2.0.0", @@ -21846,9 +21842,9 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", + "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -21857,6 +21853,7 @@ "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" } }, @@ -22904,8 +22901,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-check": { "version": "0.3.2", diff --git a/package.json b/package.json index b15361db..bbc7a0ad 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "react": "16.6.3", "react-emojione": "^5.0.1", "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-device-info": "^0.25.1", "react-native-dialog": "^5.5.0",