react-native-fast-image 9.3.7 → 10.1.0

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.
Files changed (78) hide show
  1. package/README.md +97 -61
  2. package/RNFastImage.podspec +14 -9
  3. package/android/build.gradle +21 -47
  4. package/android/consumer-rules.pro +7 -7
  5. package/android/src/main/AndroidManifest.xml +1 -2
  6. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimatable.java +1 -1
  7. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimated.java +2 -2
  8. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageApng.java +2 -2
  9. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageBlur.java +4 -6
  10. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheControl.java +1 -1
  11. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheLimits.java +4 -1
  12. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheWrite.java +1 -1
  13. package/android/src/main/java/com/fastimage/FastImageCrop.java +92 -0
  14. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageEvent.java +2 -3
  15. package/android/src/main/java/com/fastimage/FastImageEvents.java +74 -0
  16. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGif.java +1 -1
  17. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlide.java +13 -3
  18. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlideModule.java +1 -1
  19. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageKeyedGlideUrl.java +1 -1
  20. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageOkHttpProgressGlideModule.java +49 -14
  21. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageRequestListener.java +6 -1
  22. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSharedDownloads.java +1 -1
  23. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSource.java +12 -1
  24. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSourceSize.java +12 -2
  25. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvg.java +3 -3
  26. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvgRenderer.java +1 -1
  27. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageUrl.java +1 -1
  28. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewConverter.java +24 -9
  29. package/android/src/main/java/com/fastimage/FastImageViewManager.java +591 -0
  30. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewModule.java +50 -28
  31. package/android/src/main/java/com/fastimage/FastImageViewPackage.java +51 -0
  32. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewWithUrl.java +352 -126
  33. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageWebGlideUrl.java +1 -1
  34. package/app.plugin.js +2 -7
  35. package/dist/index.cjs.js +276 -157
  36. package/dist/index.cjs.js.flow +34 -17
  37. package/dist/index.cjs.web.js +211 -61
  38. package/dist/index.cjs.web.js.flow +34 -17
  39. package/dist/index.d.ts +108 -58
  40. package/dist/index.js +278 -159
  41. package/dist/index.js.flow +34 -17
  42. package/dist/index.web.js +212 -62
  43. package/dist/index.web.js.flow +34 -17
  44. package/dist/objectFit.d.ts +2 -2
  45. package/dist/objectPosition.d.ts +42 -0
  46. package/dist/specs/FastImageViewNativeComponent.d.ts +48 -0
  47. package/dist/specs/NativeFastImageModule.d.ts +11 -0
  48. package/dist/warnings.d.ts +3 -0
  49. package/ios/FastImage/FFFDownsampledImage.h +4 -8
  50. package/ios/FastImage/FFFDownsampledImage.m +0 -34
  51. package/ios/FastImage/FFFastImageModule.h +8 -0
  52. package/ios/FastImage/{FFFastImageViewManager.m → FFFastImageModule.mm} +89 -59
  53. package/ios/FastImage/FFFastImageSource.h +4 -0
  54. package/ios/FastImage/FFFastImageSource.m +5 -1
  55. package/ios/FastImage/FFFastImageView.h +36 -7
  56. package/ios/FastImage/FFFastImageView.m +229 -172
  57. package/ios/FastImage/FFFastImageViewComponentView.h +11 -0
  58. package/ios/FastImage/FFFastImageViewComponentView.mm +325 -0
  59. package/ios/FastImage/RCTConvert+FFFastImage.h +1 -1
  60. package/ios/FastImage/RCTConvert+FFFastImage.m +9 -10
  61. package/package.json +28 -9
  62. package/src/constants.ts +28 -0
  63. package/src/index.js.flow +180 -0
  64. package/src/index.tsx +1128 -0
  65. package/src/index.web.tsx +548 -0
  66. package/src/objectFit.ts +48 -0
  67. package/src/objectPosition.ts +243 -0
  68. package/src/specs/FastImageViewNativeComponent.ts +83 -0
  69. package/src/specs/NativeFastImageModule.ts +35 -0
  70. package/src/warnings.ts +37 -0
  71. package/android/src/main/AndroidManifestNew.xml +0 -3
  72. package/android/src/main/java/com/dylanvann/fastimage/FastImageCookieHandler.java +0 -63
  73. package/android/src/main/java/com/dylanvann/fastimage/FastImageEvents.java +0 -49
  74. package/android/src/main/java/com/dylanvann/fastimage/FastImageProgressListener.java +0 -18
  75. package/android/src/main/java/com/dylanvann/fastimage/FastImageShadowNode.java +0 -21
  76. package/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java +0 -379
  77. package/android/src/main/java/com/dylanvann/fastimage/FastImageViewPackage.java +0 -27
  78. package/ios/FastImage/FFFastImageViewManager.h +0 -5
@@ -54,41 +54,7 @@ static CGSize FFFPixelSize(NSData* data) {
54
54
 
55
55
  @implementation FFFDownsampledImage
56
56
 
57
- + (BOOL) isSupported {
58
- static BOOL supported = NO;
59
- static dispatch_once_t once;
60
- dispatch_once(&once, ^{
61
- // No animated image coder takes JPEG, so before SDWebImage 5.19
62
- // SDAnimatedImage returned nil for one, and SDWebImage decoded it with
63
- // its thumbnail options as they are (stretched to the box).
64
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
65
- CGContextRef context = CGBitmapContextCreate(NULL, 1, 1, 8, 4, colorSpace, kCGImageAlphaNoneSkipLast);
66
- CGColorSpaceRelease(colorSpace);
67
- CGImageRef pixel = context ? CGBitmapContextCreateImage(context) : NULL;
68
- if (context) {
69
- CGContextRelease(context);
70
- }
71
- if (!pixel) {
72
- return;
73
- }
74
- NSMutableData* jpeg = [NSMutableData data];
75
- CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef) jpeg, CFSTR("public.jpeg"), 1, NULL);
76
- if (destination) {
77
- CGImageDestinationAddImage(destination, pixel, NULL);
78
- CGImageDestinationFinalize(destination);
79
- CFRelease(destination);
80
- }
81
- CGImageRelease(pixel);
82
- supported = jpeg.length > 0 && [[SDAnimatedImage alloc] initWithData: jpeg scale: 1 options: nil] != nil;
83
- });
84
- return supported;
85
- }
86
-
87
57
  + (void) addFullSizeToContext: (SDWebImageMutableContext*)context {
88
- if (![self isSupported]) {
89
- context[SDWebImageContextAnimatedImageClass] = [SDAnimatedImage class];
90
- return;
91
- }
92
58
  context[SDWebImageContextAnimatedImageClass] = [FFFDownsampledImage class];
93
59
  context[SDWebImageContextImageDecodeOptions] = @{FFFDecodeSourceSize: [FFFSourceSize new]};
94
60
  }
@@ -0,0 +1,8 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import <RNFastImageSpec/RNFastImageSpec.h>
3
+
4
+ // FastImage's functions (preload, getCachePath, writeToCache and the caches'
5
+ // settings): the FastImageModule TurboModule (src/specs).
6
+ @interface FFFastImageModule : NSObject <NativeFastImageModuleSpec>
7
+
8
+ @end
@@ -1,8 +1,10 @@
1
- #import "FFFastImageViewManager.h"
1
+ #import "FFFastImageModule.h"
2
+ #import "RCTConvert+FFFastImage.h"
2
3
  #import "FFFastImageView.h"
3
4
  #import "FFFDownsampledImage.h"
4
5
 
5
6
  #import <SDWebImage/SDImageCache.h>
7
+ #import <SDWebImage/SDImageCoderHelper.h>
6
8
  #import <SDWebImage/SDWebImageManager.h>
7
9
  #import <SDWebImage/SDWebImageError.h>
8
10
  #import <SDWebImage/SDWebImagePrefetcher.h>
@@ -41,8 +43,7 @@ static NSNumber *FFFCacheLimit(NSString *name)
41
43
  }
42
44
 
43
45
  // Sets a limit in SDWebImage's cache config: 0 for no limit, nil for
44
- // SDWebImage's default. maxDiskAge counts from when an image was last used
45
- // (SDWebImage's default from 5.21; before, from when it was stored).
46
+ // SDWebImage's default. maxDiskAge counts from when an image was last used.
46
47
  static void FFFSetCacheLimit(SDImageCacheConfig *config, NSString *name, NSNumber *value)
47
48
  {
48
49
  double limit = MAX(value.doubleValue, 0);
@@ -54,6 +55,8 @@ static void FFFSetCacheLimit(SDImageCacheConfig *config, NSString *name, NSNumbe
54
55
  // SDWebImage never expires images with a negative age (with 0 it
55
56
  // would remove them all).
56
57
  config.maxDiskAge = limit > 0 ? limit : -1;
58
+ // SDWebImage's default; set in case the app changed it, as FastImage
59
+ // documents maxDiskAge as counted from an image's last use.
57
60
  config.diskCacheExpireType = SDImageCacheConfigExpireTypeAccessDate;
58
61
  } else {
59
62
  config.maxDiskAge = 60 * 60 * 24 * 7;
@@ -76,50 +79,51 @@ static unsigned long long FFFFolderSize(NSString *path)
76
79
  return size;
77
80
  }
78
81
 
79
- @implementation FFFastImageViewManager
82
+ // Runs once per launch, before FastImage first uses SDWebImage's cache: from
83
+ // FFFastImageModule's +initialize (on the JS thread: React Native creates the
84
+ // app's module providers, this class among them, at the first native module JS
85
+ // asks for) or FFFastImageView's (main thread), whichever comes first;
86
+ // dispatch_once makes the other wait until the limits are set. Image loads
87
+ // don't read the limits: SDWebImage reads the disk ones when it trims the disk
88
+ // cache (on its I/O queue, when the app goes to the background or closes), and
89
+ // the memory one is its NSCache's cost limit (NSCache is thread-safe).
90
+ void FFFApplyCacheLimits(void)
91
+ {
92
+ static dispatch_once_t once;
93
+ dispatch_once(&once, ^{
94
+ SDImageCacheConfig *config = SDImageCache.sharedImageCache.config;
95
+ for (NSString *name in FFFCacheLimitNames()) {
96
+ NSNumber *value = FFFCacheLimit(name);
97
+ if (value) {
98
+ FFFSetCacheLimit(config, name, value);
99
+ }
100
+ }
101
+ });
102
+ }
80
103
 
81
- RCT_EXPORT_MODULE(FastImageView)
104
+ @implementation FFFastImageModule
82
105
 
83
- // The app's cache limits (saved or in its Info.plist), before FastImage loads
84
- // any image: this class is used first, to create the views and for preload.
106
+ // React Native finds the module through codegenConfig's ios.modulesProvider
107
+ // (in the app's RCTAppDependencyProvider), as it finds the view through
108
+ // componentProvider, so it isn't registered with RCT_EXPORT_MODULE.
109
+ + (NSString *)moduleName
110
+ {
111
+ return @"FastImageModule";
112
+ }
113
+
114
+ // The app's cache limits, before a preload (views apply them too).
85
115
  + (void)initialize
86
116
  {
87
- if (self != [FFFastImageViewManager class]) {
88
- return;
89
- }
90
- SDImageCacheConfig *config = SDImageCache.sharedImageCache.config;
91
- for (NSString *name in FFFCacheLimitNames()) {
92
- NSNumber *value = FFFCacheLimit(name);
93
- if (value) {
94
- FFFSetCacheLimit(config, name, value);
95
- }
117
+ if (self == [FFFastImageModule class]) {
118
+ FFFApplyCacheLimits();
96
119
  }
97
120
  }
98
121
 
99
- - (FFFastImageView*)view {
100
- return [[FFFastImageView alloc] init];
122
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params
123
+ {
124
+ return std::make_shared<facebook::react::NativeFastImageModuleSpecJSI>(params);
101
125
  }
102
126
 
103
- RCT_EXPORT_VIEW_PROPERTY(source, FFFastImageSource)
104
- RCT_EXPORT_VIEW_PROPERTY(sources, FFFastImageSourceArray)
105
- RCT_EXPORT_VIEW_PROPERTY(defaultSource, UIImage)
106
- RCT_EXPORT_VIEW_PROPERTY(resizeMode, FFFResizeMode)
107
- RCT_EXPORT_VIEW_PROPERTY(recyclingKey, NSString)
108
- RCT_EXPORT_VIEW_PROPERTY(loopCount, NSInteger)
109
- RCT_EXPORT_VIEW_PROPERTY(imageRendering, NSString)
110
- RCT_EXPORT_VIEW_PROPERTY(paused, BOOL)
111
- RCT_EXPORT_VIEW_PROPERTY(transitionDuration, double)
112
- RCT_EXPORT_VIEW_PROPERTY(transitionBetweenImages, BOOL)
113
- RCT_EXPORT_VIEW_PROPERTY(transitionSkipOnCacheHit, NSString)
114
- RCT_EXPORT_VIEW_PROPERTY(downsample, BOOL)
115
- RCT_EXPORT_VIEW_PROPERTY(blurRadius, CGFloat)
116
- RCT_EXPORT_VIEW_PROPERTY(trackProgress, BOOL)
117
- RCT_EXPORT_VIEW_PROPERTY(onFastImageLoadStart, RCTDirectEventBlock)
118
- RCT_EXPORT_VIEW_PROPERTY(onFastImageProgress, RCTDirectEventBlock)
119
- RCT_EXPORT_VIEW_PROPERTY(onFastImageError, RCTDirectEventBlock)
120
- RCT_EXPORT_VIEW_PROPERTY(onFastImageLoad, RCTDirectEventBlock)
121
- RCT_EXPORT_VIEW_PROPERTY(onFastImageLoadEnd, RCTDirectEventBlock)
122
- RCT_REMAP_VIEW_PROPERTY(tintColor, imageColor, UIColor)
123
127
 
124
128
  // Preloads waiting to start, in the order they were added, and the number
125
129
  // loading, across all preload calls. Like SDWebImagePrefetcher, at most
@@ -251,6 +255,10 @@ static NSDictionary *FFFFailure(NSString *error)
251
255
  return @{@"ok": @NO, @"error": error};
252
256
  }
253
257
 
258
+ // preload's, getCachePath's and writeToCache's error for a source with
259
+ // diskCache false.
260
+ static NSString *const FFFNotOnDisk = @"The source has diskCache: false, so it isn't kept on disk";
261
+
254
262
  static NSDictionary *FFFFile(NSString *path)
255
263
  {
256
264
  return @{@"ok": @YES, @"path": path};
@@ -260,11 +268,12 @@ static NSDictionary *FFFFile(NSString *path)
260
268
  // { ok, width, height } or { ok: false, error }. Never rejects. A source with
261
269
  // memoryCache false is only stored on disk, without decoding it (its size
262
270
  // comes from the header).
263
- RCT_EXPORT_METHOD(preload:(nonnull NSArray<FFFastImageSource *> *)sources
264
- resolve:(RCTPromiseResolveBlock)resolve
265
- reject:(__unused RCTPromiseRejectBlock)reject)
271
+ - (void)preload:(NSArray *)sourcesJSON
272
+ resolve:(RCTPromiseResolveBlock)resolve
273
+ reject:(__unused RCTPromiseRejectBlock)reject
266
274
  {
267
- // This runs on the UIManager queue; the queue state is only touched on
275
+ NSArray<FFFastImageSource *> *sources = [RCTConvert FFFastImageSourceArray:sourcesJSON];
276
+ // This runs on the module's queue; the queue state is only touched on
268
277
  // the main queue.
269
278
  dispatch_async(dispatch_get_main_queue(), ^{
270
279
  NSMutableArray *results = [NSMutableArray arrayWithCapacity:sources.count];
@@ -285,6 +294,13 @@ RCT_EXPORT_METHOD(preload:(nonnull NSArray<FFFastImageSource *> *)sources
285
294
  finishOne();
286
295
  return;
287
296
  }
297
+ if (!source.diskCache) {
298
+ // Views decode an image for their own size, so one only
299
+ // preloaded into memory would be downloaded again.
300
+ [results addObject:FFFFailure(FFFNotOnDisk)];
301
+ finishOne();
302
+ return;
303
+ }
288
304
  [results addObject:[NSNull null]];
289
305
  SDWebImageOptions options = FFFPreloadOptions(source);
290
306
  SDWebImageMutableContext *context = FFFPreloadContext(source);
@@ -293,7 +309,7 @@ RCT_EXPORT_METHOD(preload:(nonnull NSArray<FFFastImageSource *> *)sources
293
309
  if (!source.memoryCache) {
294
310
  // Not decoded (only its header is read, for the size), and not
295
311
  // kept in memory, also when it comes from the disk cache.
296
- options |= SDWebImageAvoidDecodeImage;
312
+ context[SDWebImageContextImageForceDecodePolicy] = @(SDImageForceDecodePolicyNever);
297
313
  context[SDWebImageContextStoreCacheType] = @(SDImageCacheTypeDisk);
298
314
  }
299
315
  FFFQueueLoad(source, options, [context copy], ^(UIImage *image, NSError *error) {
@@ -317,10 +333,15 @@ RCT_EXPORT_METHOD(preload:(nonnull NSArray<FFFastImageSource *> *)sources
317
333
  // preloads' queue): { ok, path } or { ok: false, error }. Never rejects. With
318
334
  // `cacheOnly`, or a cacheKey without a uri, it doesn't download. A local
319
335
  // file is its own path.
320
- RCT_EXPORT_METHOD(getCachePath:(FFFastImageSource *)source
321
- resolve:(RCTPromiseResolveBlock)resolve
322
- reject:(__unused RCTPromiseRejectBlock)reject)
336
+ - (void)getCachePath:(NSDictionary *)sourceJSON
337
+ resolve:(RCTPromiseResolveBlock)resolve
338
+ reject:(__unused RCTPromiseRejectBlock)reject
323
339
  {
340
+ FFFastImageSource *source = [RCTConvert FFFastImageSource:sourceJSON];
341
+ if (source && !source.diskCache) {
342
+ resolve(FFFFailure(FFFNotOnDisk));
343
+ return;
344
+ }
324
345
  if (!source.url) {
325
346
  NSString *key = FFFDiskCacheKey(source);
326
347
  if (!key) {
@@ -351,8 +372,9 @@ RCT_EXPORT_METHOD(getCachePath:(FFFastImageSource *)source
351
372
  // As a disk-only preload: not decoded, and not looked up in or kept in
352
373
  // memory (an image in memory may not be on disk). It completes once
353
374
  // the file is written.
354
- SDWebImageOptions options = FFFPreloadOptions(source) | SDWebImageAvoidDecodeImage | SDWebImageWaitStoreCache;
375
+ SDWebImageOptions options = FFFPreloadOptions(source) | SDWebImageWaitStoreCache;
355
376
  SDWebImageMutableContext *context = FFFPreloadContext(source);
377
+ context[SDWebImageContextImageForceDecodePolicy] = @(SDImageForceDecodePolicyNever);
356
378
  context[SDWebImageContextQueryCacheType] = @(SDImageCacheTypeDisk);
357
379
  context[SDWebImageContextStoreCacheType] = @(SDImageCacheTypeDisk);
358
380
  FFFQueueLoad(source, options, [context copy], ^(UIImage *image, NSError *error) {
@@ -374,11 +396,16 @@ RCT_EXPORT_METHOD(getCachePath:(FFFastImageSource *)source
374
396
  // It doesn't replace an image that's already cached (Glide can't on Android;
375
397
  // a new image should get a new cacheKey), and doesn't store `web` sources
376
398
  // (Android keeps them only in an HTTP cache).
377
- RCT_EXPORT_METHOD(writeToCache:(FFFastImageSource *)source
378
- file:(NSString *)file
379
- resolve:(RCTPromiseResolveBlock)resolve
380
- reject:(__unused RCTPromiseRejectBlock)reject)
399
+ - (void)writeToCache:(NSDictionary *)sourceJSON
400
+ file:(NSString *)file
401
+ resolve:(RCTPromiseResolveBlock)resolve
402
+ reject:(__unused RCTPromiseRejectBlock)reject
381
403
  {
404
+ FFFastImageSource *source = [RCTConvert FFFastImageSource:sourceJSON];
405
+ if (source && !source.diskCache) {
406
+ resolve(FFFFailure(FFFNotOnDisk));
407
+ return;
408
+ }
382
409
  if (source.cacheControl == FFFCacheControlWeb) {
383
410
  resolve(FFFFailure(@"Can't store cache: 'web' images (they're kept in an HTTP cache)"));
384
411
  return;
@@ -421,24 +448,27 @@ RCT_EXPORT_METHOD(writeToCache:(FFFastImageSource *)source
421
448
  }
422
449
 
423
450
  // Changes cache limits at runtime and saves them, so they're used on the next
424
- // launches too: a number (0 for no limit), or null to go back to the app's
425
- // Info.plist or SDWebImage's default. A lower disk limit applies at once (what's
451
+ // launches too: a number (0 for no limit), or its name in `reset` (null in
452
+ // JS) to go back to the app's Info.plist or SDWebImage's default. A lower disk limit applies at once (what's
426
453
  // over it is removed; the disk cache is trimmed to half of maxDiskSize when
427
454
  // it's over), instead of when the app next goes to the background. Resolves
428
455
  // with the limits in effect (0 for no limit), and diskSize: the bytes the disk
429
456
  // cache uses now.
430
- RCT_EXPORT_METHOD(configureCache:(NSDictionary *)limits
431
- resolve:(RCTPromiseResolveBlock)resolve
432
- reject:(__unused RCTPromiseRejectBlock)reject)
457
+ - (void)configureCache:(NSDictionary *)limits
458
+ resolve:(RCTPromiseResolveBlock)resolve
459
+ reject:(__unused RCTPromiseRejectBlock)reject
433
460
  {
434
461
  SDImageCache *cache = SDImageCache.sharedImageCache;
435
462
  SDImageCacheConfig *config = cache.config;
436
463
  NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults;
437
464
  NSUInteger maxDiskSize = config.maxDiskSize;
438
465
  NSTimeInterval maxDiskAge = config.maxDiskAge;
466
+ // The limits set to null in JS arrive as a list of names (a TurboModule
467
+ // leaves null values out of the dictionary).
468
+ NSArray *reset = [limits[@"reset"] isKindOfClass:NSArray.class] ? limits[@"reset"] : @[];
439
469
  for (NSString *name in FFFCacheLimitNames()) {
440
470
  id value = limits[name];
441
- if (value == (id)kCFNull) {
471
+ if ([reset containsObject:name]) {
442
472
  [defaults removeObjectForKey:FFFSavedCacheLimitKey(name)];
443
473
  } else if ([value isKindOfClass:NSNumber.class]) {
444
474
  [defaults setObject:value forKey:FFFSavedCacheLimitKey(name)];
@@ -466,13 +496,13 @@ RCT_EXPORT_METHOD(configureCache:(NSDictionary *)limits
466
496
  }
467
497
  }
468
498
 
469
- RCT_EXPORT_METHOD(clearMemoryCache:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
499
+ - (void)clearMemoryCache:(RCTPromiseResolveBlock)resolve reject:(__unused RCTPromiseRejectBlock)reject
470
500
  {
471
501
  [SDImageCache.sharedImageCache clearMemory];
472
502
  resolve(@{@"ok": @YES});
473
503
  }
474
504
 
475
- RCT_EXPORT_METHOD(clearDiskCache:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
505
+ - (void)clearDiskCache:(RCTPromiseResolveBlock)resolve reject:(__unused RCTPromiseRejectBlock)reject
476
506
  {
477
507
  // And the HTTP cache of `cache: 'web'` images.
478
508
  [FFFastImageSource.webURLCache removeAllCachedResponses];
@@ -39,6 +39,10 @@ typedef NS_ENUM(NSInteger, FFFCacheControl) {
39
39
  // default YES). Without it, it's only kept on disk: views don't leave it in
40
40
  // memory, and preload doesn't decode it.
41
41
  @property (nonatomic) BOOL memoryCache;
42
+ // Whether the image is kept in the disk cache (`diskCache`, default YES).
43
+ // Without it, it isn't read from or written to the disk cache, nor for `web`
44
+ // images the HTTP cache.
45
+ @property (nonatomic) BOOL diskCache;
42
46
 
43
47
  - (instancetype)initWithURL:(NSURL *)url
44
48
  priority:(FFFPriority)priority
@@ -346,6 +346,7 @@ static BOOL FFFLooksLikeSVG(NSData *data)
346
346
  _headers = headers;
347
347
  _cacheControl = cacheControl;
348
348
  _memoryCache = YES;
349
+ _diskCache = YES;
349
350
  }
350
351
  return self;
351
352
  }
@@ -366,7 +367,10 @@ static BOOL FFFLooksLikeSVG(NSData *data)
366
367
  {
367
368
  switch (_cacheControl) {
368
369
  case FFFCacheControlWeb:
369
- return SDWebImageRefreshCached;
370
+ // Without the disk cache, nor the HTTP cache: without this option
371
+ // SDWebImage's requests neither read it nor store their responses
372
+ // there.
373
+ return _diskCache ? SDWebImageRefreshCached : 0;
370
374
  case FFFCacheControlCacheOnly:
371
375
  return SDWebImageFromCacheOnly;
372
376
  case FFFCacheControlImmutable:
@@ -4,15 +4,19 @@
4
4
  #import <SDWebImage/SDWebImageDownloader.h>
5
5
 
6
6
  #import <React/RCTComponent.h>
7
- #import <React/RCTResizeMode.h>
8
7
 
9
8
  #import "FFFastImageSource.h"
10
9
 
11
- // resizeMode: React Native's, and `none` (objectFit="none": the image at its
12
- // own size, centered, not scaled), which React Native's own resize modes only
13
- // have from 0.77, with another meaning (top-left).
14
- typedef RCTResizeMode FFFResizeMode;
15
- static const FFFResizeMode FFFResizeModeNone = (FFFResizeMode) -2;
10
+ // objectFit, as CSS's object-fit.
11
+ typedef NS_ENUM(NSInteger, FFFObjectFit) {
12
+ FFFObjectFitCover,
13
+ FFFObjectFitContain,
14
+ FFFObjectFitFill,
15
+ // The image at its own size, or scaled down to fit if it's larger.
16
+ FFFObjectFitScaleDown,
17
+ // The image at its own size, whatever its size (cropped by the view).
18
+ FFFObjectFitNone,
19
+ };
16
20
 
17
21
  @interface FFFastImageView : SDAnimatedImageView
18
22
 
@@ -23,7 +27,7 @@ static const FFFResizeMode FFFResizeModeNone = (FFFResizeMode) -2;
23
27
  @property (nonatomic, copy) RCTDirectEventBlock onFastImageError;
24
28
  @property (nonatomic, copy) RCTDirectEventBlock onFastImageLoad;
25
29
  @property (nonatomic, copy) RCTDirectEventBlock onFastImageLoadEnd;
26
- @property (nonatomic, assign) FFFResizeMode resizeMode;
30
+ @property (nonatomic, assign) FFFObjectFit objectFit;
27
31
  @property (nonatomic, strong) FFFastImageSource *source;
28
32
  // Several sources (2 or more) of the same image at different sizes: the view
29
33
  // loads the one whose size is closest to its own.
@@ -51,10 +55,35 @@ static const FFFResizeMode FFFResizeModeNone = (FFFResizeMode) -2;
51
55
  @property (nonatomic, assign) BOOL downsample;
52
56
  // Blurs the loaded image by this radius, in points (0 is no blur).
53
57
  @property (nonatomic, assign) CGFloat blurRadius;
58
+ // objectPosition, as CSS computes it: on each axis the image's left or top
59
+ // edge is at (view - image) * fraction + offset, in points.
60
+ @property (nonatomic, assign) CGFloat objectPositionX;
61
+ @property (nonatomic, assign) CGFloat objectPositionXOffset;
62
+ @property (nonatomic, assign) CGFloat objectPositionY;
63
+ @property (nonatomic, assign) CGFloat objectPositionYOffset;
64
+
65
+ // After an update's props are set: loads the image if they changed it (once
66
+ // the view has a size, when it needs one).
67
+ - (void) didSetProps;
68
+
69
+ // Keeps the view's mask (React Native's, for its rounded corners) on the box
70
+ // the view was laid out at, while objectPosition moves the view: after React
71
+ // Native sets or removes it.
72
+ - (void) updateMask;
73
+
74
+ // Stops for good, before the view is discarded: cancels the load and sends no
75
+ // more events, also for a load that already finished and is on its way to the
76
+ // main queue.
77
+ - (void) stop;
54
78
 
55
79
  @end
56
80
 
57
81
  // An error's description, with the HTTP status code when there is one.
58
82
  FOUNDATION_EXTERN NSString *FFFErrorMessage(NSError *error);
59
83
 
84
+ // Applies the app's cache limits (saved by configureCache, or in its
85
+ // Info.plist) to SDWebImage's cache, once, before FastImage loads an image
86
+ // (in FFFastImageModule.mm).
87
+ FOUNDATION_EXTERN void FFFApplyCacheLimits(void);
88
+
60
89