better performance on lower end devices with react-native-fast-image (#275)

* thumbnail aspect ratio sizing tweaks
* show approximate values for formatted bytes
* truncate titles over 80 characters in the file item list component
This commit is contained in:
Akinwale Ariwodola 2018-09-01 22:04:50 +01:00 committed by GitHub
parent e9abbf256e
commit 4b7be60c27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 100 additions and 31 deletions

16
app/package-lock.json generated
View file

@ -3969,8 +3969,17 @@
"version": "github:lbryio/lbryinc#678c5098e2099dd1560b2fefa2795f38ca3ce07b",
"from": "github:lbryio/lbryinc",
"requires": {
"lbry-redux": "github:lbryio/lbry-redux#31f7afa8a37f5741dac01fc1ecdf153f3bed95dc",
"reselect": "^3.0.0"
},
"dependencies": {
"lbry-redux": {
"version": "github:lbryio/lbry-redux#31f7afa8a37f5741dac01fc1ecdf153f3bed95dc",
"from": "github:lbryio/lbry-redux#31f7afa8a37f5741dac01fc1ecdf153f3bed95dc",
"requires": {
"proxy-polyfill": "0.1.6",
"reselect": "^3.0.0"
}
}
}
},
"lcid": {
@ -5188,6 +5197,11 @@
"react-native-drawer-layout": "1.3.2"
}
},
"react-native-fast-image": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-5.0.3.tgz",
"integrity": "sha512-70XlQPt8b7yQSMwUEEIN5jTx7KOx1EBD2XhIRIEHChfNv5Gwn8dh28RSo/Dq9qezf4CWJXO3CAb4lq+Hu9d0vw=="
},
"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",

View file

@ -12,6 +12,7 @@
"moment": "^2.22.1",
"react": "16.2.0",
"react-native": "0.55.3",
"react-native-fast-image": "^5.0.3",
"react-native-fetch-blob": "^0.10.8",
"react-native-image-zoom-viewer": "^2.2.5",
"react-native-vector-icons": "^5.0.0",

View file

@ -1,6 +1,7 @@
import React from 'react';
import { ActivityIndicator, Image, Text, View } from 'react-native';
import Colors from '../../styles/colors';
import FastImage from 'react-native-fast-image'
import fileItemMediaStyle from '../../styles/fileItemMedia';
class FileItemMedia extends React.PureComponent {
@ -18,6 +19,10 @@ class FileItemMedia extends React.PureComponent {
fileItemMediaStyle.autothumbOrange,
];
state: {
imageLoadFailed: false
};
componentWillMount() {
this.setState({
autoThumbStyle:
@ -27,21 +32,47 @@ class FileItemMedia extends React.PureComponent {
});
}
getFastImageResizeMode(resizeMode) {
switch (resizeMode) {
case "contain":
return FastImage.resizeMode.contain;
case "stretch":
console.log('using stretch resize mode...');
return FastImage.resizeMode.stretch;
case "center":
return FastImage.resizeMode.center;
default:
return FastImage.resizeMode.cover;
}
}
render() {
let style = this.props.style;
const { blurRadius, isResolvingUri, thumbnail, title, resizeMode } = this.props;
const atStyle = this.state.autoThumbStyle;
if (thumbnail && ((typeof thumbnail) === 'string')) {
if (thumbnail && ((typeof thumbnail) === 'string') && !this.state.imageLoadFailed) {
if (style == null) {
style = fileItemMediaStyle.thumbnail;
}
if (blurRadius > 0) {
// No blur radius support in FastImage yet
return (
<Image
source={{uri: thumbnail}}
blurRadius={blurRadius}
resizeMode={resizeMode ? resizeMode : "cover"}
style={style}
/>);
}
return (
<Image source={{uri: thumbnail}}
blurRadius={blurRadius}
resizeMode={resizeMode ? resizeMode : "cover"}
style={style} />
<FastImage
source={{uri: thumbnail}}
onError={() => this.setState({ imageLoadFailed: true })}
resizeMode={this.getFastImageResizeMode(resizeMode)}
style={style}
/>
);
}

View file

@ -27,19 +27,27 @@ class FileListItem extends React.PureComponent {
formatBytes = (bytes) => {
if (bytes < 1048576) { // < 1MB
const value = (bytes / 1024.0).toFixed(2);
const value = (bytes / 1024.0).toFixed(0);
return `${value} KB`;
}
if (bytes < 1073741824) { // < 1GB
const value = (bytes / (1024.0 * 1024.0)).toFixed(2);
const value = (bytes / (1024.0 * 1024.0)).toFixed(0);
return `${value} MB`;
}
const value = (bytes / (1024.0 * 1024.0 * 1024.0)).toFixed(2);
const value = (bytes / (1024.0 * 1024.0 * 1024.0)).toFixed(0);
return `${value} GB`;
}
formatTitle = (title) => {
if (!title) {
return title;
}
return (title.length > 80) ? title.substring(0, 77).trim() + '...' : title;
}
getDownloadProgress = (fileInfo) => {
return Math.ceil((fileInfo.written_bytes / fileInfo.total_bytes) * 100);
}
@ -85,7 +93,7 @@ class FileListItem extends React.PureComponent {
</View>
</View>)}
{!isResolving && <Text style={fileListStyle.title}>{title || name}</Text>}
{!isResolving && <Text style={fileListStyle.title}>{this.formatTitle(title) || this.formatTitle(name)}</Text>}
{!isResolving && channel &&
<Link style={fileListStyle.publisher} text={channel} onPress={() => {
const channelUri = normalizeURI(channel);

View file

@ -1,14 +1,17 @@
import { Dimensions, StyleSheet } from 'react-native';
import { Dimensions, PixelRatio, StyleSheet } from 'react-native';
import Colors from './colors';
const screenDimension = Dimensions.get('window');
const screenWidth = screenDimension.width;
const screenHeight = screenDimension.height;
const screenWidthPixels = PixelRatio.getPixelSizeForLayoutSize(screenWidth);
const screenHeightPixels = PixelRatio.getPixelSizeForLayoutSize(screenHeight);
console.log('screenHeightPixels=' + screenHeightPixels);
// calculate thumbnail width and height based on device's aspect ratio
const horizontalMargin = 48; // left and right margins (24 + 24)
const verticalMargin = (screenWidth / screenHeight) * horizontalMargin;
const verticalMargin = (screenWidthPixels > 720 && screenHeightPixels > 1920) ? 0 : ((screenWidthPixels <= 720) ? 20 : 16);
const mediaWidth = screenWidth - horizontalMargin;
const mediaHeight = (screenWidth / (screenHeight - verticalMargin)) * mediaWidth;
const mediaHeight = ((screenWidth / screenHeight) * ((screenWidthPixels <= 720) ? screenWidth : mediaWidth)) - verticalMargin;
const discoverStyle = StyleSheet.create({
container: {

View file

@ -1,18 +1,21 @@
import { Dimensions, StyleSheet } from 'react-native';
import { Dimensions, PixelRatio, StyleSheet } from 'react-native';
import Colors from './colors';
const screenDimension = Dimensions.get('window');
const screenWidth = screenDimension.width;
const screenHeight = screenDimension.height;
const thumbnailHeight = 100;
const thumbnailWidth = (screenHeight / screenWidth) * thumbnailHeight;
const screenWidthPixels = PixelRatio.getPixelSizeForLayoutSize(screenWidth);
const screenHeightPixels = PixelRatio.getPixelSizeForLayoutSize(screenHeight);
const verticalAdjust = (screenHeightPixels > 1280 && screenHeightPixels <= 1920) ? 6 : 0;
const thumbnailWidth = (screenWidthPixels <= 720) ? 144 : 156;
const thumbnailHeight = ((screenWidth / screenHeight) * thumbnailWidth) - verticalAdjust;
const fileListStyle = StyleSheet.create({
item: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 16
marginTop: 8
},
detailsContainer: {
flex: 1
@ -20,37 +23,37 @@ const fileListStyle = StyleSheet.create({
thumbnail: {
width: thumbnailWidth,
height: thumbnailHeight,
marginRight: 16,
marginRight: (screenWidthPixels <= 720) ? 10 : 12,
justifyContent: 'center'
},
title: {
fontFamily: 'Metropolis-SemiBold',
fontSize: 16
fontSize: (screenWidthPixels <= 720) ? 12 : 16
},
uri: {
fontFamily: 'Metropolis-SemiBold',
fontSize: 14,
fontSize: (screenWidthPixels <= 720) ? 12 : 14,
marginBottom: 8
},
publisher: {
fontFamily: 'Metropolis-SemiBold',
fontSize: 14,
marginTop: 3,
fontSize: (screenWidthPixels <= 720) ? 12 : 14,
marginTop: (screenWidthPixels <= 720) ? 1 : 3,
color: Colors.LbryGreen
},
loading: {
position: 'absolute'
},
downloadInfo: {
marginTop: 8
marginTop: (screenWidthPixels <= 720) ? 4 : 8
},
downloadStorage: {
fontFamily: 'Metropolis-Regular',
fontSize: 14,
fontSize: (screenWidthPixels <= 720) ? 12 : 14,
color: Colors.ChannelGrey
},
progress: {
marginTop: 4,
marginTop: (screenWidthPixels <= 720) ? 2 : 4,
height: 3,
flex: 1,
flexDirection: 'row'

View file

@ -21,7 +21,7 @@ const searchStyle = StyleSheet.create({
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 16
marginTop: 8
},
searchInput: {
width: '100%',

View file

@ -40,6 +40,10 @@ android {
}
}
dexOptions {
jumboMode true
}
{% if args.sign -%}
signingConfigs {
release {
@ -80,9 +84,10 @@ subprojects {
}
dependencies {
compile project(':react-native-video')
compile project(':react-native-fast-image')
compile project(':react-native-fetch-blob')
{%- for aar in aars %}
compile project(':react-native-video')
{%- for aar in aars %}
compile(name: '{{ aar }}', ext: 'aar')
{%- endfor -%}
{%- if args.depends -%}

View file

@ -1,5 +1,7 @@
rootProject.name = 'browser'
include ':react-native-video'
project(':react-native-video').projectDir = new File(rootProject.projectDir, './react/node_modules/react-native-video/android-exoplayer')
include ':react-native-fast-image'
project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, './react/node_modules/react-native-fast-image/android')
include ':react-native-fetch-blob'
project(':react-native-fetch-blob').projectDir = new File(rootProject.projectDir, './react/node_modules/react-native-fetch-blob/android')
include ':react-native-video'
project(':react-native-video').projectDir = new File(rootProject.projectDir, './react/node_modules/react-native-video/android-exoplayer')

View file

@ -20,6 +20,7 @@ import android.telephony.TelephonyManager;
import android.widget.Toast;
import com.brentvatne.react.ReactVideoPackage;
import com.dylanvann.fastimage.FastImageViewPackage;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.ReactRootView;
@ -103,6 +104,7 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(new MainReactPackage())
.addPackage(new FastImageViewPackage())
.addPackage(new ReactVideoPackage())
.addPackage(new RNFetchBlobPackage())
.addPackage(new LbryReactPackage())