diff --git a/ImageCacheProvider.js b/ImageCacheProvider.js index 72ea051..5edc2de 100644 --- a/ImageCacheProvider.js +++ b/ImageCacheProvider.js @@ -1,15 +1,23 @@ 'use strict'; const _ = require('lodash'); -const RNFS = require('react-native-fs'); + +const RNFatchBlob = require('react-native-fetch-blob').default; + +const { + fs +} = RNFatchBlob; const { - DocumentDirectoryPath -} = RNFS; + DocumentDir: DocumentDirectoryPath +} = fs.dirs; const SHA1 = require("crypto-js/sha1"); const URL = require('url-parse'); +const defaultHeaders = {}; +const defaultResolveHeaders = _.constant(defaultHeaders); + const defaultOptions = { useQueryParamsInCacheKey: false }; @@ -68,8 +76,9 @@ function getCachedImageFilePath(url, options) { } function deleteFile(filePath) { - return RNFS.exists(filePath) - .then(res => res && RNFS.unlink(filePath)) + return fs.stat(filePath) + .then(res => res && res.type === 'file') + .then(exists => exists && fs.unlink(filePath)) .catch((err) => { // swallow error to always resolve }); @@ -78,7 +87,10 @@ function deleteFile(filePath) { function ensurePath(filePath) { const parts = filePath.split('/'); const dirPath = _.initial(parts).join('/'); - return RNFS.mkdir(dirPath, {NSURLIsExcludedFromBackupKey: true}); + return fs.isDir(dirPath) + .then(exists => + !exists && fs.mkdir(dirPath) + ); } /** @@ -86,32 +98,24 @@ function ensurePath(filePath) { * is complete and the file is saved. * if the download fails, or was stopped the partial file is deleted, and the * promise is rejected - * @param fromUrl - * @param toFile + * @param fromUrl String source url + * @param toFile String destination path + * @param headers Object headers to use when downloading the file * @returns {Promise} */ -function downloadImage(fromUrl, toFile, headers) { +function downloadImage(fromUrl, toFile, headers = {}) { // use toFile as the key as is was created using the cacheKey if (!_.has(activeDownloads, toFile)) { // create an active download for this file activeDownloads[toFile] = new Promise((resolve, reject) => { - const downloadOptions = { - fromUrl, - toFile, - headers - }; - RNFS.downloadFile(downloadOptions).promise - .then(res => { - if (Math.floor(res.statusCode / 100) == 2) { - resolve(toFile); - } else { - return Promise.reject('Failed to successfully download image') - } - }) - .catch(err => { - return deleteFile(toFile) + RNFatchBlob + .config({path: toFile}) + .fetch('GET', fromUrl, headers) + .then(res => resolve(toFile)) + .catch(err => + deleteFile(toFile) .then(() => reject(err)) - }) + ) .finally(() => { // cleanup delete activeDownloads[toFile]; @@ -156,9 +160,9 @@ function isCacheable(url) { function getCachedImagePath(url, options = defaultOptions) { const filePath = getCachedImageFilePath(url, options); - return RNFS.stat(filePath) + return fs.stat(filePath) .then(res => { - if (!res.isFile()) { + if (res.type !== 'file') { // reject the promise if res is not a file throw new Error('Failed to get image from cache'); } @@ -176,7 +180,7 @@ function getCachedImagePath(url, options = defaultOptions) { }) } -function cacheImage(url, options = defaultOptions, resolveHeaders) { +function cacheImage(url, options = defaultOptions, resolveHeaders = defaultResolveHeaders) { const filePath = getCachedImageFilePath(url, options); return ensurePath(filePath) .then(() => resolveHeaders()) diff --git a/README.md b/README.md index ad8f794..1a74d5f 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,17 @@ or yarn add react-native-cached-image -#### react-native-fs -_\* As noted by [@Froelund](https://github.com/Froelund) [here](https://github.com/kfiroo/react-native-cached-image/issues/15) `react-native-fs` is not maintained anymore, but its author points to `react-native-fetch-blob` as an alternative [here](https://github.com/johanneslumpe/react-native-fs#this-project-is-not-actively-maintained-consider-using-react-native-fetch-blob-as-a-replacement). I will work on replacing the modules soon_ +#### react-native-fs --> react-native-fetch-blob +_\* As noted by [@Froelund](https://github.com/Froelund) [here](https://github.com/kfiroo/react-native-cached-image/issues/15) `react-native-fs` is not maintained anymore, but its author points to `react-native-fetch-blob` as an alternative [here](https://github.com/johanneslumpe/react-native-fs#this-project-is-not-actively-maintained-consider-using-react-native-fetch-blob-as-a-replacement). -We use `react-native-fs` to handle file system access in this package and it requires an extra step during the installation. +We use [`react-native-fetch-blob`](https://github.com/wkh237/react-native-fetch-blob#installation) to handle file system access in this package and it requires an extra step during the installation. _You should only have to do this once._ - react-native link react-native-fs + react-native link react-native-fetch-blob + +Or, if you want to add Android permissions to AndroidManifest.xml automatically, use this one: + RNFB_ANDROID_PERMISSIONS=true react-native link react-native-fetch-blob ### Network Status - Android only Add the following line to your android/app/src/AndroidManifest.xml diff --git a/package.json b/package.json index 6194bfc..878bda5 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "dependencies": { "crypto-js": "3.1.9-1", "lodash": "4.17.4", - "react-native-fs": "2.1.0-rc.1", + "react-native-fetch-blob": "0.10.4", "url-parse": "1.1.7" } } diff --git a/yarn.lock b/yarn.lock index bea11df..e421ae8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,28 +2,85 @@ # yarn lockfile v1 -base-64@^0.1.0: +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +base-64@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + crypto-js@3.1.9-1: version "3.1.9-1" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.9-1.tgz#fda19e761fc077e01ffbfdc6e9fdfc59e8806cd8" +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +glob@^7.0.6: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + lodash@4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +minimatch@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + querystringify@0.0.x: version "0.0.4" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" -react-native-fs@2.1.0-rc.1: - version v2.1.0-rc.1 - resolved "https://registry.yarnpkg.com/react-native-fs/-/react-native-fs-2.1.0-rc.1.tgz#f6078891005478648738db396e822ec0aefc4b95" +react-native-fetch-blob@0.10.4: + version "0.10.4" + resolved "https://registry.yarnpkg.com/react-native-fetch-blob/-/react-native-fetch-blob-0.10.4.tgz#7e2d2096ea79dbc8da96e1915cf862f6afe2d0fd" dependencies: - base-64 "^0.1.0" - utf8 "^2.1.1" + base-64 "0.1.0" + glob "^7.0.6" requires-port@1.0.x: version "1.0.0" @@ -36,6 +93,6 @@ url-parse@1.1.7: querystringify "0.0.x" requires-port "1.0.x" -utf8@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"