react-native-fast-image 8.19.0 → 8.20.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 +2 -2
- package/dist/index.cjs.js +9 -2
- package/dist/index.cjs.js.flow +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +9 -2
- package/dist/index.js.flow +2 -0
- package/ios/FastImage/FFFastImageView.m +37 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -230,9 +230,9 @@ Called when the image starts to load.
|
|
|
230
230
|
|
|
231
231
|
### `onProgress?: (event) => void`
|
|
232
232
|
|
|
233
|
-
Called
|
|
233
|
+
Called while the image downloads, with the bytes `loaded` so far, the `total`, and `progress` (`loaded / total`, from 0 to 1; the last event has 1). Not called while the total is unknown (a response without a `Content-Length`).
|
|
234
234
|
|
|
235
|
-
e.g. `onProgress={e => console.log(e.nativeEvent.
|
|
235
|
+
e.g. `onProgress={e => console.log(e.nativeEvent.progress)}`
|
|
236
236
|
|
|
237
237
|
---
|
|
238
238
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -84,6 +84,13 @@ function loadResult(event) {
|
|
|
84
84
|
error: (_event$error = event.error) !== null && _event$error !== void 0 ? _event$error : "Failed to load the image"
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
+
function withProgress(onProgress) {
|
|
88
|
+
return onProgress && ((event) => {
|
|
89
|
+
const { loaded, total } = event.nativeEvent;
|
|
90
|
+
event.nativeEvent.progress = total > 0 ? Math.min(1, Math.max(0, loaded / total)) : 0;
|
|
91
|
+
onProgress(event);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
87
94
|
function withoutCache(source) {
|
|
88
95
|
const { cache: _cache, ...rest } = source || {};
|
|
89
96
|
return rest;
|
|
@@ -114,7 +121,7 @@ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgre
|
|
|
114
121
|
source: resolvedSource,
|
|
115
122
|
defaultSource,
|
|
116
123
|
onLoadStart,
|
|
117
|
-
onProgress,
|
|
124
|
+
onProgress: withProgress(onProgress),
|
|
118
125
|
onLoad: onLoadEnd ? (event) => {
|
|
119
126
|
const { width, height } = event.nativeEvent.source;
|
|
120
127
|
fallbackResult.current = {
|
|
@@ -155,7 +162,7 @@ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgre
|
|
|
155
162
|
source: resolvedSource,
|
|
156
163
|
defaultSource: resolvedDefaultSource,
|
|
157
164
|
onFastImageLoadStart: onLoadStart,
|
|
158
|
-
onFastImageProgress: onProgress,
|
|
165
|
+
onFastImageProgress: withProgress(onProgress),
|
|
159
166
|
onFastImageLoad: onLoad,
|
|
160
167
|
onFastImageError: onError,
|
|
161
168
|
onFastImageLoadEnd: onLoadEnd && ((event) => onLoadEnd(loadResult(event.nativeEvent))),
|
package/dist/index.cjs.js.flow
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -57,6 +57,13 @@ function loadResult(event) {
|
|
|
57
57
|
error: (_event$error = event.error) !== null && _event$error !== void 0 ? _event$error : "Failed to load the image"
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
+
function withProgress(onProgress) {
|
|
61
|
+
return onProgress && ((event) => {
|
|
62
|
+
const { loaded, total } = event.nativeEvent;
|
|
63
|
+
event.nativeEvent.progress = total > 0 ? Math.min(1, Math.max(0, loaded / total)) : 0;
|
|
64
|
+
onProgress(event);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
60
67
|
function withoutCache(source) {
|
|
61
68
|
const { cache: _cache, ...rest } = source || {};
|
|
62
69
|
return rest;
|
|
@@ -87,7 +94,7 @@ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgre
|
|
|
87
94
|
source: resolvedSource,
|
|
88
95
|
defaultSource,
|
|
89
96
|
onLoadStart,
|
|
90
|
-
onProgress,
|
|
97
|
+
onProgress: withProgress(onProgress),
|
|
91
98
|
onLoad: onLoadEnd ? (event) => {
|
|
92
99
|
const { width, height } = event.nativeEvent.source;
|
|
93
100
|
fallbackResult.current = {
|
|
@@ -128,7 +135,7 @@ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgre
|
|
|
128
135
|
source: resolvedSource,
|
|
129
136
|
defaultSource: resolvedDefaultSource,
|
|
130
137
|
onFastImageLoadStart: onLoadStart,
|
|
131
|
-
onFastImageProgress: onProgress,
|
|
138
|
+
onFastImageProgress: withProgress(onProgress),
|
|
132
139
|
onFastImageLoad: onLoad,
|
|
133
140
|
onFastImageError: onError,
|
|
134
141
|
onFastImageLoadEnd: onLoadEnd && ((event) => onLoadEnd(loadResult(event.nativeEvent))),
|
package/dist/index.js.flow
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#import <SDWebImage/UIView+WebCache.h>
|
|
4
4
|
#import <React/RCTUtils.h>
|
|
5
5
|
#import <SDWebImage/SDWebImageError.h>
|
|
6
|
+
#import <SDWebImage/SDImageTransformer.h>
|
|
6
7
|
#import "FFFDownsampledImage.h"
|
|
7
8
|
|
|
8
9
|
@interface FFFastImageView ()
|
|
@@ -58,6 +59,9 @@ static CFTimeInterval FFFEnteredBackgroundAt = 0;
|
|
|
58
59
|
self = [super init];
|
|
59
60
|
self.resizeMode = RCTResizeModeCover;
|
|
60
61
|
self.clipsToBounds = YES;
|
|
62
|
+
// The tint (tintColor) stays as it is while an alert or sheet is shown,
|
|
63
|
+
// rather than dimming like the system's controls.
|
|
64
|
+
self.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
|
|
61
65
|
_loopCount = -1;
|
|
62
66
|
return self;
|
|
63
67
|
}
|
|
@@ -197,53 +201,47 @@ static CFTimeInterval FFFEnteredBackgroundAt = 0;
|
|
|
197
201
|
// Re-apply to the untinted image, so the tint can change or be removed.
|
|
198
202
|
UIImage* image = self.untintedImage ?: super.image;
|
|
199
203
|
if (image) {
|
|
204
|
+
// SDAnimatedImageView ignores the image it already shows, which would
|
|
205
|
+
// keep an animated image's frames as they were tinted.
|
|
206
|
+
super.image = nil;
|
|
200
207
|
[self setImage: image];
|
|
201
208
|
}
|
|
202
209
|
}
|
|
203
210
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
UIImage* templateImage = [image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate];
|
|
211
|
-
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
|
|
212
|
-
UIImage* newImage;
|
|
213
|
-
if (@available(iOS 10.0, tvOS 10.0, *)) {
|
|
214
|
-
// UIGraphicsBeginImageContextWithOptions is deprecated since iOS 17.
|
|
215
|
-
// Keep the source image's scale and a standard-range (8-bit) bitmap,
|
|
216
|
-
// matching what it produced.
|
|
217
|
-
UIGraphicsImageRendererFormat* format = [[UIGraphicsImageRendererFormat alloc] init];
|
|
218
|
-
format.scale = image.scale;
|
|
219
|
-
format.opaque = NO;
|
|
220
|
-
if (@available(iOS 12.0, tvOS 12.0, *)) {
|
|
221
|
-
format.preferredRange = UIGraphicsImageRendererFormatRangeStandard;
|
|
222
|
-
} else {
|
|
223
|
-
format.prefersExtendedRange = NO;
|
|
224
|
-
}
|
|
225
|
-
UIGraphicsImageRenderer* renderer = [[UIGraphicsImageRenderer alloc] initWithSize: image.size format: format];
|
|
226
|
-
newImage = [renderer imageWithActions: ^(UIGraphicsImageRendererContext* context) {
|
|
227
|
-
[color set];
|
|
228
|
-
[templateImage drawInRect: rect];
|
|
229
|
-
}];
|
|
230
|
-
} else {
|
|
231
|
-
// iOS/tvOS 9. Remove this branch once the minimum is iOS 10+.
|
|
232
|
-
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
|
|
233
|
-
[color set];
|
|
234
|
-
[templateImage drawInRect: rect];
|
|
235
|
-
newImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
236
|
-
UIGraphicsEndImageContext();
|
|
237
|
-
}
|
|
238
|
-
return newImage;
|
|
211
|
+
// Whether SDAnimatedImageView can tint the frames of an animated image as
|
|
212
|
+
// they're decoded (animationTransformer, SDWebImage 5.20+).
|
|
213
|
+
- (BOOL) tintsFrames {
|
|
214
|
+
return [self respondsToSelector: @selector(setAnimationTransformer:)];
|
|
239
215
|
}
|
|
240
216
|
|
|
241
217
|
- (void) setImage: (UIImage*)image {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
218
|
+
// Tinted as React Native's Image does it: UIKit draws a template image in
|
|
219
|
+
// the view's tintColor, so no tinted copy of the image is made.
|
|
220
|
+
// SDAnimatedImageView draws the frames of an animated image itself,
|
|
221
|
+
// without the tint, so each frame is tinted as it's decoded (source-in,
|
|
222
|
+
// as the template is), or, before SDWebImage 5.20, the first frame shows.
|
|
223
|
+
UIColor* tint = image ? self.imageColor : nil;
|
|
224
|
+
BOOL animated = [image conformsToProtocol: @protocol(SDAnimatedImage)] && [(id<SDAnimatedImage>)image animatedImageFrameCount] > 1;
|
|
225
|
+
self.untintedImage = tint ? image : nil;
|
|
226
|
+
self.tintColor = tint;
|
|
227
|
+
if ([self tintsFrames]) {
|
|
228
|
+
[self setValue: tint && animated ? [SDImageTintTransformer transformerWithColor: tint] : nil forKey: @"animationTransformer"];
|
|
229
|
+
}
|
|
230
|
+
if (tint && animated && [self tintsFrames]) {
|
|
231
|
+
BOOL changed = super.image != image;
|
|
232
|
+
super.image = image;
|
|
233
|
+
// Shows the first frame tinted now, also while paused (the player
|
|
234
|
+
// only draws frames as it plays; until then the view draws the
|
|
235
|
+
// untinted image).
|
|
236
|
+
if (changed) {
|
|
237
|
+
[self.player seekToFrameAtIndex: 0 loopCount: 0];
|
|
238
|
+
}
|
|
239
|
+
} else if (tint) {
|
|
240
|
+
if (animated) {
|
|
241
|
+
image = [UIImage imageWithCGImage: image.CGImage scale: image.scale orientation: image.imageOrientation];
|
|
242
|
+
}
|
|
243
|
+
super.image = [image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate];
|
|
245
244
|
} else {
|
|
246
|
-
self.untintedImage = nil;
|
|
247
245
|
super.image = image;
|
|
248
246
|
}
|
|
249
247
|
[self updateContentMode];
|