diff --git a/__tests__/__snapshots__/RoomItem.js.snap b/__tests__/__snapshots__/RoomItem.js.snap index 7322a46b6266f4d2dbca041b497d70accaf50e24..9d388e323fd013899645d76f372aef3fc94c134b 100644 --- a/__tests__/__snapshots__/RoomItem.js.snap +++ b/__tests__/__snapshots__/RoomItem.js.snap @@ -546,7 +546,49 @@ exports[`render unread +999 1`] = ` > NA </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/name", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -741,7 +783,49 @@ exports[`render unread 1`] = ` > NA </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/name", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -936,7 +1020,49 @@ exports[`renders correctly 1`] = ` > NA </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/name", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap index a735dc7f54adc5b3dccb4d470328d8179fcb66b6..9310dc94c494ea6e85eb8921e58a64cc636ce966 100644 --- a/__tests__/__snapshots__/Storyshots.test.js.snap +++ b/__tests__/__snapshots__/Storyshots.test.js.snap @@ -37,7 +37,49 @@ exports[`Storyshots Avatar avatar 1`] = ` > TE </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 25, + "width": 25, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/test", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> </View> <View style={ @@ -73,7 +115,49 @@ exports[`Storyshots Avatar avatar 1`] = ` > AA </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 40, + "width": 40, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/aa", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> </View> <View style={ @@ -109,7 +193,49 @@ exports[`Storyshots Avatar avatar 1`] = ` > BB </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 30, + "width": 30, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/bb", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> </View> <View style={ @@ -145,7 +271,49 @@ exports[`Storyshots Avatar avatar 1`] = ` > TE </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 25, + "width": 25, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/test", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> </View> </View> </RCTScrollView> @@ -223,7 +391,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > RC </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/rocket.cat", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -390,7 +600,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > RC </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/rocket.cat", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -561,7 +813,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > RC </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/rocket.cat", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -751,7 +1045,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > LC </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -945,7 +1281,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > LC </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -1135,7 +1513,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > LC </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -1325,7 +1745,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > LC </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -1515,7 +1977,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > LC </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -1705,7 +2209,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > W </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/W", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -1872,7 +2418,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > WW </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/WW", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ @@ -2039,7 +2627,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` > </Text> - + <View + style={ + Array [ + Array [ + Object { + "position": "absolute", + }, + Object { + "borderRadius": 2, + "height": 46, + "width": 46, + }, + ], + Object { + "overflow": "hidden", + }, + ] + } + > + <FastImageView + onFastImageError={undefined} + onFastImageLoad={undefined} + onFastImageLoadEnd={undefined} + onFastImageLoadStart={undefined} + onFastImageProgress={undefined} + resizeMode="cover" + source={ + Object { + "priority": "high", + "uri": "/avatar/", + } + } + style={ + Object { + "bottom": 0, + "left": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + </View> <View style={ Array [ diff --git a/android/app/build.gradle b/android/app/build.gradle index 793040f619614114d1044dd9f68c25bda01272fe..cbef9d7096cce56a51336ee4db331a18f4b0f120 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -90,8 +90,8 @@ def enableSeparateBuildPerCPUArchitecture = false def enableProguardInReleaseBuilds = false android { - compileSdkVersion 25 - buildToolsVersion "25.0.1" + compileSdkVersion 27 + buildToolsVersion "27.0.1" defaultConfig { applicationId "chat.rocket.reactnative" @@ -184,9 +184,11 @@ dependencies { compile project(':react-native-fetch-blob') compile project(':react-native-zeroconf') compile project(':react-native-toast') + compile project(':react-native-fast-image') compile project(':realm') compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:23.0.1" + compile "com.android.support:support-v4:27.1.0" compile 'com.android.support:customtabs:23.0.1' compile "com.facebook.react:react-native:+" // From node_modules compile 'com.facebook.fresco:fresco:1.7.1' diff --git a/android/app/src/main/java/com/rocketchatrn/CustomTabsAndroid.java b/android/app/src/main/java/chat/rocketchat/reactnative/CustomTabsAndroid.java similarity index 100% rename from android/app/src/main/java/com/rocketchatrn/CustomTabsAndroid.java rename to android/app/src/main/java/chat/rocketchat/reactnative/CustomTabsAndroid.java diff --git a/android/app/src/main/java/com/rocketchatrn/CustomTabsHelper.java b/android/app/src/main/java/chat/rocketchat/reactnative/CustomTabsHelper.java similarity index 100% rename from android/app/src/main/java/com/rocketchatrn/CustomTabsHelper.java rename to android/app/src/main/java/chat/rocketchat/reactnative/CustomTabsHelper.java diff --git a/android/app/src/main/java/com/rocketchatrn/MainActivity.java b/android/app/src/main/java/chat/rocketchat/reactnative/MainActivity.java similarity index 100% rename from android/app/src/main/java/com/rocketchatrn/MainActivity.java rename to android/app/src/main/java/chat/rocketchat/reactnative/MainActivity.java diff --git a/android/app/src/main/java/com/rocketchatrn/MainApplication.java b/android/app/src/main/java/chat/rocketchat/reactnative/MainApplication.java similarity index 94% rename from android/app/src/main/java/com/rocketchatrn/MainApplication.java rename to android/app/src/main/java/chat/rocketchat/reactnative/MainApplication.java index 689cee99fbb1a0b62cee5f00c691bb5f0f4c2ece..7883ed1b26d77b99e0eae7a74c7d177e9d7d4459 100644 --- a/android/app/src/main/java/com/rocketchatrn/MainApplication.java +++ b/android/app/src/main/java/chat/rocketchat/reactnative/MainApplication.java @@ -19,6 +19,7 @@ import com.remobile.toast.RCTToastPackage; import com.wix.reactnativekeyboardinput.KeyboardInputPackage; import com.rnim.rn.audio.ReactNativeAudioPackage; import com.smixx.fabric.FabricPackage; +import com.dylanvann.fastimage.FastImageViewPackage; import java.util.Arrays; import java.util.List; @@ -49,7 +50,8 @@ public class MainApplication extends Application implements ReactApplication { new ReactNativeAudioPackage(), new KeyboardInputPackage(MainApplication.this), new RocketChatNativePackage(), - new FabricPackage() + new FabricPackage(), + new FastImageViewPackage() ); } }; diff --git a/android/app/src/main/java/com/rocketchatrn/RocketChatNativePackage.java b/android/app/src/main/java/chat/rocketchat/reactnative/RocketChatNativePackage.java similarity index 100% rename from android/app/src/main/java/com/rocketchatrn/RocketChatNativePackage.java rename to android/app/src/main/java/chat/rocketchat/reactnative/RocketChatNativePackage.java diff --git a/android/build.gradle b/android/build.gradle index eed9972b5c13ea781f87b5aa6c065900984713ad..d29444e96c12aac476d82fd808ee59b3e438fdd3 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -16,6 +16,9 @@ allprojects { repositories { mavenLocal() jcenter() + maven { + url 'https://maven.google.com' + } 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 bba1bd27f0c6f50b072a07d61cd11a88d929af65..1259f2ba93b1d5f8044cc6f7cc36e5c33f1f005c 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,6 @@ rootProject.name = 'RocketChatRN' +include ':react-native-fast-image' +project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android') include ':react-native-fabric' project(':react-native-fabric').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fabric/android') include ':react-native-audio' diff --git a/app/containers/Avatar.js b/app/containers/Avatar.js index 6842218e2496983da1aa24f1286b300e73e1181e..7d1b400537651743231148e8e4ec2f0f1c718409 100644 --- a/app/containers/Avatar.js +++ b/app/containers/Avatar.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { StyleSheet, Text, View, ViewPropTypes } from 'react-native'; -import { CachedImage } from 'react-native-img-cache'; +import FastImage from 'react-native-fast-image'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import avatarInitialsAndColor from '../utils/avatarInitialsAndColor'; @@ -34,6 +34,7 @@ export default class Avatar extends React.PureComponent { type: PropTypes.string, children: PropTypes.object }; + state = { showInitials: true }; render() { const { text = '', size = 25, baseUrl, borderRadius = 2, style, avatar, type = 'd' @@ -59,15 +60,25 @@ export default class Avatar extends React.PureComponent { if (type === 'd') { const uri = avatar || `${ baseUrl }/avatar/${ text }`; - const image = (avatar || baseUrl) && ( - <CachedImage + const image = uri && ( + <FastImage style={[styles.avatar, avatarStyle]} - source={{ uri }} + source={{ + uri, + priority: FastImage.priority.high + }} /> ); return ( <View style={[styles.iconContainer, iconContainerStyle, style]}> - <Text style={[styles.avatarInitials, avatarInitialsStyle]} allowFontScaling={false}>{initials}</Text> + {this.state.showInitials && + <Text + style={[styles.avatarInitials, avatarInitialsStyle]} + allowFontScaling={false} + > + {initials} + </Text> + } {image} {this.props.children} </View>); diff --git a/app/containers/EmojiPicker/CustomEmoji.js b/app/containers/EmojiPicker/CustomEmoji.js index 8215f0ea6a5c96ace690aa1fe3a293e87593e5c3..2f10cb7714075bacc1b0138737da312ccad5b3b9 100644 --- a/app/containers/EmojiPicker/CustomEmoji.js +++ b/app/containers/EmojiPicker/CustomEmoji.js @@ -1,7 +1,7 @@ import React from 'react'; import { ViewPropTypes } from 'react-native'; import PropTypes from 'prop-types'; -import { CachedImage } from 'react-native-img-cache'; +import FastImage from 'react-native-fast-image'; import { connect } from 'react-redux'; @connect(state => ({ @@ -19,7 +19,7 @@ export default class CustomEmoji extends React.Component { render() { const { baseUrl, emoji, style } = this.props; return ( - <CachedImage + <FastImage style={style} source={{ uri: `${ baseUrl }/emoji-custom/${ encodeURIComponent(emoji.content || emoji.name) }.${ emoji.extension }` }} /> diff --git a/app/containers/message/Image.js b/app/containers/message/Image.js index 2bf78435c84cb4ea463581e19498f87812fb9543..7724edbef6993376d1047dcc69258cf245f89a74 100644 --- a/app/containers/message/Image.js +++ b/app/containers/message/Image.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { CachedImage } from 'react-native-img-cache'; +import FastImage from 'react-native-fast-image'; import { TouchableOpacity, StyleSheet } from 'react-native'; import { connect } from 'react-redux'; import PhotoModal from './PhotoModal'; @@ -13,8 +13,8 @@ const styles = StyleSheet.create({ }, image: { width: 320, - height: 200, - resizeMode: 'cover' + height: 200 + // resizeMode: 'cover' }, labelContainer: { alignItems: 'flex-start' @@ -56,7 +56,7 @@ export default class extends React.PureComponent { onPress={() => this._onPressButton()} style={styles.button} > - <CachedImage + <FastImage style={styles.image} source={{ uri: encodeURI(img) }} /> diff --git a/app/containers/message/Markdown.js b/app/containers/message/Markdown.js index 3c88b09d5948f2e433d9867bc23f19c984ea6dbe..1dc11b8ff4f0dca46a12884107edc512b710982b 100644 --- a/app/containers/message/Markdown.js +++ b/app/containers/message/Markdown.js @@ -94,6 +94,13 @@ const defaultRules = { const codeStyle = StyleSheet.flatten(styles.codeStyle); +// Support <http://link|Text> +const formatText = text => + text.replace( + new RegExp('(?:<|<)((?:https|http):\\/\\/[^\\|]+)\\|(.+?)(?=>|>)(?:>|>)', 'gm'), + (match, url, title) => `[${ title }](${ url })` + ); + @connect(state => ({ customEmojis: state.customEmojis })) @@ -108,7 +115,8 @@ export default class Markdown extends React.Component { if (!msg) { return null; } - const m = emojify(msg, { output: 'unicode' }); + let m = formatText(msg); + m = emojify(m, { output: 'unicode' }); const s = StyleSheet.flatten(style); return ( diff --git a/app/containers/message/PhotoModal.js b/app/containers/message/PhotoModal.js index 7d378794eae3d7c1832c8a60cabe7aeb9dc8a9a0..0bb21888e2f0ad388c4c6fa17ae2226d96fd8d88 100644 --- a/app/containers/message/PhotoModal.js +++ b/app/containers/message/PhotoModal.js @@ -1,6 +1,6 @@ import React from 'react'; import { ScrollView, View, Text, TouchableWithoutFeedback } from 'react-native'; -import { CachedImage } from 'react-native-img-cache'; +import FastImage from 'react-native-fast-image'; import PropTypes from 'prop-types'; import Modal from 'react-native-modal'; @@ -50,7 +50,7 @@ export default class PhotoModal extends React.PureComponent { <View style={styles.imageWrapper}> <ScrollView contentContainerStyle={styles.imageWrapper} maximumZoomScale={5}> <TouchableWithoutFeedback onPress={onClose}> - <CachedImage + <FastImage style={styles.image} source={{ uri: encodeURI(image) }} mutable diff --git a/app/containers/message/Reply.js b/app/containers/message/Reply.js index f6df68380dea55e04e98460c50df19aa43e1d184..592482bb699813e135bad167bcc7c33e7151f72c 100644 --- a/app/containers/message/Reply.js +++ b/app/containers/message/Reply.js @@ -65,13 +65,6 @@ const onPress = (attachment) => { openLink(attachment.title_link || attachment.author_link); }; -// Support <http://link|Text> -const formatText = text => - text.replace( - new RegExp('(?:<|<)((?:https|http):\\/\\/[^\\|]+)\\|(.+?)(?=>|>)(?:>|>)', 'gm'), - (match, url, title) => `[${ title }](${ url })` - ); - const Reply = ({ attachment, timeFormat }) => { if (!attachment) { return null; @@ -113,7 +106,7 @@ const Reply = ({ attachment, timeFormat }) => { }; const renderText = () => ( - attachment.text ? <Markdown msg={formatText(attachment.text)} /> : null + attachment.text ? <Markdown msg={attachment.text} /> : null ); const renderFields = () => { diff --git a/app/views/Photo.js b/app/views/Photo.js deleted file mode 100644 index a13dd4adb391fc98ae1d44a4329d310aba28d403..0000000000000000000000000000000000000000 --- a/app/views/Photo.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import { ScrollView, View } from 'react-native'; -import { CachedImage } from 'react-native-img-cache'; -import PropTypes from 'prop-types'; - -const styles = { - imageWrapper: { - flex: 1, - alignItems: 'stretch', - backgroundColor: '#000' - }, - image: { - flex: 1 - } -}; - -export default class Photo extends React.PureComponent { - static propTypes = { - navigation: PropTypes.object.isRequired - } - render() { - const { image } = this.props.navigation.state.params; - return ( - <View style={styles.imageWrapper}> - <ScrollView contentContainerStyle={styles.imageWrapper} maximumZoomScale={1.5}> - <CachedImage - style={{ ...styles.image }} - source={{ uri: encodeURI(image) }} - mutable - resizeMode='contain' - /> - </ScrollView> - </View> - ); - } -} diff --git a/app/views/RoomView/ListView.js b/app/views/RoomView/ListView.js index 0c0d587b87d0a18c119b4766d4d3e50452efed7a..3dd10fbea70bcbdc5ac97fad9ee3245f090ffb08 100644 --- a/app/views/RoomView/ListView.js +++ b/app/views/RoomView/ListView.js @@ -9,7 +9,6 @@ import PropTypes from 'prop-types'; import DateSeparator from './DateSeparator'; import UnreadSeparator from './UnreadSeparator'; import styles from './styles'; -import throttle from '../../utils/throttle'; import Typing from '../../containers/Typing'; import database from '../../lib/realm'; import scrollPersistTaps from '../../utils/scrollPersistTaps'; @@ -52,17 +51,16 @@ export class List extends React.Component { return this.props.end !== nextProps.end; } componentWillUnmount() { - this.date.removeListener(this.updateState); - this.date.removeAllListeners(); + this.data.removeAllListeners(); this.updateState.stop(); } - updateState = throttle(() => { + updateState = () => { // this.setState({ this.dataSource = this.dataSource.cloneWithRows(this.data); LayoutAnimation.easeInEaseOut(); this.forceUpdate(); // }); - }, 2500); + }; render() { return (<ListView @@ -70,13 +68,14 @@ export class List extends React.Component { style={styles.list} data={this.data} keyExtractor={item => item._id} - onEndReachedThreshold={0.5} + onEndReachedThreshold={100} renderFooter={this.props.renderFooter} renderHeader={() => <Typing />} onEndReached={() => this.props.onEndReached(this.data)} dataSource={this.dataSource} renderRow={(item, previousItem) => this.props.renderRow(item, previousItem)} - initialListSize={10} + initialListSize={20} + pageSize={20} {...scrollPersistTaps} />); } diff --git a/app/views/RoomsListView/Header/index.js b/app/views/RoomsListView/Header/index.js index 3850acb7288608a9a02b34408b622cf8a9b0d527..e07b3dc372d0d017586ba1afa1b831a258b3dc5a 100644 --- a/app/views/RoomsListView/Header/index.js +++ b/app/views/RoomsListView/Header/index.js @@ -4,7 +4,7 @@ import Icon from 'react-native-vector-icons/Ionicons'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import Modal from 'react-native-modal'; -import { CachedImage } from 'react-native-img-cache'; +import FastImage from 'react-native-fast-image'; import { HeaderBackButton } from 'react-navigation'; import Avatar from '../../../containers/Avatar'; @@ -118,7 +118,7 @@ export default class RoomsListHeaderView extends React.PureComponent { style={styles.headerButton} onPress={() => this.props.navigation.navigate({ key: 'DrawerOpen', routeName: 'DrawerOpen' })} > - <CachedImage + <FastImage style={styles.serverImage} source={{ uri: encodeURI(`${ this.props.baseUrl }/assets/favicon_32.png`) }} /> diff --git a/ios/RocketChatRN.xcodeproj/project.pbxproj b/ios/RocketChatRN.xcodeproj/project.pbxproj index 0bf4d04e13a0ac58c6e7eb0a91a2c6b6b89d7351..800e7e1a18b010252f5db2e04f458bf4c215ec71 100644 --- a/ios/RocketChatRN.xcodeproj/project.pbxproj +++ b/ios/RocketChatRN.xcodeproj/project.pbxproj @@ -5,7 +5,6 @@ }; objectVersion = 46; objects = { - /* Begin PBXBuildFile section */ 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; @@ -71,6 +70,7 @@ CBD0E0A35B174C4DBFED3B31 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E528DE3A405E43B4A37ABA68 /* Zocial.ttf */; }; D6408D9E4A864FF6BA986857 /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8A2DD67ADD954AD9873F45FC /* SimpleLineIcons.ttf */; }; EF736EF520A64AE8820E684A /* libRealmReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DF26CC845883492D8AC8869B /* libRealmReact.a */; }; + BAB7DC22804246F3923A1833 /* libFastImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD2E2837F110483CA29EE0D4 /* libFastImage.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -535,6 +535,8 @@ DF26CC845883492D8AC8869B /* libRealmReact.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRealmReact.a; sourceTree = "<group>"; }; E528DE3A405E43B4A37ABA68 /* Zocial.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Zocial.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"; sourceTree = "<group>"; }; F88C6541BD764BEEABB87272 /* Octicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Octicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = "<group>"; }; + 1845C223DA364898A8400573 /* FastImage.xcodeproj */ = {isa = PBXFileReference; name = "FastImage.xcodeproj"; path = "../node_modules/react-native-fast-image/ios/FastImage.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; }; + FD2E2837F110483CA29EE0D4 /* libFastImage.a */ = {isa = PBXFileReference; name = "libFastImage.a"; path = "libFastImage.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -580,6 +582,7 @@ 0F026E58B8A6427D9A204D89 /* libSplashScreen.a in Frameworks */, 2C800DF680F8451599E80AF1 /* libSafariViewManager.a in Frameworks */, 74815BBCB91147C08C8F7B3D /* libRNAudio.a in Frameworks */, + BAB7DC22804246F3923A1833 /* libFastImage.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -839,6 +842,7 @@ 30FCE1B6376C423E94C9FBB0 /* SplashScreen.xcodeproj */, 4019A5E1911B4C61944FBCEC /* SafariViewManager.xcodeproj */, C21010507E5B4B37BA0E4C9D /* RNAudio.xcodeproj */, + 1845C223DA364898A8400573 /* FastImage.xcodeproj */, ); name = Libraries; sourceTree = "<group>"; @@ -1768,6 +1772,7 @@ "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", "$(SRCROOT)/../node_modules/react-native-safari-view", "$(SRCROOT)/../node_modules/react-native-audio/ios", + "$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**", ); INFOPLIST_FILE = RocketChatRNTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -1781,6 +1786,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1811,6 +1817,7 @@ "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", "$(SRCROOT)/../node_modules/react-native-safari-view", "$(SRCROOT)/../node_modules/react-native-audio/ios", + "$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**", ); INFOPLIST_FILE = RocketChatRNTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -1824,6 +1831,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1864,6 +1872,7 @@ "$(SRCROOT)/../node_modules/react-native-safari-view", "$(SRCROOT)/../node_modules/react-native-audio/ios", "$(SRCROOT)/../../../react-native/React/**", + "$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**", ); INFOPLIST_FILE = RocketChatRN/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1909,6 +1918,7 @@ "$(SRCROOT)/../node_modules/react-native-safari-view", "$(SRCROOT)/../node_modules/react-native-audio/ios", "$(SRCROOT)/../../../react-native/React/**", + "$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**", ); INFOPLIST_FILE = RocketChatRN/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1952,6 +1962,7 @@ "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", "$(SRCROOT)/../node_modules/react-native-safari-view", "$(SRCROOT)/../node_modules/react-native-audio/ios", + "$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**", ); INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1964,6 +1975,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -2004,6 +2016,7 @@ "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", "$(SRCROOT)/../node_modules/react-native-safari-view", "$(SRCROOT)/../node_modules/react-native-audio/ios", + "$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**", ); INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2016,6 +2029,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -2052,6 +2066,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2084,6 +2099,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/package-lock.json b/package-lock.json index af04587d6a0470e7b32e931f9846282d00b70da4..3cb4700d27387a89a15c876e3174025b32ec5900 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15869,6 +15869,14 @@ "resolved": "https://registry.npmjs.org/react-native-fabric/-/react-native-fabric-0.5.1.tgz", "integrity": "sha512-NKYXiH8w/DjNXoozko1twjAd5F8shL/UiTVx/PQ8QNaasWpbxlXgeJ5exhDSIcDXao0AUdcPWJunYdSCjq208g==" }, + "react-native-fast-image": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-4.0.8.tgz", + "integrity": "sha512-/FC2M3ZDqmQRERQpYlyMhyr7eX5euvi9bXkowNY5A7t/bRB09LSsfQbk8FtI2stgSgA6d0YUXHt3ll7m/ZB0SQ==", + "requires": { + "prop-types": "15.6.1" + } + }, "react-native-fetch-blob": { "version": "0.10.8", "resolved": "https://registry.npmjs.org/react-native-fetch-blob/-/react-native-fetch-blob-0.10.8.tgz", @@ -15898,14 +15906,6 @@ "resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-0.26.7.tgz", "integrity": "sha1-rS7pV/f2zAE5aJPqA9hMsq2y43Y=" }, - "react-native-img-cache": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/react-native-img-cache/-/react-native-img-cache-1.5.3.tgz", - "integrity": "sha1-zP+6hmAwd9C+T53Aiv9Z4/VRCQs=", - "requires": { - "crypto-js": "3.1.9-1" - } - }, "react-native-iphone-x-helper": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.0.2.tgz", diff --git a/package.json b/package.json index 53125930e7d21269062285e619cc093c67b1213f..949dfa320a9b1dd702d58a386fac7daed2130a6a 100644 --- a/package.json +++ b/package.json @@ -46,9 +46,9 @@ "react-native-cached-image": "^1.4.3", "react-native-easy-markdown": "git+https://github.com/diegolmello/react-native-easy-markdown.git", "react-native-fabric": "^0.5.1", + "react-native-fast-image": "^4.0.8", "react-native-fetch-blob": "^0.10.8", "react-native-image-picker": "^0.26.7", - "react-native-img-cache": "^1.5.2", "react-native-keyboard-aware-scroll-view": "^0.5.0", "react-native-keyboard-input": "git+https://github.com/RocketChat/react-native-keyboard-input.git", "react-native-keyboard-tracking-view": "git+https://github.com/RocketChat/react-native-keyboard-tracking-view.git",