diff --git a/app/package-lock.json b/app/package-lock.json index 071ff51..aa9b0b4 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -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", diff --git a/app/package.json b/app/package.json index 14315b1..f70e51c 100644 --- a/app/package.json +++ b/app/package.json @@ -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", diff --git a/app/src/component/fileItemMedia/view.js b/app/src/component/fileItemMedia/view.js index 9541916..e4d792c 100644 --- a/app/src/component/fileItemMedia/view.js +++ b/app/src/component/fileItemMedia/view.js @@ -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 ( + ); + } + return ( - + this.setState({ imageLoadFailed: true })} + resizeMode={this.getFastImageResizeMode(resizeMode)} + style={style} + /> ); } diff --git a/app/src/component/fileListItem/view.js b/app/src/component/fileListItem/view.js index 2d3c4ac..8191652 100644 --- a/app/src/component/fileListItem/view.js +++ b/app/src/component/fileListItem/view.js @@ -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 { )} - {!isResolving && {title || name}} + {!isResolving && {this.formatTitle(title) || this.formatTitle(name)}} {!isResolving && channel && { const channelUri = normalizeURI(channel); diff --git a/app/src/styles/discover.js b/app/src/styles/discover.js index a5f71bf..1b5a016 100644 --- a/app/src/styles/discover.js +++ b/app/src/styles/discover.js @@ -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: { diff --git a/app/src/styles/fileList.js b/app/src/styles/fileList.js index dfaec77..bc684a0 100644 --- a/app/src/styles/fileList.js +++ b/app/src/styles/fileList.js @@ -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' diff --git a/app/src/styles/search.js b/app/src/styles/search.js index 7d6c971..ac3ca9d 100644 --- a/app/src/styles/search.js +++ b/app/src/styles/search.js @@ -21,7 +21,7 @@ const searchStyle = StyleSheet.create({ flex: 1, flexDirection: 'row', justifyContent: 'space-between', - marginTop: 16 + marginTop: 8 }, searchInput: { width: '100%', diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/templates/build.tmpl.gradle b/p4a/pythonforandroid/bootstraps/lbry/build/templates/build.tmpl.gradle index acb74d2..5d8b782 100644 --- a/p4a/pythonforandroid/bootstraps/lbry/build/templates/build.tmpl.gradle +++ b/p4a/pythonforandroid/bootstraps/lbry/build/templates/build.tmpl.gradle @@ -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 -%} diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/templates/settings.tmpl.gradle b/p4a/pythonforandroid/bootstraps/lbry/build/templates/settings.tmpl.gradle index 33372a1..aeb014f 100644 --- a/p4a/pythonforandroid/bootstraps/lbry/build/templates/settings.tmpl.gradle +++ b/p4a/pythonforandroid/bootstraps/lbry/build/templates/settings.tmpl.gradle @@ -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') diff --git a/src/main/java/io/lbry/browser/MainActivity.java b/src/main/java/io/lbry/browser/MainActivity.java index feaada3..bc04e8c 100644 --- a/src/main/java/io/lbry/browser/MainActivity.java +++ b/src/main/java/io/lbry/browser/MainActivity.java @@ -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())