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.
- package/README.md +97 -61
- package/RNFastImage.podspec +14 -9
- package/android/build.gradle +21 -47
- package/android/consumer-rules.pro +7 -7
- package/android/src/main/AndroidManifest.xml +1 -2
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimatable.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimated.java +2 -2
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageApng.java +2 -2
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageBlur.java +4 -6
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheControl.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheLimits.java +4 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheWrite.java +1 -1
- package/android/src/main/java/com/fastimage/FastImageCrop.java +92 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageEvent.java +2 -3
- package/android/src/main/java/com/fastimage/FastImageEvents.java +74 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGif.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlide.java +13 -3
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlideModule.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageKeyedGlideUrl.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageOkHttpProgressGlideModule.java +49 -14
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageRequestListener.java +6 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSharedDownloads.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSource.java +12 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSourceSize.java +12 -2
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvg.java +3 -3
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvgRenderer.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageUrl.java +1 -1
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewConverter.java +24 -9
- package/android/src/main/java/com/fastimage/FastImageViewManager.java +591 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewModule.java +50 -28
- package/android/src/main/java/com/fastimage/FastImageViewPackage.java +51 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewWithUrl.java +352 -126
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageWebGlideUrl.java +1 -1
- package/app.plugin.js +2 -7
- package/dist/index.cjs.js +276 -157
- package/dist/index.cjs.js.flow +34 -17
- package/dist/index.cjs.web.js +211 -61
- package/dist/index.cjs.web.js.flow +34 -17
- package/dist/index.d.ts +108 -58
- package/dist/index.js +278 -159
- package/dist/index.js.flow +34 -17
- package/dist/index.web.js +212 -62
- package/dist/index.web.js.flow +34 -17
- package/dist/objectFit.d.ts +2 -2
- package/dist/objectPosition.d.ts +42 -0
- package/dist/specs/FastImageViewNativeComponent.d.ts +48 -0
- package/dist/specs/NativeFastImageModule.d.ts +11 -0
- package/dist/warnings.d.ts +3 -0
- package/ios/FastImage/FFFDownsampledImage.h +4 -8
- package/ios/FastImage/FFFDownsampledImage.m +0 -34
- package/ios/FastImage/FFFastImageModule.h +8 -0
- package/ios/FastImage/{FFFastImageViewManager.m → FFFastImageModule.mm} +89 -59
- package/ios/FastImage/FFFastImageSource.h +4 -0
- package/ios/FastImage/FFFastImageSource.m +5 -1
- package/ios/FastImage/FFFastImageView.h +36 -7
- package/ios/FastImage/FFFastImageView.m +229 -172
- package/ios/FastImage/FFFastImageViewComponentView.h +11 -0
- package/ios/FastImage/FFFastImageViewComponentView.mm +325 -0
- package/ios/FastImage/RCTConvert+FFFastImage.h +1 -1
- package/ios/FastImage/RCTConvert+FFFastImage.m +9 -10
- package/package.json +28 -9
- package/src/constants.ts +28 -0
- package/src/index.js.flow +180 -0
- package/src/index.tsx +1128 -0
- package/src/index.web.tsx +548 -0
- package/src/objectFit.ts +48 -0
- package/src/objectPosition.ts +243 -0
- package/src/specs/FastImageViewNativeComponent.ts +83 -0
- package/src/specs/NativeFastImageModule.ts +35 -0
- package/src/warnings.ts +37 -0
- package/android/src/main/AndroidManifestNew.xml +0 -3
- package/android/src/main/java/com/dylanvann/fastimage/FastImageCookieHandler.java +0 -63
- package/android/src/main/java/com/dylanvann/fastimage/FastImageEvents.java +0 -49
- package/android/src/main/java/com/dylanvann/fastimage/FastImageProgressListener.java +0 -18
- package/android/src/main/java/com/dylanvann/fastimage/FastImageShadowNode.java +0 -21
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java +0 -379
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewPackage.java +0 -27
- 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 "
|
|
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
|
-
|
|
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
|
-
|
|
104
|
+
@implementation FFFastImageModule
|
|
82
105
|
|
|
83
|
-
//
|
|
84
|
-
//
|
|
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
|
|
88
|
-
|
|
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
|
-
- (
|
|
100
|
-
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
271
|
+
- (void)preload:(NSArray *)sourcesJSON
|
|
272
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
273
|
+
reject:(__unused RCTPromiseRejectBlock)reject
|
|
266
274
|
{
|
|
267
|
-
|
|
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
|
-
|
|
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
|
-
|
|
321
|
-
|
|
322
|
-
|
|
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) |
|
|
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
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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
|
|
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
|
-
|
|
431
|
-
|
|
432
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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)
|
|
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
|
|