Skip to content

Commit 9e408e1

Browse files
author
Jesse Badwal
committed
Merge remote-tracking branch 'origin/dev'
Conflicts: image.js package.json
2 parents 0d25c93 + 4bd7920 commit 9e408e1

File tree

3 files changed

+86
-75
lines changed

3 files changed

+86
-75
lines changed

.gitignore

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
/.project
2-
/node_modules/
3-
/npm-debug.log
1+
/.project
2+
/node_modules/
3+
/npm-debug.log
4+
/.settings/

image.js

Lines changed: 77 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import PropTypes from 'prop-types';
12
import React from 'react';
23
import { Image, ActivityIndicator, NetInfo, Platform } from 'react-native';
34
import RNFS, { DocumentDirectoryPath } from 'react-native-fs';
@@ -9,39 +10,50 @@ const URL = require('url-parse');
910
export default
1011
class CacheableImage extends React.Component {
1112

12-
constructor(props) {
13-
super(props)
14-
this.imageDownloadBegin = this.imageDownloadBegin.bind(this);
15-
this.imageDownloadProgress = this.imageDownloadProgress.bind(this);
16-
this._handleConnectivityChange = this._handleConnectivityChange.bind(this);
17-
this._stopDownload = this._stopDownload.bind(this);
18-
19-
this.state = {
20-
isRemote: false,
21-
cachedImagePath: null,
22-
cacheable: true
23-
};
13+
static propTypes = {
14+
activityIndicatorProps: PropTypes.object,
15+
defaultSource: Image.propTypes.source,
16+
useQueryParamsInCacheKey: PropTypes.oneOfType([
17+
PropTypes.bool,
18+
PropTypes.array
19+
]),
20+
checkNetwork: PropTypes.bool,
21+
networkAvailable: PropTypes.bool,
22+
downloadInBackground: PropTypes.bool,
23+
storagePermissionGranted: PropTypes.bool
24+
}
2425

25-
this.networkAvailable = props.networkAvailable;
26-
this.downloading = false;
27-
this.jobId = null;
28-
};
26+
static defaultProps = {
27+
style: { backgroundColor: 'transparent' },
28+
activityIndicatorProps: {
29+
style: { backgroundColor: 'transparent', flex: 1 }
30+
},
31+
useQueryParamsInCacheKey: false, // bc
32+
checkNetwork: true,
33+
networkAvailable: false,
34+
downloadInBackground: (Platform.OS === 'ios') ? false : true,
35+
storagePermissionGranted: true
36+
}
2937

30-
componentWillReceiveProps(nextProps) {
31-
if (nextProps.source != this.props.source || nextProps.networkAvailable != this.networkAvailable) {
32-
this.networkAvailable = nextProps.networkAvailable;
33-
this._processSource(nextProps.source);
34-
}
38+
state = {
39+
isRemote: false,
40+
cachedImagePath: null,
41+
cacheable: true
3542
}
3643

37-
shouldComponentUpdate(nextProps, nextState) {
38-
if (nextState === this.state && nextProps === this.props) {
39-
return false;
44+
networkAvailable = this.props.networkAvailable
45+
46+
downloading = false
47+
48+
jobId = null
49+
50+
setNativeProps(nativeProps) {
51+
if (this._imageComponent) {
52+
this._imageComponent.setNativeProps(nativeProps);
4053
}
41-
return true;
4254
}
43-
44-
async imageDownloadBegin(info) {
55+
56+
imageDownloadBegin = info => {
4557
switch (info.statusCode) {
4658
case 404:
4759
case 403:
@@ -52,14 +64,14 @@ class CacheableImage extends React.Component {
5264
}
5365
}
5466

55-
async imageDownloadProgress(info) {
67+
imageDownloadProgress = info => {
5668
if ((info.contentLength / info.bytesWritten) == 1) {
5769
this.downloading = false;
5870
this.jobId = null;
5971
}
6072
}
6173

62-
async checkImageCache(imageUri, cachePath, cacheKey) {
74+
checkImageCache = (imageUri, cachePath, cacheKey) => {
6375
const dirPath = DocumentDirectoryPath+'/'+cachePath;
6476
const filePath = dirPath+'/'+cacheKey;
6577

@@ -154,7 +166,7 @@ class CacheableImage extends React.Component {
154166
});
155167
}
156168

157-
_deleteFilePath(filePath) {
169+
_deleteFilePath = (filePath) => {
158170
RNFS
159171
.exists(filePath)
160172
.then((res) => {
@@ -166,9 +178,10 @@ class CacheableImage extends React.Component {
166178
});
167179
}
168180

169-
_processSource(source, skipSourceCheck) {
181+
_processSource = (source, skipSourceCheck) => {
170182

171-
if (source !== null
183+
if (this.props.storagePermissionGranted
184+
&& source !== null
172185
&& source != ''
173186
&& typeof source === "object"
174187
&& source.hasOwnProperty('uri')
@@ -210,17 +223,38 @@ class CacheableImage extends React.Component {
210223
}
211224
}
212225

213-
_stopDownload() {
226+
_stopDownload = () => {
214227
if (!this.jobId) return;
215228

216229
this.downloading = false;
217230
RNFS.stopDownload(this.jobId);
218231
this.jobId = null;
219232
}
220233

234+
_handleConnectivityChange = isConnected => {
235+
this.networkAvailable = isConnected;
236+
if (this.networkAvailable && this.state.isRemote && !this.state.cachedImagePath) {
237+
this._processSource(this.props.source);
238+
}
239+
}
240+
241+
componentWillReceiveProps(nextProps) {
242+
if (nextProps.source != this.props.source || nextProps.networkAvailable != this.networkAvailable) {
243+
this.networkAvailable = nextProps.networkAvailable;
244+
this._processSource(nextProps.source);
245+
}
246+
}
247+
248+
shouldComponentUpdate(nextProps, nextState) {
249+
if (nextState === this.state && nextProps === this.props) {
250+
return false;
251+
}
252+
return true;
253+
}
254+
221255
componentWillMount() {
222256
if (this.props.checkNetwork) {
223-
NetInfo.isConnected.addEventListener('change', this._handleConnectivityChange);
257+
NetInfo.isConnected.addEventListener('connectionChange', this._handleConnectivityChange);
224258
// componentWillUnmount unsets this._handleConnectivityChange in case the component unmounts before this fetch resolves
225259
NetInfo.isConnected.fetch().done(this._handleConnectivityChange);
226260
}
@@ -230,21 +264,17 @@ class CacheableImage extends React.Component {
230264

231265
componentWillUnmount() {
232266
if (this.props.checkNetwork) {
233-
NetInfo.isConnected.removeEventListener('change', this._handleConnectivityChange);
267+
NetInfo.isConnected.removeEventListener('connectionChange', this._handleConnectivityChange);
234268
this._handleConnectivityChange = null;
235269
}
236270

237271
if (this.downloading && this.jobId) {
238272
this._stopDownload();
239273
}
240274
}
241-
242-
async _handleConnectivityChange(isConnected) {
243-
this.networkAvailable = isConnected;
244-
};
245-
275+
246276
render() {
247-
if (!this.state.isRemote && !this.props.defaultSource) {
277+
if ((!this.state.isRemote && !this.props.defaultSource) || !this.props.storagePermissionGranted) {
248278
return this.renderLocal();
249279
}
250280

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

289+
const { children, defaultSource, checkNetwork, networkAvailable, downloadInBackground, activityIndicatorProps, ...props } = this.props;
290+
const style = [activityIndicatorProps.style, this.props.style];
259291
return (
260-
<ActivityIndicator {...this.props.activityIndicatorProps} />
292+
<ActivityIndicator {...props} {...activityIndicatorProps} style={style} />
261293
);
262294
}
263295

264296
renderCache() {
265297
const { children, defaultSource, checkNetwork, networkAvailable, downloadInBackground, activityIndicatorProps, ...props } = this.props;
266298
return (
267-
<ResponsiveImage {...props} source={{uri: 'file://'+this.state.cachedImagePath}}>
299+
<ResponsiveImage {...props} source={{uri: 'file://'+this.state.cachedImagePath}} ref={component => this._imageComponent = component}>
268300
{children}
269301
</ResponsiveImage>
270302
);
@@ -273,7 +305,7 @@ class CacheableImage extends React.Component {
273305
renderLocal() {
274306
const { children, defaultSource, checkNetwork, networkAvailable, downloadInBackground, activityIndicatorProps, ...props } = this.props;
275307
return (
276-
<ResponsiveImage {...props}>
308+
<ResponsiveImage {...props} ref={component => this._imageComponent = component}>
277309
{children}
278310
</ResponsiveImage>
279311
);
@@ -282,32 +314,9 @@ class CacheableImage extends React.Component {
282314
renderDefaultSource() {
283315
const { children, defaultSource, checkNetwork, networkAvailable, ...props } = this.props;
284316
return (
285-
<CacheableImage {...props} source={defaultSource} checkNetwork={false} networkAvailable={this.networkAvailable} >
317+
<CacheableImage {...props} source={defaultSource} checkNetwork={false} networkAvailable={this.networkAvailable} ref={component => this._imageComponent = component}>
286318
{children}
287319
</CacheableImage>
288320
);
289321
}
290322
}
291-
292-
CacheableImage.propTypes = {
293-
activityIndicatorProps: React.PropTypes.object,
294-
defaultSource: Image.propTypes.source,
295-
useQueryParamsInCacheKey: React.PropTypes.oneOfType([
296-
React.PropTypes.bool,
297-
React.PropTypes.array
298-
]),
299-
checkNetwork: React.PropTypes.bool,
300-
networkAvailable: React.PropTypes.bool,
301-
downloadInBackground: React.PropTypes.bool
302-
};
303-
304-
CacheableImage.defaultProps = {
305-
style: { backgroundColor: 'transparent' },
306-
activityIndicatorProps: {
307-
style: { backgroundColor: 'transparent', flex: 1 }
308-
},
309-
useQueryParamsInCacheKey: false, // bc
310-
checkNetwork: true,
311-
networkAvailable: false,
312-
downloadInBackground: (Platform.OS === 'ios') ? false : true
313-
};

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-cacheable-image",
3-
"version": "1.6.0",
3+
"version": "2.0.0",
44
"description": "An Image component for React Native that will cache itself to disk",
55
"main": "image.js",
66
"scripts": {
@@ -21,8 +21,9 @@
2121
"homepage": "https://github.com/jayesbe/react-native-cacheable-image#readme",
2222
"dependencies": {
2323
"crypto-js": "^3.1.6",
24-
"react-native-fs": "^2.0.1-rc.2",
25-
"url-parse": "^1.1.1",
26-
"react-native-responsive-image": "^2.2.0"
24+
"prop-types": "^15.5.10",
25+
"react-native-fs": "^2.3.0",
26+
"react-native-responsive-image": "^2.0.0",
27+
"url-parse": "^1.1.1"
2728
}
2829
}

0 commit comments

Comments
 (0)