From c5eca7ec040af7978cb55eccaea5e0d10a2e730a Mon Sep 17 00:00:00 2001 From: Andy Phillipson Date: Fri, 23 Oct 2020 21:42:40 -0400 Subject: [PATCH 1/2] Add abilty to load the same image via multiple parallel app requests --- README.md | 5 +++-- index.js | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 755528d..58a92c4 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ v1.0.0 | `````` or `````` properties | | | same with `````` and `````` | 1.0 | | expiration | number | 604800 | expiration seconds (0:no expiration, default cache a week) | 1.0 | | activityIndicator | Component | null | when loading show it as an indicator, you can use your component| 1.0 | +| retry | Object | {count: 3, interval: 100} | when multiple parallel requests are made for the same uri only the first remote fetch is made, the remaining requests will read from cache. If the remote request has not completed then cache checks for subsequent requests will occur using this retry config. Count is the number of times to try. Interval is the time to wait between each retry. If the first (original) remote request fails then all requests will fail (your app may retry, e.g., provide user interction for refresh) | 1.0.8 | ### Usage @@ -95,7 +96,7 @@ render() ### Static Function -**CachedImage.getSize(url, success=(width,height)=>void,fail=(error)=>void)** +**CachedImage.getSize(url, success=(width,height)=>void,fail=(error)=>void,retry={retryConfig})** Get the image size, if no cache, will cache it. @@ -111,7 +112,7 @@ CachedImage.getSize("https://assets-cdn.github.com/images/modules/logos_page/Oct }); ``` -**CachedImage.prefetch(url,expiration=0,success=(cachFile)=>void,fail=(error)=>void)** +**CachedImage.prefetch(url,expiration=0,success=(cachFile)=>void,fail=(error)=>void,retry={retryConfig})** prefetch an image and cache it. diff --git a/index.js b/index.js index 1f75ddb..4e94fae 100644 --- a/index.js +++ b/index.js @@ -20,11 +20,14 @@ const SHA1 = require('crypto-js/sha1'); const defaultImageTypes = ['png', 'jpeg', 'jpg', 'gif', 'bmp', 'tiff', 'tif']; +const defaultRetry = {count: 3, interval: 100}; + export default class CachedImage extends Component { static defaultProps = { expiration: 86400 * 7, // default cache a week activityIndicator: null, // default not show an activity indicator + defaultRetry, // default prefetch retry }; static cacheDir = RNFetchBlob.fs.dirs.CacheDir + "/CachedImage/"; @@ -72,8 +75,9 @@ export default class CachedImage extends Component { * @param url * @param success callback (width,height)=>{} * @param failure callback (error:string)=>{} + * @param retry object {count:number, interval:number} */ - static getSize = (url: string, success: Function, failure: Function) => { + static getSize = (url: string, success: Function, failure: Function, retry: Object = defaultRetry) => { CachedImage.prefetch(url, 0, (cacheFile) => { @@ -86,7 +90,7 @@ export default class CachedImage extends Component { }, (error) => { Image.getSize(url, success, failure); - }); + }, retry); }; @@ -97,8 +101,9 @@ export default class CachedImage extends Component { * @param expiration if zero or not set, no expiration * @param success callback (cacheFile:string)=>{} * @param failure callback (error:string)=>{} + * @param retry object {count:number, interval:number} */ - static prefetch = (url: string, expiration: number, success: Function, failure: Function) => { + static prefetch = (url: string, expiration: number, success: Function, failure: Function, retry: Object = defaultRetry) => { // source invalidate if (!url || url.toString() !== url) { @@ -107,9 +112,25 @@ export default class CachedImage extends Component { } const cacheFile = _getCacheFilename(url); - if(CachedImage.sameURL.includes(cacheFile)){ - success && success(cacheFile); + function checkCached(exists) { + if (exists) { + success && success(cacheFile); + } else { + if (retry.count > 0) { + --retry.count; + setTimeout(() => { + CachedImage.prefetch(url, expiration, success, failure, retry); + }, retry.interval); + } else { + failure && failure("same url fetch timeout."); + } + } + } + + if(CachedImage.sameURL.includes(cacheFile)) { + // Check to see if the cacheFile exists yet (download may be in progress). + CachedImage.isUrlCached(url, checkCached, failure); return } CachedImage.sameURL.push(cacheFile) @@ -125,8 +146,6 @@ export default class CachedImage extends Component { }) .catch((error) => { // not exist - // success && success(cacheFile) - _saveCacheFile(url, success, failure); }); }; @@ -169,11 +188,11 @@ export default class CachedImage extends Component { // cache failed use original source if (this._mounted) { setTimeout(() => { - this.setState({source: { uri: this.props.source}}); + this.setState({source: this.props.source}); }, 0); } this._downloading = false; - }); + }, this.props.retry); } } else { this.state.source = this.props.source; From 3d199bf6145e58a093523546481f39bf50acb71d Mon Sep 17 00:00:00 2001 From: Andy Phillipson Date: Mon, 15 Aug 2022 13:53:43 -0400 Subject: [PATCH 2/2] Update deps --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index faac18d..cee4b90 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,6 @@ "crypto-js": "^3.1.9-1" }, "peerDependencies": { - "rn-fetch-blob": "^0.10.12" + "rn-fetch-blob": "^0.12.0" } } \ No newline at end of file