Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev'
Browse files Browse the repository at this point in the history
Conflicts:
	image.js
	package.json
  • Loading branch information
Jesse Badwal committed May 22, 2018
2 parents 0d25c93 + 4bd7920 commit 9e408e1
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 75 deletions.
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.project
/node_modules/
/npm-debug.log
/.project
/node_modules/
/npm-debug.log
/.settings/
145 changes: 77 additions & 68 deletions image.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import PropTypes from 'prop-types';
import React from 'react';
import { Image, ActivityIndicator, NetInfo, Platform } from 'react-native';
import RNFS, { DocumentDirectoryPath } from 'react-native-fs';
Expand All @@ -9,39 +10,50 @@ const URL = require('url-parse');
export default
class CacheableImage extends React.Component {

constructor(props) {
super(props)
this.imageDownloadBegin = this.imageDownloadBegin.bind(this);
this.imageDownloadProgress = this.imageDownloadProgress.bind(this);
this._handleConnectivityChange = this._handleConnectivityChange.bind(this);
this._stopDownload = this._stopDownload.bind(this);

this.state = {
isRemote: false,
cachedImagePath: null,
cacheable: true
};
static propTypes = {
activityIndicatorProps: PropTypes.object,
defaultSource: Image.propTypes.source,
useQueryParamsInCacheKey: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.array
]),
checkNetwork: PropTypes.bool,
networkAvailable: PropTypes.bool,
downloadInBackground: PropTypes.bool,
storagePermissionGranted: PropTypes.bool
}

this.networkAvailable = props.networkAvailable;
this.downloading = false;
this.jobId = null;
};
static defaultProps = {
style: { backgroundColor: 'transparent' },
activityIndicatorProps: {
style: { backgroundColor: 'transparent', flex: 1 }
},
useQueryParamsInCacheKey: false, // bc
checkNetwork: true,
networkAvailable: false,
downloadInBackground: (Platform.OS === 'ios') ? false : true,
storagePermissionGranted: true
}

componentWillReceiveProps(nextProps) {
if (nextProps.source != this.props.source || nextProps.networkAvailable != this.networkAvailable) {
this.networkAvailable = nextProps.networkAvailable;
this._processSource(nextProps.source);
}
state = {
isRemote: false,
cachedImagePath: null,
cacheable: true
}

shouldComponentUpdate(nextProps, nextState) {
if (nextState === this.state && nextProps === this.props) {
return false;
networkAvailable = this.props.networkAvailable

downloading = false

jobId = null

setNativeProps(nativeProps) {
if (this._imageComponent) {
this._imageComponent.setNativeProps(nativeProps);
}
return true;
}
async imageDownloadBegin(info) {

imageDownloadBegin = info => {
switch (info.statusCode) {
case 404:
case 403:
Expand All @@ -52,14 +64,14 @@ class CacheableImage extends React.Component {
}
}

async imageDownloadProgress(info) {
imageDownloadProgress = info => {
if ((info.contentLength / info.bytesWritten) == 1) {
this.downloading = false;
this.jobId = null;
}
}

async checkImageCache(imageUri, cachePath, cacheKey) {
checkImageCache = (imageUri, cachePath, cacheKey) => {
const dirPath = DocumentDirectoryPath+'/'+cachePath;
const filePath = dirPath+'/'+cacheKey;

Expand Down Expand Up @@ -154,7 +166,7 @@ class CacheableImage extends React.Component {
});
}

_deleteFilePath(filePath) {
_deleteFilePath = (filePath) => {
RNFS
.exists(filePath)
.then((res) => {
Expand All @@ -166,9 +178,10 @@ class CacheableImage extends React.Component {
});
}

_processSource(source, skipSourceCheck) {
_processSource = (source, skipSourceCheck) => {

if (source !== null
if (this.props.storagePermissionGranted
&& source !== null
&& source != ''
&& typeof source === "object"
&& source.hasOwnProperty('uri')
Expand Down Expand Up @@ -210,17 +223,38 @@ class CacheableImage extends React.Component {
}
}

_stopDownload() {
_stopDownload = () => {
if (!this.jobId) return;

this.downloading = false;
RNFS.stopDownload(this.jobId);
this.jobId = null;
}

_handleConnectivityChange = isConnected => {
this.networkAvailable = isConnected;
if (this.networkAvailable && this.state.isRemote && !this.state.cachedImagePath) {
this._processSource(this.props.source);
}
}

componentWillReceiveProps(nextProps) {
if (nextProps.source != this.props.source || nextProps.networkAvailable != this.networkAvailable) {
this.networkAvailable = nextProps.networkAvailable;
this._processSource(nextProps.source);
}
}

shouldComponentUpdate(nextProps, nextState) {
if (nextState === this.state && nextProps === this.props) {
return false;
}
return true;
}

componentWillMount() {
if (this.props.checkNetwork) {
NetInfo.isConnected.addEventListener('change', this._handleConnectivityChange);
NetInfo.isConnected.addEventListener('connectionChange', this._handleConnectivityChange);
// componentWillUnmount unsets this._handleConnectivityChange in case the component unmounts before this fetch resolves
NetInfo.isConnected.fetch().done(this._handleConnectivityChange);
}
Expand All @@ -230,21 +264,17 @@ class CacheableImage extends React.Component {

componentWillUnmount() {
if (this.props.checkNetwork) {
NetInfo.isConnected.removeEventListener('change', this._handleConnectivityChange);
NetInfo.isConnected.removeEventListener('connectionChange', this._handleConnectivityChange);
this._handleConnectivityChange = null;
}

if (this.downloading && this.jobId) {
this._stopDownload();
}
}

async _handleConnectivityChange(isConnected) {
this.networkAvailable = isConnected;
};


render() {
if (!this.state.isRemote && !this.props.defaultSource) {
if ((!this.state.isRemote && !this.props.defaultSource) || !this.props.storagePermissionGranted) {
return this.renderLocal();
}

Expand All @@ -256,15 +286,17 @@ class CacheableImage extends React.Component {
return this.renderDefaultSource();
}

const { children, defaultSource, checkNetwork, networkAvailable, downloadInBackground, activityIndicatorProps, ...props } = this.props;
const style = [activityIndicatorProps.style, this.props.style];
return (
<ActivityIndicator {...this.props.activityIndicatorProps} />
<ActivityIndicator {...props} {...activityIndicatorProps} style={style} />
);
}

renderCache() {
const { children, defaultSource, checkNetwork, networkAvailable, downloadInBackground, activityIndicatorProps, ...props } = this.props;
return (
<ResponsiveImage {...props} source={{uri: 'file://'+this.state.cachedImagePath}}>
<ResponsiveImage {...props} source={{uri: 'file://'+this.state.cachedImagePath}} ref={component => this._imageComponent = component}>
{children}
</ResponsiveImage>
);
Expand All @@ -273,7 +305,7 @@ class CacheableImage extends React.Component {
renderLocal() {
const { children, defaultSource, checkNetwork, networkAvailable, downloadInBackground, activityIndicatorProps, ...props } = this.props;
return (
<ResponsiveImage {...props}>
<ResponsiveImage {...props} ref={component => this._imageComponent = component}>
{children}
</ResponsiveImage>
);
Expand All @@ -282,32 +314,9 @@ class CacheableImage extends React.Component {
renderDefaultSource() {
const { children, defaultSource, checkNetwork, networkAvailable, ...props } = this.props;
return (
<CacheableImage {...props} source={defaultSource} checkNetwork={false} networkAvailable={this.networkAvailable} >
<CacheableImage {...props} source={defaultSource} checkNetwork={false} networkAvailable={this.networkAvailable} ref={component => this._imageComponent = component}>
{children}
</CacheableImage>
);
}
}

CacheableImage.propTypes = {
activityIndicatorProps: React.PropTypes.object,
defaultSource: Image.propTypes.source,
useQueryParamsInCacheKey: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.array
]),
checkNetwork: React.PropTypes.bool,
networkAvailable: React.PropTypes.bool,
downloadInBackground: React.PropTypes.bool
};

CacheableImage.defaultProps = {
style: { backgroundColor: 'transparent' },
activityIndicatorProps: {
style: { backgroundColor: 'transparent', flex: 1 }
},
useQueryParamsInCacheKey: false, // bc
checkNetwork: true,
networkAvailable: false,
downloadInBackground: (Platform.OS === 'ios') ? false : true
};
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-cacheable-image",
"version": "1.6.0",
"version": "2.0.0",
"description": "An Image component for React Native that will cache itself to disk",
"main": "image.js",
"scripts": {
Expand All @@ -21,8 +21,9 @@
"homepage": "https://github.com/jayesbe/react-native-cacheable-image#readme",
"dependencies": {
"crypto-js": "^3.1.6",
"react-native-fs": "^2.0.1-rc.2",
"url-parse": "^1.1.1",
"react-native-responsive-image": "^2.2.0"
"prop-types": "^15.5.10",
"react-native-fs": "^2.3.0",
"react-native-responsive-image": "^2.0.0",
"url-parse": "^1.1.1"
}
}

0 comments on commit 9e408e1

Please sign in to comment.