react-native-fast-image 8.9.0 → 8.10.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 CHANGED
@@ -208,9 +208,11 @@ e.g. `onLoad={e => console.log(e.nativeEvent.width, e.nativeEvent.height)}`
208
208
 
209
209
  ---
210
210
 
211
- ### `onError?: () => void`
211
+ ### `onError?: (event) => void`
212
212
 
213
- Called on an image fetching error.
213
+ Called on an image fetching error, with a message describing it (e.g. the HTTP status code).
214
+
215
+ e.g. `onError={e => console.log(e.nativeEvent.error)}`
214
216
 
215
217
  ---
216
218
 
@@ -41,11 +41,26 @@ public class FastImageRequestListener implements RequestListener<Drawable> {
41
41
  }
42
42
  FastImageViewWithUrl view = (FastImageViewWithUrl) ((ImageViewTarget) target).getView();
43
43
  view.onImageFailed(thumbnail);
44
- FastImageEvents.send(view, REACT_ON_ERROR_EVENT);
44
+ WritableMap event = new WritableNativeMap();
45
+ event.putString("error", errorMessage(e));
46
+ FastImageEvents.send(view, REACT_ON_ERROR_EVENT, event);
45
47
  FastImageEvents.send(view, REACT_ON_LOAD_END_EVENT);
46
48
  return false;
47
49
  }
48
50
 
51
+ // The first root cause's message, e.g. "Not Found, status code: 404".
52
+ // The first root cause's message, e.g. "Not Found, status code: 404" (also
53
+ // for preload results).
54
+ static String errorMessage(@androidx.annotation.Nullable GlideException e) {
55
+ if (e != null) {
56
+ for (Throwable cause : e.getRootCauses()) {
57
+ if (cause.getMessage() != null) return cause.getMessage();
58
+ }
59
+ if (e.getMessage() != null) return e.getMessage();
60
+ }
61
+ return "Failed to load the image";
62
+ }
63
+
49
64
  @Override
50
65
  public boolean onResourceReady(Drawable resource, Object model, final Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
51
66
  if (!(target instanceof ImageViewTarget)) {
@@ -122,7 +122,7 @@ class FastImageViewModule extends ReactContextBaseJavaModule {
122
122
  .listener(new RequestListener<Drawable>() {
123
123
  @Override
124
124
  public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
125
- results[index] = failure(errorMessage(e));
125
+ results[index] = failure(FastImageRequestListener.errorMessage(e));
126
126
  preloadsInFlight--;
127
127
  finishOne.run();
128
128
  startPendingPreloads();
@@ -164,17 +164,6 @@ class FastImageViewModule extends ReactContextBaseJavaModule {
164
164
  return result;
165
165
  }
166
166
 
167
- // The first root cause's message, e.g. "Not Found, status code: 404".
168
- private static String errorMessage(@Nullable GlideException e) {
169
- if (e != null) {
170
- for (Throwable cause : e.getRootCauses()) {
171
- if (cause.getMessage() != null) return cause.getMessage();
172
- }
173
- if (e.getMessage() != null) return e.getMessage();
174
- }
175
- return "Failed to load the image";
176
- }
177
-
178
167
  @ReactMethod
179
168
  public void clearMemoryCache(final Promise promise) {
180
169
  final Activity activity = getCurrentActivity();
@@ -308,7 +308,7 @@ class FastImageViewWithUrl extends AppCompatImageView {
308
308
  // (#1028, #945).
309
309
  if (mSource != null && (imageSource == null || imageSource.getUri().toString().length() == 0)) {
310
310
  WritableMap event = new WritableNativeMap();
311
- event.putString("message", "Invalid source prop:" + mSource);
311
+ event.putString("error", "Invalid source: " + mSource);
312
312
  FastImageEvents.send(this, REACT_ON_ERROR_EVENT, event);
313
313
  FastImageEvents.send(this, REACT_ON_LOAD_END_EVENT);
314
314
 
@@ -13,6 +13,12 @@ export type OnLoadEvent = SyntheticEvent<
13
13
  }>,
14
14
  >
15
15
 
16
+ export type OnErrorEvent = SyntheticEvent<
17
+ $ReadOnly<{|
18
+ error: string,
19
+ |}>,
20
+ >
21
+
16
22
  export type OnProgressEvent = SyntheticEvent<
17
23
  $ReadOnly<{|
18
24
  loaded: number,
@@ -70,7 +76,7 @@ export type FastImageSource = {
70
76
 
71
77
  export type FastImageProps = $ReadOnly<{|
72
78
  ...ViewProps,
73
- onError?: ?() => void,
79
+ onError?: ?(event: OnErrorEvent) => void,
74
80
  onLoad?: ?(event: OnLoadEvent) => void,
75
81
  onLoadEnd?: ?() => void,
76
82
  onLoadStart?: ?() => void,
package/dist/index.d.ts CHANGED
@@ -35,6 +35,11 @@ export interface OnLoadEvent {
35
35
  target?: number;
36
36
  };
37
37
  }
38
+ export interface OnErrorEvent {
39
+ nativeEvent: {
40
+ error: string;
41
+ };
42
+ }
38
43
  export interface OnProgressEvent {
39
44
  nativeEvent: {
40
45
  loaded: number;
@@ -78,7 +83,7 @@ export interface FastImageProps extends AccessibilityProps, ViewProps {
78
83
  onLoadStart?(): void;
79
84
  onProgress?(event: OnProgressEvent): void;
80
85
  onLoad?(event: OnLoadEvent): void;
81
- onError?(): void;
86
+ onError?(event: OnErrorEvent): void;
82
87
  onLoadEnd?(): void;
83
88
  /**
84
89
  * onLayout function
@@ -13,6 +13,12 @@ export type OnLoadEvent = SyntheticEvent<
13
13
  }>,
14
14
  >
15
15
 
16
+ export type OnErrorEvent = SyntheticEvent<
17
+ $ReadOnly<{|
18
+ error: string,
19
+ |}>,
20
+ >
21
+
16
22
  export type OnProgressEvent = SyntheticEvent<
17
23
  $ReadOnly<{|
18
24
  loaded: number,
@@ -70,7 +76,7 @@ export type FastImageSource = {
70
76
 
71
77
  export type FastImageProps = $ReadOnly<{|
72
78
  ...ViewProps,
73
- onError?: ?() => void,
79
+ onError?: ?(event: OnErrorEvent) => void,
74
80
  onLoad?: ?(event: OnLoadEvent) => void,
75
81
  onLoadEnd?: ?() => void,
76
82
  onLoadStart?: ?() => void,
@@ -28,3 +28,7 @@
28
28
 
29
29
  @end
30
30
 
31
+ // An error's description, with the HTTP status code when there is one.
32
+ FOUNDATION_EXTERN NSString *FFFErrorMessage(NSError *error);
33
+
34
+
@@ -2,6 +2,7 @@
2
2
  #import <SDWebImage/UIImage+MultiFormat.h>
3
3
  #import <SDWebImage/UIView+WebCache.h>
4
4
  #import <React/RCTUtils.h>
5
+ #import <SDWebImage/SDWebImageError.h>
5
6
 
6
7
  @interface FFFastImageView ()
7
8
 
@@ -12,6 +13,7 @@
12
13
  @property(nonatomic, assign) BOOL needsReload;
13
14
 
14
15
  @property(nonatomic, strong) NSDictionary* onLoadEvent;
16
+ @property(nonatomic, strong) NSDictionary* onErrorEvent;
15
17
  // The image before tinting, kept while a tint is applied so the tint can be
16
18
  // changed or removed. nil when there's no tint (super.image is untinted).
17
19
  @property(nonatomic, strong) UIImage* untintedImage;
@@ -120,7 +122,7 @@ static CFTimeInterval FFFEnteredBackgroundAt = 0;
120
122
  - (void) setOnFastImageError: (RCTDirectEventBlock)onFastImageError {
121
123
  _onFastImageError = onFastImageError;
122
124
  if (self.hasErrored && _onFastImageError) {
123
- _onFastImageError(@{});
125
+ _onFastImageError(self.onErrorEvent);
124
126
  }
125
127
  }
126
128
 
@@ -194,6 +196,26 @@ static CFTimeInterval FFFEnteredBackgroundAt = 0;
194
196
  [self updateContentMode];
195
197
  }
196
198
 
199
+ // The error's description, with the HTTP status code when there is one (as on
200
+ // Android): SDWebImage keeps the code out of the description. Also for preload
201
+ // results.
202
+ NSString *FFFErrorMessage(NSError *error)
203
+ {
204
+ NSNumber *statusCode = error.userInfo[SDWebImageErrorDownloadStatusCodeKey];
205
+ if (statusCode) {
206
+ return [NSString stringWithFormat: @"%@, status code: %@", error.localizedDescription, statusCode];
207
+ }
208
+ return error.localizedDescription ?: @"Failed to load the image";
209
+ }
210
+
211
+ - (void) sendOnError: (nullable NSString*)message {
212
+ self.hasErrored = YES;
213
+ self.onErrorEvent = @{ @"error": message ?: @"Failed to load the image" };
214
+ if (self.onFastImageError) {
215
+ self.onFastImageError(self.onErrorEvent);
216
+ }
217
+ }
218
+
197
219
  - (void) sendOnLoad: (UIImage*)image {
198
220
  self.onLoadEvent = @{
199
221
  @"width": [NSNumber numberWithDouble: image.size.width],
@@ -258,10 +280,7 @@ static CFTimeInterval FFFEnteredBackgroundAt = 0;
258
280
  // Not decodable: fail like a remote image, showing defaultSource.
259
281
  [self setImage: _defaultSource];
260
282
  self.showsLoadedImage = NO;
261
- self.hasErrored = YES;
262
- if (self.onFastImageError) {
263
- self.onFastImageError(@{});
264
- }
283
+ [self sendOnError: @"Failed to decode the image"];
265
284
  if (self.onFastImageLoadEnd) {
266
285
  self.onFastImageLoadEnd(@{});
267
286
  }
@@ -391,10 +410,7 @@ static CFTimeInterval FFFEnteredBackgroundAt = 0;
391
410
  if (error) {
392
411
  // SDWebImage shows the placeholder (defaultSource or nothing).
393
412
  weakSelf.showsLoadedImage = NO;
394
- weakSelf.hasErrored = YES;
395
- if (weakSelf.onFastImageError) {
396
- weakSelf.onFastImageError(@{});
397
- }
413
+ [weakSelf sendOnError: FFFErrorMessage(error)];
398
414
  if (weakSelf.onFastImageLoadEnd) {
399
415
  weakSelf.onFastImageLoadEnd(@{});
400
416
  }
@@ -26,16 +26,6 @@ RCT_EXPORT_VIEW_PROPERTY(onFastImageLoad, RCTDirectEventBlock)
26
26
  RCT_EXPORT_VIEW_PROPERTY(onFastImageLoadEnd, RCTDirectEventBlock)
27
27
  RCT_REMAP_VIEW_PROPERTY(tintColor, imageColor, UIColor)
28
28
 
29
- // The error's description, with the HTTP status code when there is one.
30
- static NSString *FFFErrorMessage(NSError *error)
31
- {
32
- NSNumber *statusCode = error.userInfo[SDWebImageErrorDownloadStatusCodeKey];
33
- if (statusCode) {
34
- return [NSString stringWithFormat:@"%@, status code: %@", error.localizedDescription, statusCode];
35
- }
36
- return error.localizedDescription ?: @"Failed to load the image";
37
- }
38
-
39
29
  // Preloads waiting to start, in the order they were added, and the number
40
30
  // loading, across all preload calls. Like SDWebImagePrefetcher, at most
41
31
  // maxConcurrentPrefetchCount load at a time, so a long list doesn't queue
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-fast-image",
3
- "version": "8.9.0",
3
+ "version": "8.10.0",
4
4
  "description": "🚩 FastImage, performant React Native image component.",
5
5
  "keywords": [
6
6
  "cache",