react-native-fast-image 8.16.1 → 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.
@@ -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, but
68
- // React Native's shared client has no HTTP cache (unless the app gave
69
- // it one), so those urls get a client with one (#280). Other urls are
70
- // cached by Glide, so they don't use it (that would store them twice).
71
- OkHttpClient webClient = client.cache() != null
72
- ? client
73
- : client.newBuilder()
74
- .cache(new Cache(new File(context.getCacheDir(), "fast-image-http-cache"), WEB_CACHE_SIZE))
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
  }
@@ -3,6 +3,7 @@
3
3
  #import <SDWebImage/SDWebImageDownloaderRequestModifier.h>
4
4
  #import <SDWebImage/SDWebImageCacheKeyFilter.h>
5
5
  #import <SDWebImage/SDWebImageDefine.h>
6
+ #import <SDWebImage/SDImageLoader.h>
6
7
 
7
8
  typedef NS_ENUM(NSInteger, FFFPriority) {
8
9
  FFFPriorityLow,
@@ -47,4 +48,13 @@ typedef NS_ENUM(NSInteger, FFFCacheControl) {
47
48
  // downloads. For views and preload alike.
48
49
  - (SDWebImageOptions)cacheOptions;
49
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
+
50
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
 
@@ -42,6 +47,58 @@
42
47
  return 0;
43
48
  }
44
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
+
45
102
  - (SDWebImageDownloaderRequestModifier *)requestModifier
46
103
  {
47
104
  NSDictionary* headers = _headers;
@@ -508,6 +508,7 @@ NSString *FFFErrorMessage(NSError *error)
508
508
  - (SDWebImageContext*) loadContext {
509
509
  SDWebImageMutableContext* context = [NSMutableDictionary dictionary];
510
510
  context[SDWebImageContextDownloadRequestModifier] = _source.requestModifier;
511
+ context[SDWebImageContextImageLoader] = _source.imageLoader;
511
512
  context[SDWebImageContextCacheKeyFilter] = _source.cacheKeyFilter;
512
513
  CGSize box = [self decodeBox];
513
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
  }
@@ -153,6 +154,8 @@ RCT_EXPORT_METHOD(clearMemoryCache:(RCTPromiseResolveBlock)resolve reject:(RCTPr
153
154
 
154
155
  RCT_EXPORT_METHOD(clearDiskCache:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
155
156
  {
157
+ // And the HTTP cache of `cache: 'web'` images.
158
+ [FFFastImageSource.webURLCache removeAllCachedResponses];
156
159
  [SDImageCache.sharedImageCache clearDiskOnCompletion:^(){
157
160
  resolve(NULL);
158
161
  }];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-fast-image",
3
- "version": "8.16.1",
3
+ "version": "8.16.2",
4
4
  "description": "🚩 FastImage, performant React Native image component.",
5
5
  "keywords": [
6
6
  "cache",