Giter Site home page Giter Site logo

Comments (11)

antondomratchev avatar antondomratchev commented on July 27, 2024 2

@escobar5 @janreyho I was able to do this using ImageCache.get().on() which is what the CacheImage component uses under the covers. However I can't seem to figure out how to keep track of how many images have been downloaded or when the downloads have all been completed.
For example:

export function cacheImages(images) {
  return (dispatch) => {
    return forEachIndexed((image, index) => {
      const observer = () => {
        dispatch(updateCacheProgress(index))
        ImageCache.get().dispose({ uri: image.url }, observer)
      }
      ImageCache.get().on({ uri: image.url }, observer, true)
    }, images)
  }
}

@wcandillon I am using this in a thunked redux action creator so when the app gets a list of images, I call ImageCache.get().on() on each image. However, my on handler gets called out of index order whenever the image resource is downloaded. I was wondering if you know of a way to keep track of the images being downloaded if I wanted to show the download progress to the user.

Thanks for the awesome package and a very readable source. 👍

from react-native-img-cache.

brownieboy avatar brownieboy commented on July 27, 2024 2

@jankarres ,

Doh! Yeah, you're right. It was my calling code that was missing the rejection handling. All good now.

from react-native-img-cache.

jankarres avatar jankarres commented on July 27, 2024 1

@antondomratchev Thanks for your solution. I had the same problem as described in this issue.

The problem is that ImageCache only executes the given callback if the download was successful. The fact that the download was successful only means that the request received a positive response. The system does not take into account whether a file has been loaded.

The following workaround checks if the downloaded file contains any content and uses the state of ImageCache to determine whether the download has been aborted. This solution is useful for the moment. I sent a more sensible solution via PR.

import { ImageCache } from "react-native-img-cache";
import FetchBlob from "react-native-fetch-blob";

function preload(url: string) {
    return new Promise(function(resolve, reject) {
        // Create instance of ImageCache
        const instance = ImageCache.get();
        let finished = false;

        // Create interval to check if download has finished
        const downloadEndedIntervalId = setInterval(() => {
            if (instance.cache[url].downloading) {
                // Wait 50 ms after the download has finished to ensure that callback could be triggered
                setTimeout(() => {
                    if (!finished) { // Promise not yet resolved => download seems to be failed
                        finished = true;
                        clearInterval(downloadEndedIntervalId);

                        reject("DownloadFailed");
                    }
                }, 50);
            }
        }, 100);

        // Callback of download
        const callback = (localUrl) => {
            if (!finished) {
                finished = true;
                clearInterval(downloadEndedIntervalId);

                // Get stats of file (file exists, even if download failed, in case of a succesfull resolved request)
                FetchBlob.fs.stat(localUrl)
                    .then((stat) => {
                        // Check if downloaded file is larger then 0 bytes
                        if (stat && stat.size > 0) {
                            resolve(localUrl);
                        }
                        else { // File downloaded, but without content
                            reject("DownloadFailed");
                        }
                    });
            }
        };

        // Execute download of image
        instance.on({
            uri: url
        }, callback, true);
    });
}

If the PR has been accepted, you can use the following function where no timeouts and intervals are used. It returns the path on success and null on failure.

import { ImageCache } from "react-native-img-cache";

ImageCache.get().preload({
        uri: url
    }, (path) => {
        // Do something
    })

I wrote the code like the whole library with callbacks. For Promises, simply use the following wrappers

import { ImageCache } from "react-native-img-cache";

function preload(url: string) {
    return new Promise((resolve, reject) => {
        ImageCache.get().preload({
            uri: url
        }, (path) => {
            if (path) {
                resolve(path);
            }
            else {
                reject();
            }
        });
    });
}

from react-native-img-cache.

jankarres avatar jankarres commented on July 27, 2024 1

@piubellofelipe The PR #74 is not yet merged by @wcandillon. For this reason, the code will not work (explained above).

from react-native-img-cache.

piubellofelipe avatar piubellofelipe commented on July 27, 2024 1

ok, got it @jankarres . Thanks for the explanation :)

from react-native-img-cache.

janreyho avatar janreyho commented on July 27, 2024

+1

from react-native-img-cache.

antondomratchev avatar antondomratchev commented on July 27, 2024

@wcandillon This is a little off topic, let me know if I need to create a new issue for this. It would be a nice addition to the API if the observer handler would return both the path and the original URI on notify()

Currently the observer returns a path to the local resource which works great when used directly in CacheImage component. However when using the ImageCache observer as pre-caching mechanism it would be benefitial to also return the original URI to keep track of which images have been downloaded from the application side. I am going to implement this in a fork and would love to hear your feedback on it.

from react-native-img-cache.

Selman555 avatar Selman555 commented on July 27, 2024

There should be a consistent way to pre-cache with just the URI as well.
I have an issue with the parent container disappearing completely when the image is initially cached...

from react-native-img-cache.

piubellofelipe avatar piubellofelipe commented on July 27, 2024

@jankarres , using like your latest example. passing an invalid url actually caches an blank image :/

from react-native-img-cache.

brownieboy avatar brownieboy commented on July 27, 2024

@jankarres,

Since your PR has not been accepted, I'm using your long preload() function above. Although it works, it's throwing multiple "Possible Unhandled Promise Rejection" warnings in the react-native console. Basically, one warning for every file that I try to preload, I think.

from react-native-img-cache.

jankarres avatar jankarres commented on July 27, 2024

@brownieboy You get a promise back from the function. Do you care about catching exceptions? Without any error message I can't help you.

from react-native-img-cache.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.