react-native-fast-image 9.2.0 → 9.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/android/src/main/java/com/dylanvann/fastimage/FastImageSharedDownloads.java +15 -2
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java +13 -3
- package/dist/index.d.ts +3 -1
- package/ios/FastImage/FFFastImageView.m +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,6 +76,8 @@ To set the cache's size when the app starts, see [Native config](#native-config)
|
|
|
76
76
|
|
|
77
77
|
If your Android app has its own Glide `AppGlideModule`, read [using FastImage with an AppGlideModule](docs/android-build-settings.md#if-your-app-has-its-own-appglidemodule) first, or FastImage may not work.
|
|
78
78
|
|
|
79
|
+
On iOS, FastImage works with SDWebImage 5.11.1 and later, but apps that run on iOS 26 or later need 5.21.4 or later: earlier versions can crash there while loading images ([SDWebImage#3849](https://github.com/SDWebImage/SDWebImage/issues/3849)). A new install gets the latest version. If your `Podfile.lock` has an older one, update it with `cd ios && pod update SDWebImage`.
|
|
80
|
+
|
|
79
81
|
## Usage
|
|
80
82
|
|
|
81
83
|
```jsx
|
|
@@ -529,9 +531,9 @@ for (const result of results) {
|
|
|
529
531
|
}
|
|
530
532
|
```
|
|
531
533
|
|
|
532
|
-
Each source's `cache` applies, as for a view: with `web` the preload follows the HTTP cache, and with `cacheOnly` it doesn't download. A `cacheOnly` preload resolves `ok` only if the image is cached
|
|
534
|
+
Each source's `cache` applies, as for a view: with `web` the preload follows the HTTP cache, and with `cacheOnly` it doesn't download. A `cacheOnly` preload resolves `ok` only if the image is cached.
|
|
533
535
|
|
|
534
|
-
A source with `memoryCache: false` is only downloaded to the disk cache, without being decoded into memory, and is decoded when it's shown. Use it to preload many images, or large ones, e.g. the next pages of a feed: a decoded photo can take tens of MB of memory. Other sources are
|
|
536
|
+
A source with `memoryCache: false` is only downloaded to the disk cache, without being decoded into memory, and is decoded when it's shown. Use it to preload many images, or large ones, e.g. the next pages of a feed: a decoded photo can take tens of MB of memory. Other sources are decoded too. A view showing a preloaded image loads it from the cache for its own size: it doesn't wait for the network, but it fades in as other images from the disk cache do (see `transition`'s `skipOnCacheHit`).
|
|
535
537
|
|
|
536
538
|
```js
|
|
537
539
|
await FastImage.preload(photos.map((uri) => ({ uri, memoryCache: false })))
|
|
@@ -765,7 +767,7 @@ How the image fades in: see [`transition`](#transition).
|
|
|
765
767
|
- `'all'`: skips it for images from the memory or disk cache too, so images that download fade in, and local files and bundled images usually only the first time (the disk cache usually keeps them too).
|
|
766
768
|
- `'none'`: always fades.
|
|
767
769
|
|
|
768
|
-
Downloads, local files and bundled images (`require()`) fade in.
|
|
770
|
+
Downloads, local files and bundled images (`require()`) fade in. On Android, a `cache: 'web'` image from its HTTP cache, without a request, counts as one from the memory cache (these images aren't kept there).
|
|
769
771
|
|
|
770
772
|
<!-- api:types end -->
|
|
771
773
|
|
|
@@ -370,11 +370,18 @@ final class FastImageSharedDownloads {
|
|
|
370
370
|
// A preload's file is from Glide's disk cache. A download is remote
|
|
371
371
|
// for every request reading it: Glide stores it in its disk cache once
|
|
372
372
|
// (a request that finds it there already reads it from there), and
|
|
373
|
-
// fades the image in as for any download.
|
|
373
|
+
// fades the image in as for any download. A `web` image's response
|
|
374
|
+
// from its HTTP cache, without the network, is from a disk cache too
|
|
375
|
+
// (OkHttp's; Glide doesn't store `web` images in its own).
|
|
374
376
|
@NonNull
|
|
375
377
|
@Override
|
|
376
378
|
public DataSource getDataSource() {
|
|
377
|
-
|
|
379
|
+
if (fromFile) return DataSource.DATA_DISK_CACHE;
|
|
380
|
+
Download joined;
|
|
381
|
+
synchronized (downloads) {
|
|
382
|
+
joined = download;
|
|
383
|
+
}
|
|
384
|
+
return joined != null && joined.fromHttpCache ? DataSource.DATA_DISK_CACHE : DataSource.REMOTE;
|
|
378
385
|
}
|
|
379
386
|
}
|
|
380
387
|
|
|
@@ -553,6 +560,9 @@ final class FastImageSharedDownloads {
|
|
|
553
560
|
// bytes it had received).
|
|
554
561
|
private long reserved = 0;
|
|
555
562
|
private boolean silent = false;
|
|
563
|
+
// Whether the response came from the HTTP cache of `web` images
|
|
564
|
+
// without the network (set before its bytes are read).
|
|
565
|
+
private volatile boolean fromHttpCache = false;
|
|
556
566
|
|
|
557
567
|
// With downloads locked.
|
|
558
568
|
private Download(String key, GlideUrl url, OkHttpClient client, Request request, Priority priority) {
|
|
@@ -838,6 +848,9 @@ final class FastImageSharedDownloads {
|
|
|
838
848
|
fail(new HttpException(response.message(), response.code()));
|
|
839
849
|
return;
|
|
840
850
|
}
|
|
851
|
+
// OkHttp has no network response for one it served from the
|
|
852
|
+
// cache without checking with the server.
|
|
853
|
+
fromHttpCache = response.networkResponse() == null && response.cacheResponse() != null;
|
|
841
854
|
final long length = body.contentLength();
|
|
842
855
|
synchronized (downloads) {
|
|
843
856
|
// No progress without a length.
|
|
@@ -288,14 +288,20 @@ class FastImageViewWithUrl extends AppCompatImageView implements ReactPointerEve
|
|
|
288
288
|
// Fades a loaded image in, unless it's from a cache that skipOnCacheHit
|
|
289
289
|
// skips, as Glide's and Coil's cross-fades and Fresco decide: from the
|
|
290
290
|
// memory cache it shows at once (by default), and from the disk cache
|
|
291
|
-
// too with 'all'. Downloads, local files and bundled images fade.
|
|
291
|
+
// too with 'all'. Downloads, local files and bundled images fade. A `web`
|
|
292
|
+
// image isn't kept in the memory cache, so one from its HTTP cache
|
|
293
|
+
// without the network (a disk cache hit, see FastImageSharedDownloads)
|
|
294
|
+
// counts as one from memory: shown again, e.g. in a list scrolled back
|
|
295
|
+
// up, it shows at once.
|
|
292
296
|
private final class FadeFactory implements TransitionFactory<Drawable> {
|
|
293
297
|
private final int duration;
|
|
294
298
|
private final String skipOnCacheHit;
|
|
299
|
+
private final boolean webCache;
|
|
295
300
|
|
|
296
|
-
FadeFactory(int duration, String skipOnCacheHit) {
|
|
301
|
+
FadeFactory(int duration, String skipOnCacheHit, boolean webCache) {
|
|
297
302
|
this.duration = duration;
|
|
298
303
|
this.skipOnCacheHit = skipOnCacheHit;
|
|
304
|
+
this.webCache = webCache;
|
|
299
305
|
}
|
|
300
306
|
|
|
301
307
|
@Override
|
|
@@ -314,6 +320,7 @@ class FastImageViewWithUrl extends AppCompatImageView implements ReactPointerEve
|
|
|
314
320
|
private boolean skips(DataSource dataSource) {
|
|
315
321
|
if (skipOnCacheHit.equals("none")) return false;
|
|
316
322
|
if (dataSource == DataSource.MEMORY_CACHE) return true;
|
|
323
|
+
if (webCache && dataSource == DataSource.DATA_DISK_CACHE) return true;
|
|
317
324
|
// Glide also keeps a local file's or bundled image's decoded
|
|
318
325
|
// image in its disk cache (at the size it was decoded at, and not
|
|
319
326
|
// for GIFs), so with 'all' they usually only fade the first time.
|
|
@@ -1056,7 +1063,10 @@ class FastImageViewWithUrl extends AppCompatImageView implements ReactPointerEve
|
|
|
1056
1063
|
boolean replacing = shownRequest != null && model != null;
|
|
1057
1064
|
if (mTransitionDuration > 0 && !switching && (!replacing || mTransitionBetweenImages)) {
|
|
1058
1065
|
builder = builder.transition(DrawableTransitionOptions.with(
|
|
1059
|
-
new FadeFactory(
|
|
1066
|
+
new FadeFactory(
|
|
1067
|
+
mTransitionDuration,
|
|
1068
|
+
mTransitionSkipOnCacheHit,
|
|
1069
|
+
imageSource != null && imageSource.isWebCache())));
|
|
1060
1070
|
}
|
|
1061
1071
|
if (thumbnail) {
|
|
1062
1072
|
builder = builder.thumbnail(fromCache(shownRequest));
|
package/dist/index.d.ts
CHANGED
|
@@ -122,7 +122,9 @@ export type Transition = {
|
|
|
122
122
|
* usually only the first time (the disk cache usually keeps them too).
|
|
123
123
|
* - `'none'`: always fades.
|
|
124
124
|
*
|
|
125
|
-
* Downloads, local files and bundled images (`require()`) fade in.
|
|
125
|
+
* Downloads, local files and bundled images (`require()`) fade in. On
|
|
126
|
+
* Android, a `cache: 'web'` image from its HTTP cache, without a request,
|
|
127
|
+
* counts as one from the memory cache (these images aren't kept there).
|
|
126
128
|
* @default 'memory'
|
|
127
129
|
*/
|
|
128
130
|
skipOnCacheHit?: 'none' | 'memory' | 'all' | null;
|
|
@@ -1048,6 +1048,11 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
1048
1048
|
// queue. Read and call it there, so it can't change or be released
|
|
1049
1049
|
// in between (EXC_BAD_ACCESS).
|
|
1050
1050
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1051
|
+
// Sent before the load was cancelled (the source changed) but
|
|
1052
|
+
// run after: it's not the current load's progress.
|
|
1053
|
+
if (weakSelf.loadCount != load) {
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1051
1056
|
RCTDirectEventBlock onProgress = weakSelf.onFastImageProgress;
|
|
1052
1057
|
if (onProgress) {
|
|
1053
1058
|
onProgress(@{
|