From 2e245e4d7c1dc73d265c53f6495a1cf5559e21eb Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 17 Jul 2018 16:10:27 -0300 Subject: [PATCH] Image upload improvements (#368) @RocketChat/ReactNative - [x] Crop image - [x] Type image description (like web) - [x] Show upload progress - [x] "Try again" in case of error - [x] Cancel upload while in progress - [x] [Android] Zoom on photos ![image](https://user-images.githubusercontent.com/804994/42526934-a12da304-844d-11e8-8668-f3d69369726a.png) ![image](https://user-images.githubusercontent.com/804994/42527829-297945fe-8450-11e8-9f0e-9e668dd33043.png) --- android/app/build.gradle | 7 +- .../assets/fonts/MaterialCommunityIcons.ttf | Bin 292556 -> 322456 bytes .../app/src/main/assets/fonts/Octicons.ttf | Bin 27428 -> 27520 bytes .../rocket/reactnative/MainApplication.java | 4 +- android/build.gradle | 1 + android/settings.gradle | 12 +- app/containers/Button/index.js | 19 +- app/containers/MessageBox/FilesActions.js | 59 ++ app/containers/MessageBox/UploadModal.js | 133 +++++ app/containers/MessageBox/index.js | 137 +++-- app/containers/message/Image.js | 1 + app/containers/message/PhotoModal.js | 71 ++- app/i18n/locales/en.js | 7 + app/lib/createStore.js | 2 +- app/lib/methods/sendFileMessage.js | 89 +++ app/lib/realm.js | 19 +- app/lib/rocketchat.js | 88 +-- app/presentation/RoomItem.js | 2 +- app/views/ProfileView/index.js | 26 +- app/views/RoomView/UploadProgress.js | 158 ++++++ app/views/RoomView/index.js | 2 + ios/RocketChatRN.xcodeproj/project.pbxproj | 178 +++--- ios/RocketChatRN/Info.plist | 1 + package-lock.json | 515 +++++++++++------- package.json | 24 +- 25 files changed, 1090 insertions(+), 465 deletions(-) create mode 100644 app/containers/MessageBox/FilesActions.js create mode 100644 app/containers/MessageBox/UploadModal.js create mode 100644 app/lib/methods/sendFileMessage.js create mode 100644 app/views/RoomView/UploadProgress.js diff --git a/android/app/build.gradle b/android/app/build.gradle index d224d8bbe..b5061cd0c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -103,6 +103,7 @@ android { abiFilters "armeabi-v7a", "x86" } missingDimensionStrategy "RNN.reactNativeVersion", "reactNative55" + vectorDrawables.useSupportLibrary = true } compileOptions { @@ -178,17 +179,17 @@ repositories { } dependencies { + implementation project(':react-native-image-crop-picker') implementation project(':react-native-i18n') implementation project(':react-native-fabric') implementation project(':react-native-audio') implementation project(":reactnativekeyboardinput") implementation project(':react-native-video') implementation project(':react-native-svg') - implementation project(':react-native-image-picker') implementation project(':react-native-vector-icons') - implementation project(':react-native-fetch-blob') + implementation project(':rn-fetch-blob') implementation project(':react-native-zeroconf') - implementation project(':react-native-toast') + implementation project(':@remobile/react-native-toast') implementation project(':react-native-fast-image') implementation project(':realm') implementation project(':react-native-navigation') diff --git a/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf b/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf index 69404e3d9758bf3d6a7e4ce27e5362089366542f..82524a0c1223bfc2bf060a9b16390c3cc21577c1 100644 GIT binary patch delta 42753 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 C4>a=t delta 14905 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 W$n{;z4?=3$(9xe;uD6V@@cs|bD}N{e diff --git a/android/app/src/main/assets/fonts/Octicons.ttf b/android/app/src/main/assets/fonts/Octicons.ttf index 5b1f7d6ea2c870df4f29f4b40a300334844d2214..09f5a96c05af2c82a0002f0d8b0fca6ba3f08fc7 100644 GIT binary patch delta 5784 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 U^~|c&zj!rcwU_^oeWT~U07H+3{{R30 delta 5557 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 createAdditionalReactPackages() { return Arrays.asList( new MainReactPackage(), + new PickerPackage(), new SvgPackage(), - new ImagePickerPackage(), new VectorIconsPackage(), new RNFetchBlobPackage(), new ZeroconfReactPackage(), diff --git a/android/build.gradle b/android/build.gradle index d6cd4cf1b..7b1e283f5 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -25,6 +25,7 @@ allprojects { maven { url 'https://maven.google.com' } + maven { url "https://jitpack.io" } maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url "$rootDir/../node_modules/react-native/android" diff --git a/android/settings.gradle b/android/settings.gradle index 0cc5136b6..7a7576153 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,10 @@ rootProject.name = 'RocketChatRN' +include ':@remobile/react-native-toast' +project(':@remobile/react-native-toast').projectDir = new File(rootProject.projectDir, '../node_modules/@remobile/react-native-toast/android') +include ':rn-fetch-blob' +project(':rn-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/rn-fetch-blob/android') +include ':react-native-image-crop-picker' +project(':react-native-image-crop-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-crop-picker/android') include ':react-native-i18n' project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android') include ':react-native-fast-image' @@ -13,18 +19,12 @@ include ':react-native-video' project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android') include ':react-native-svg' project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android') -include ':react-native-image-picker' -project(':react-native-image-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-picker/android') include ':react-native-vector-icons' project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') -include ':react-native-fetch-blob' -project(':react-native-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fetch-blob/android') include ':react-native-zeroconf' project(':react-native-zeroconf').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-zeroconf/android') include ':realm' project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android') -include ':react-native-toast' -project(':react-native-toast').projectDir = new File(settingsDir, '../node_modules/@remobile/react-native-toast/android') include ':react-native-navigation' project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/android/app/') include ':reactnativenotifications' diff --git a/app/containers/Button/index.js b/app/containers/Button/index.js index f72880b2c..32eb7de94 100644 --- a/app/containers/Button/index.js +++ b/app/containers/Button/index.js @@ -16,8 +16,7 @@ const colors = { const styles = StyleSheet.create({ container: { paddingHorizontal: 15, - paddingVertical: 10, - borderRadius: 2 + paddingVertical: 10 }, text: { textAlign: 'center', @@ -40,6 +39,9 @@ const styles = StyleSheet.create({ }, disabled: { opacity: 0.5 + }, + border: { + borderRadius: 2 } }); @@ -48,7 +50,9 @@ export default class Button extends React.PureComponent { title: PropTypes.string, type: PropTypes.string, onPress: PropTypes.func, - disabled: PropTypes.bool + disabled: PropTypes.bool, + margin: PropTypes.any, + backgroundColor: PropTypes.string } static defaultProps = { @@ -60,21 +64,22 @@ export default class Button extends React.PureComponent { render() { const { - title, type, onPress, disabled, ...otherProps + title, type, onPress, disabled, margin, backgroundColor, ...otherProps } = this.props; return ( diff --git a/app/containers/MessageBox/FilesActions.js b/app/containers/MessageBox/FilesActions.js new file mode 100644 index 000000000..e7def299d --- /dev/null +++ b/app/containers/MessageBox/FilesActions.js @@ -0,0 +1,59 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ActionSheet from 'react-native-actionsheet'; + +import I18n from '../../i18n'; + +export default class FilesActions extends Component { + static propTypes = { + hideActions: PropTypes.func.isRequired, + takePhoto: PropTypes.func.isRequired, + chooseFromLibrary: PropTypes.func.isRequired + } + + constructor(props) { + super(props); + + // Cancel + this.options = [I18n.t('Cancel')]; + this.CANCEL_INDEX = 0; + + // Photo + this.options.push(I18n.t('Take_a_photo')); + this.PHOTO_INDEX = 1; + + // Library + this.options.push(I18n.t('Choose_from_library')); + this.LIBRARY_INDEX = 2; + + setTimeout(() => { + this.ActionSheet.show(); + }); + } + + handleActionPress = (actionIndex) => { + const { takePhoto, chooseFromLibrary } = this.props; + switch (actionIndex) { + case this.PHOTO_INDEX: + takePhoto(); + break; + case this.LIBRARY_INDEX: + chooseFromLibrary(); + break; + default: + break; + } + this.props.hideActions(); + } + + render() { + return ( + this.ActionSheet = o} + options={this.options} + cancelButtonIndex={this.CANCEL_INDEX} + onPress={this.handleActionPress} + /> + ); + } +} diff --git a/app/containers/MessageBox/UploadModal.js b/app/containers/MessageBox/UploadModal.js new file mode 100644 index 000000000..53f91ed45 --- /dev/null +++ b/app/containers/MessageBox/UploadModal.js @@ -0,0 +1,133 @@ +import React, { Component } from 'react'; +import { View, Text, StyleSheet, Image, ScrollView, Platform } from 'react-native'; +import PropTypes from 'prop-types'; +import Modal from 'react-native-modal'; +import { responsive } from 'react-native-responsive-ui'; +import equal from 'deep-equal'; + +import TextInput from '../TextInput'; +import Button from '../Button'; +import I18n from '../../i18n'; + +const cancelButtonColor = '#f7f8fa'; + +const styles = StyleSheet.create({ + titleContainer: { + flexDirection: 'row', + paddingHorizontal: 16, + paddingTop: 16 + }, + title: { + fontWeight: 'bold' + }, + container: { + height: Platform.OS === 'ios' ? 404 : 430, + backgroundColor: '#ffffff', + flexDirection: 'column' + }, + scrollView: { + flex: 1, + padding: 16 + }, + image: { + height: 150, + flex: 1, + marginBottom: 16, + resizeMode: 'contain' + }, + buttonContainer: { + flexDirection: 'row', + justifyContent: 'space-between', + padding: 16, + backgroundColor: '#f7f8fa' + }, + buttonMargin: { + margin: 0 + } +}); + +@responsive +export default class UploadModal extends Component { + static propTypes = { + isVisible: PropTypes.bool, + file: PropTypes.object, + close: PropTypes.func, + submit: PropTypes.func, + window: PropTypes.object + } + + state = { + name: '', + description: '', + file: {} + }; + + static getDerivedStateFromProps(props, state) { + if (!equal(props.file, state.file) && props.file && props.file.path) { + return { + file: props.file, + name: props.file.filename || 'Filename', + description: '' + }; + } + return null; + } + + _submit = () => { + const { file, submit } = this.props; + const { name, description } = this.state; + submit({ ...file, name, description }); + } + + render() { + const { window: { width }, isVisible, close } = this.props; + const { name, description, file } = this.state; + return ( + this.props.close()} + onBackButtonPress={() => this.props.close()} + animationIn='fadeIn' + animationOut='fadeOut' + useNativeDriver + hideModalContentWhileAnimating + > + + + Upload file? + + + + + this.setState({ name: value })} + /> + this.setState({ description: value })} + /> + + +