react-native-fast-image 8.16.0 → 8.16.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 +2 -0
- package/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java +18 -9
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewModule.java +8 -0
- package/ios/FastImage/FFFastImageSource.h +15 -0
- package/ios/FastImage/FFFastImageSource.m +70 -0
- package/ios/FastImage/FFFastImageView.m +2 -11
- package/ios/FastImage/FFFastImageViewManager.m +7 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -349,6 +349,8 @@ for (const result of results) {
|
|
|
349
349
|
}
|
|
350
350
|
```
|
|
351
351
|
|
|
352
|
+
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, and loads it from the disk cache into memory, so a view shows it at once.
|
|
353
|
+
|
|
352
354
|
### `FastImage.clearMemoryCache: () => Promise<void>`
|
|
353
355
|
|
|
354
356
|
Clear all images from memory cache.
|
package/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java
CHANGED
|
@@ -2,6 +2,7 @@ package com.dylanvann.fastimage;
|
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import androidx.annotation.NonNull;
|
|
5
|
+
import androidx.annotation.Nullable;
|
|
5
6
|
|
|
6
7
|
import com.bumptech.glide.Glide;
|
|
7
8
|
import com.bumptech.glide.Registry;
|
|
@@ -42,6 +43,15 @@ public class FastImageOkHttpProgressGlideModule extends LibraryGlideModule {
|
|
|
42
43
|
|
|
43
44
|
private static final DispatchingProgressListener progressListener = new DispatchingProgressListener();
|
|
44
45
|
private static final long WEB_CACHE_SIZE = 50 * 1024 * 1024;
|
|
46
|
+
// The HTTP cache of `cache: 'web'` images, once Glide has set up.
|
|
47
|
+
@Nullable
|
|
48
|
+
private static Cache webCache;
|
|
49
|
+
|
|
50
|
+
// Empties the HTTP cache of `cache: 'web'` images (clearDiskCache).
|
|
51
|
+
static void clearWebCache() throws IOException {
|
|
52
|
+
Cache cache = webCache;
|
|
53
|
+
if (cache != null) cache.evictAll();
|
|
54
|
+
}
|
|
45
55
|
|
|
46
56
|
@Override
|
|
47
57
|
public void registerComponents(
|
|
@@ -64,15 +74,14 @@ public class FastImageOkHttpProgressGlideModule extends LibraryGlideModule {
|
|
|
64
74
|
OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory(client);
|
|
65
75
|
registry.replace(GlideUrl.class, InputStream.class, factory);
|
|
66
76
|
|
|
67
|
-
// `cache: 'web'` skips Glide's caches and relies on HTTP caching,
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
.build();
|
|
77
|
+
// `cache: 'web'` skips Glide's caches and relies on HTTP caching, so
|
|
78
|
+
// those urls get a client with an HTTP cache (#280): one of their own,
|
|
79
|
+
// not the app's (if it gave React Native's shared client one), so
|
|
80
|
+
// clearDiskCache can empty it without the app's other responses.
|
|
81
|
+
// Other urls are cached by Glide, so they don't use it (that would
|
|
82
|
+
// store them twice).
|
|
83
|
+
webCache = new Cache(new File(context.getCacheDir(), "fast-image-http-cache"), WEB_CACHE_SIZE);
|
|
84
|
+
OkHttpClient webClient = client.newBuilder().cache(webCache).build();
|
|
76
85
|
registry.prepend(FastImageWebGlideUrl.class, InputStream.class, new WebUrlLoaderFactory(webClient));
|
|
77
86
|
}
|
|
78
87
|
|
|
@@ -24,6 +24,7 @@ import com.facebook.react.bridge.UiThreadUtil;
|
|
|
24
24
|
import com.facebook.react.bridge.WritableArray;
|
|
25
25
|
import com.facebook.react.bridge.WritableMap;
|
|
26
26
|
|
|
27
|
+
import java.io.IOException;
|
|
27
28
|
import java.util.ArrayDeque;
|
|
28
29
|
|
|
29
30
|
class FastImageViewModule extends ReactContextBaseJavaModule {
|
|
@@ -190,6 +191,13 @@ class FastImageViewModule extends ReactContextBaseJavaModule {
|
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
Glide.get(activity.getApplicationContext()).clearDiskCache();
|
|
194
|
+
// And the HTTP cache of `cache: 'web'` images, which Glide doesn't
|
|
195
|
+
// cache.
|
|
196
|
+
try {
|
|
197
|
+
FastImageOkHttpProgressGlideModule.clearWebCache();
|
|
198
|
+
} catch (IOException e) {
|
|
199
|
+
// Cleared as far as it could.
|
|
200
|
+
}
|
|
193
201
|
promise.resolve(null);
|
|
194
202
|
}
|
|
195
203
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
#import <UIKit/UIKit.h>
|
|
3
3
|
#import <SDWebImage/SDWebImageDownloaderRequestModifier.h>
|
|
4
4
|
#import <SDWebImage/SDWebImageCacheKeyFilter.h>
|
|
5
|
+
#import <SDWebImage/SDWebImageDefine.h>
|
|
6
|
+
#import <SDWebImage/SDImageLoader.h>
|
|
5
7
|
|
|
6
8
|
typedef NS_ENUM(NSInteger, FFFPriority) {
|
|
7
9
|
FFFPriorityLow,
|
|
@@ -42,4 +44,17 @@ typedef NS_ENUM(NSInteger, FFFCacheControl) {
|
|
|
42
44
|
// Caches the image under cacheKey, or nil without one.
|
|
43
45
|
- (SDWebImageCacheKeyFilter *)cacheKeyFilter;
|
|
44
46
|
|
|
47
|
+
// The load options for `cache`: web follows the HTTP cache, cacheOnly never
|
|
48
|
+
// downloads. For views and preload alike.
|
|
49
|
+
- (SDWebImageOptions)cacheOptions;
|
|
50
|
+
|
|
51
|
+
// The loader for `cache: 'web'` images, whose HTTP cache is their own (see
|
|
52
|
+
// webURLCache), or nil for SDWebImage's shared one.
|
|
53
|
+
- (id<SDImageLoader>)imageLoader;
|
|
54
|
+
|
|
55
|
+
// The HTTP cache of `cache: 'web'` images: their own rather than the app's
|
|
56
|
+
// shared NSURLCache, so clearDiskCache can empty it without the app's other
|
|
57
|
+
// responses. 50 MB, as on Android.
|
|
58
|
+
+ (NSURLCache *)webURLCache;
|
|
59
|
+
|
|
45
60
|
@end
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#import "FFFastImageSource.h"
|
|
2
|
+
#import <SDWebImage/SDWebImageDownloader.h>
|
|
3
|
+
#import <SDWebImage/SDWebImageDownloaderResponseModifier.h>
|
|
4
|
+
#import <SDWebImage/SDWebImageDownloaderDecryptor.h>
|
|
5
|
+
|
|
6
|
+
static NSUInteger const FFFWebCacheSize = 50 * 1024 * 1024;
|
|
2
7
|
|
|
3
8
|
@implementation FFFastImageSource
|
|
4
9
|
|
|
@@ -29,6 +34,71 @@
|
|
|
29
34
|
}];
|
|
30
35
|
}
|
|
31
36
|
|
|
37
|
+
- (SDWebImageOptions)cacheOptions
|
|
38
|
+
{
|
|
39
|
+
switch (_cacheControl) {
|
|
40
|
+
case FFFCacheControlWeb:
|
|
41
|
+
return SDWebImageRefreshCached;
|
|
42
|
+
case FFFCacheControlCacheOnly:
|
|
43
|
+
return SDWebImageFromCacheOnly;
|
|
44
|
+
case FFFCacheControlImmutable:
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
- (id<SDImageLoader>)imageLoader
|
|
51
|
+
{
|
|
52
|
+
if (_cacheControl != FFFCacheControlWeb) {
|
|
53
|
+
return nil;
|
|
54
|
+
}
|
|
55
|
+
static SDWebImageDownloader *downloader;
|
|
56
|
+
static dispatch_once_t once;
|
|
57
|
+
dispatch_once(&once, ^{
|
|
58
|
+
// As SDWebImage's shared downloader is set up, with the HTTP cache.
|
|
59
|
+
SDWebImageDownloaderConfig *config = [SDWebImageDownloader.sharedDownloader.config copy];
|
|
60
|
+
NSURLSessionConfiguration *session = [(config.sessionConfiguration ?: NSURLSessionConfiguration.defaultSessionConfiguration) copy];
|
|
61
|
+
session.URLCache = [FFFastImageSource webURLCache];
|
|
62
|
+
config.sessionConfiguration = session;
|
|
63
|
+
downloader = [[SDWebImageDownloader alloc] initWithConfig:config];
|
|
64
|
+
// The shared downloader's response modifier and decryptor, when it
|
|
65
|
+
// has them (as they are at each download). Its request modifier
|
|
66
|
+
// wouldn't apply anyway: each load's own (for its headers) replaces
|
|
67
|
+
// it. Headers set with setValue:forHTTPHeaderField: can't be read
|
|
68
|
+
// back, so web images don't get those.
|
|
69
|
+
downloader.responseModifier = [SDWebImageDownloaderResponseModifier responseModifierWithBlock:^NSURLResponse * _Nullable(NSURLResponse * _Nonnull response) {
|
|
70
|
+
id<SDWebImageDownloaderResponseModifier> shared = SDWebImageDownloader.sharedDownloader.responseModifier;
|
|
71
|
+
return shared ? [shared modifiedResponseWithResponse:response] : response;
|
|
72
|
+
}];
|
|
73
|
+
downloader.decryptor = [SDWebImageDownloaderDecryptor decryptorWithBlock:^NSData * _Nullable(NSData * _Nonnull data, NSURLResponse * _Nullable response) {
|
|
74
|
+
id<SDWebImageDownloaderDecryptor> shared = SDWebImageDownloader.sharedDownloader.decryptor;
|
|
75
|
+
return shared ? [shared decryptedDataWithData:data response:response] : data;
|
|
76
|
+
}];
|
|
77
|
+
});
|
|
78
|
+
return downloader;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
+ (NSURLCache *)webURLCache
|
|
82
|
+
{
|
|
83
|
+
static NSURLCache *cache;
|
|
84
|
+
static dispatch_once_t once;
|
|
85
|
+
dispatch_once(&once, ^{
|
|
86
|
+
NSString *name = @"fast-image-http-cache";
|
|
87
|
+
if (@available(iOS 13.0, tvOS 13.0, *)) {
|
|
88
|
+
NSURL *caches = [NSFileManager.defaultManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask].firstObject;
|
|
89
|
+
cache = [[NSURLCache alloc] initWithMemoryCapacity:0
|
|
90
|
+
diskCapacity:FFFWebCacheSize
|
|
91
|
+
directoryURL:[caches URLByAppendingPathComponent:name]];
|
|
92
|
+
} else {
|
|
93
|
+
// In the app's caches directory.
|
|
94
|
+
cache = [[NSURLCache alloc] initWithMemoryCapacity:0
|
|
95
|
+
diskCapacity:FFFWebCacheSize
|
|
96
|
+
diskPath:name];
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return cache;
|
|
100
|
+
}
|
|
101
|
+
|
|
32
102
|
- (SDWebImageDownloaderRequestModifier *)requestModifier
|
|
33
103
|
{
|
|
34
104
|
NSDictionary* headers = _headers;
|
|
@@ -500,17 +500,7 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
500
500
|
break;
|
|
501
501
|
}
|
|
502
502
|
|
|
503
|
-
|
|
504
|
-
case FFFCacheControlWeb:
|
|
505
|
-
options |= SDWebImageRefreshCached;
|
|
506
|
-
break;
|
|
507
|
-
case FFFCacheControlCacheOnly:
|
|
508
|
-
options |= SDWebImageFromCacheOnly;
|
|
509
|
-
break;
|
|
510
|
-
case FFFCacheControlImmutable:
|
|
511
|
-
break;
|
|
512
|
-
}
|
|
513
|
-
return options;
|
|
503
|
+
return options | [_source cacheOptions];
|
|
514
504
|
}
|
|
515
505
|
|
|
516
506
|
// Headers, and the size to decode at (see FFFDownsampledImage), which it
|
|
@@ -518,6 +508,7 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
518
508
|
- (SDWebImageContext*) loadContext {
|
|
519
509
|
SDWebImageMutableContext* context = [NSMutableDictionary dictionary];
|
|
520
510
|
context[SDWebImageContextDownloadRequestModifier] = _source.requestModifier;
|
|
511
|
+
context[SDWebImageContextImageLoader] = _source.imageLoader;
|
|
521
512
|
context[SDWebImageContextCacheKeyFilter] = _source.cacheKeyFilter;
|
|
522
513
|
CGSize box = [self decodeBox];
|
|
523
514
|
self.decodedBox = box;
|
|
@@ -42,6 +42,7 @@ static SDWebImageMutableContext *FFFPreloadContext(FFFastImageSource *source)
|
|
|
42
42
|
{
|
|
43
43
|
SDWebImageMutableContext *context = [NSMutableDictionary dictionary];
|
|
44
44
|
context[SDWebImageContextDownloadRequestModifier] = source.requestModifier;
|
|
45
|
+
context[SDWebImageContextImageLoader] = source.imageLoader;
|
|
45
46
|
context[SDWebImageContextCacheKeyFilter] = source.cacheKeyFilter;
|
|
46
47
|
return context;
|
|
47
48
|
}
|
|
@@ -89,8 +90,9 @@ RCT_EXPORT_METHOD(preload:(nonnull NSArray<FFFastImageSource *> *)sources
|
|
|
89
90
|
}
|
|
90
91
|
};
|
|
91
92
|
// With the prefetcher's options (low priority), but one source at a
|
|
92
|
-
// time (not SDWebImagePrefetcher), to get each source's result
|
|
93
|
-
// send its headers with its own request only
|
|
93
|
+
// time (not SDWebImagePrefetcher), to get each source's result, to
|
|
94
|
+
// send its headers with its own request only, and to follow its
|
|
95
|
+
// `cache` (#406).
|
|
94
96
|
SDWebImageOptions prefetcherOptions = [SDWebImagePrefetcher sharedImagePrefetcher].options;
|
|
95
97
|
|
|
96
98
|
[sources enumerateObjectsUsingBlock:^(FFFastImageSource * _Nonnull source, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
@@ -112,6 +114,7 @@ RCT_EXPORT_METHOD(preload:(nonnull NSArray<FFFastImageSource *> *)sources
|
|
|
112
114
|
options |= SDWebImageHighPriority;
|
|
113
115
|
}
|
|
114
116
|
}
|
|
117
|
+
options |= [source cacheOptions];
|
|
115
118
|
[FFFPendingPreloads addObject:[^{
|
|
116
119
|
// Once per slot: SDWebImage calls this once with finished set
|
|
117
120
|
// (a progressive load calls it more, without).
|
|
@@ -151,6 +154,8 @@ RCT_EXPORT_METHOD(clearMemoryCache:(RCTPromiseResolveBlock)resolve reject:(RCTPr
|
|
|
151
154
|
|
|
152
155
|
RCT_EXPORT_METHOD(clearDiskCache:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
|
|
153
156
|
{
|
|
157
|
+
// And the HTTP cache of `cache: 'web'` images.
|
|
158
|
+
[FFFastImageSource.webURLCache removeAllCachedResponses];
|
|
154
159
|
[SDImageCache.sharedImageCache clearDiskOnCompletion:^(){
|
|
155
160
|
resolve(NULL);
|
|
156
161
|
}];
|