react-native-fast-image 8.14.0 → 8.15.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 +12 -2
- package/android/src/main/java/com/dylanvann/fastimage/FastImageEvents.java +18 -0
- package/android/src/main/java/com/dylanvann/fastimage/FastImageRequestListener.java +4 -3
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java +3 -3
- package/dist/index.cjs.js +36 -4
- package/dist/index.cjs.js.flow +5 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +37 -5
- package/dist/index.js.flow +5 -1
- package/ios/FastImage/FFFastImageView.m +13 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -242,9 +242,19 @@ e.g. `onError={e => console.log(e.nativeEvent.error)}`
|
|
|
242
242
|
|
|
243
243
|
---
|
|
244
244
|
|
|
245
|
-
### `onLoadEnd?: () => void`
|
|
245
|
+
### `onLoadEnd?: (result) => void`
|
|
246
246
|
|
|
247
|
-
Called when the image finishes loading, whether it was successful or an error.
|
|
247
|
+
Called when the image finishes loading, whether it was successful or an error, with the result: `{ ok: true, width, height }` (the image's size, as `onLoad` gets it) or `{ ok: false, error }` (as `onError` gets it). TypeScript makes you check `ok` before reading the size or the error.
|
|
248
|
+
|
|
249
|
+
```jsx
|
|
250
|
+
<FastImage
|
|
251
|
+
source={{ uri }}
|
|
252
|
+
onLoadEnd={(result) => {
|
|
253
|
+
if (result.ok) setAspectRatio(result.width / result.height)
|
|
254
|
+
else setFailed(result.error)
|
|
255
|
+
}}
|
|
256
|
+
/>
|
|
257
|
+
```
|
|
248
258
|
|
|
249
259
|
---
|
|
250
260
|
|
|
@@ -26,6 +26,24 @@ final class FastImageEvents {
|
|
|
26
26
|
send(view, name, Arguments.createMap());
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// onLoadEnd with the load's result: ok with the image's size, as onLoad
|
|
30
|
+
// sent it.
|
|
31
|
+
static void sendLoadEnd(View view, int width, int height) {
|
|
32
|
+
WritableMap event = Arguments.createMap();
|
|
33
|
+
event.putBoolean("ok", true);
|
|
34
|
+
event.putInt("width", width);
|
|
35
|
+
event.putInt("height", height);
|
|
36
|
+
send(view, FastImageRequestListener.REACT_ON_LOAD_END_EVENT, event);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// onLoadEnd with the load's result: not ok, with the error onError sent.
|
|
40
|
+
static void sendLoadEnd(View view, String error) {
|
|
41
|
+
WritableMap event = Arguments.createMap();
|
|
42
|
+
event.putBoolean("ok", false);
|
|
43
|
+
event.putString("error", error);
|
|
44
|
+
send(view, FastImageRequestListener.REACT_ON_LOAD_END_EVENT, event);
|
|
45
|
+
}
|
|
46
|
+
|
|
29
47
|
static void send(View view, String name, WritableMap data) {
|
|
30
48
|
ReactContext context = FastImageViewManager.getReactContext(view.getContext());
|
|
31
49
|
if (context == null) return;
|
|
@@ -41,10 +41,11 @@ public class FastImageRequestListener implements RequestListener<Drawable> {
|
|
|
41
41
|
}
|
|
42
42
|
FastImageViewWithUrl view = (FastImageViewWithUrl) ((ImageViewTarget) target).getView();
|
|
43
43
|
view.onImageFailed(thumbnail);
|
|
44
|
+
String error = errorMessage(e);
|
|
44
45
|
WritableMap event = new WritableNativeMap();
|
|
45
|
-
event.putString("error",
|
|
46
|
+
event.putString("error", error);
|
|
46
47
|
FastImageEvents.send(view, REACT_ON_ERROR_EVENT, event);
|
|
47
|
-
FastImageEvents.
|
|
48
|
+
FastImageEvents.sendLoadEnd(view, error);
|
|
48
49
|
return false;
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -98,6 +99,6 @@ public class FastImageRequestListener implements RequestListener<Drawable> {
|
|
|
98
99
|
event.putInt("width", size[0]);
|
|
99
100
|
event.putInt("height", size[1]);
|
|
100
101
|
FastImageEvents.send(view, REACT_ON_LOAD_EVENT, event);
|
|
101
|
-
FastImageEvents.
|
|
102
|
+
FastImageEvents.sendLoadEnd(view, size[0], size[1]);
|
|
102
103
|
}
|
|
103
104
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package com.dylanvann.fastimage;
|
|
2
2
|
|
|
3
3
|
import static com.dylanvann.fastimage.FastImageRequestListener.REACT_ON_ERROR_EVENT;
|
|
4
|
-
import static com.dylanvann.fastimage.FastImageRequestListener.REACT_ON_LOAD_END_EVENT;
|
|
5
4
|
|
|
6
5
|
import android.annotation.SuppressLint;
|
|
7
6
|
import android.content.Context;
|
|
@@ -376,10 +375,11 @@ class FastImageViewWithUrl extends AppCompatImageView {
|
|
|
376
375
|
// resolved: fire onError and onLoadEnd and show defaultSource, as on iOS
|
|
377
376
|
// (#1028, #945).
|
|
378
377
|
if (mSource != null && (imageSource == null || imageSource.getUri().toString().length() == 0)) {
|
|
378
|
+
String error = "Invalid source: " + mSource;
|
|
379
379
|
WritableMap event = new WritableNativeMap();
|
|
380
|
-
event.putString("error",
|
|
380
|
+
event.putString("error", error);
|
|
381
381
|
FastImageEvents.send(this, REACT_ON_ERROR_EVENT, event);
|
|
382
|
-
FastImageEvents.
|
|
382
|
+
FastImageEvents.sendLoadEnd(this, error);
|
|
383
383
|
|
|
384
384
|
// Cancel existing requests.
|
|
385
385
|
clearView(requestManager);
|
package/dist/index.cjs.js
CHANGED
|
@@ -73,12 +73,24 @@ function loopCount(loop) {
|
|
|
73
73
|
if (loop === false) return 1;
|
|
74
74
|
return Number.isFinite(loop) ? Math.max(1, Math.floor(loop)) : 0;
|
|
75
75
|
}
|
|
76
|
+
function loadResult(event) {
|
|
77
|
+
var _event$width, _event$height, _event$error;
|
|
78
|
+
return event.ok ? {
|
|
79
|
+
ok: true,
|
|
80
|
+
width: (_event$width = event.width) !== null && _event$width !== void 0 ? _event$width : 0,
|
|
81
|
+
height: (_event$height = event.height) !== null && _event$height !== void 0 ? _event$height : 0
|
|
82
|
+
} : {
|
|
83
|
+
ok: false,
|
|
84
|
+
error: (_event$error = event.error) !== null && _event$error !== void 0 ? _event$error : "Failed to load the image"
|
|
85
|
+
};
|
|
86
|
+
}
|
|
76
87
|
function withoutCache(source) {
|
|
77
88
|
const { cache: _cache, ...rest } = source || {};
|
|
78
89
|
return rest;
|
|
79
90
|
}
|
|
80
91
|
function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgress, onLoad, onError, onLoadEnd, style, fallback, children, resizeMode = "cover", loop, forwardedRef, onLayout, pointerEvents, ...viewProps }) {
|
|
81
92
|
const { onClick, ...props } = viewProps;
|
|
93
|
+
const fallbackResult = (0, react.useRef)(void 0);
|
|
82
94
|
const wrapperProps = {
|
|
83
95
|
onLayout,
|
|
84
96
|
onClick,
|
|
@@ -103,9 +115,29 @@ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgre
|
|
|
103
115
|
defaultSource,
|
|
104
116
|
onLoadStart,
|
|
105
117
|
onProgress,
|
|
106
|
-
onLoad
|
|
107
|
-
|
|
108
|
-
|
|
118
|
+
onLoad: onLoadEnd ? (event) => {
|
|
119
|
+
const { width, height } = event.nativeEvent.source;
|
|
120
|
+
fallbackResult.current = {
|
|
121
|
+
ok: true,
|
|
122
|
+
width,
|
|
123
|
+
height
|
|
124
|
+
};
|
|
125
|
+
onLoad === null || onLoad === void 0 || onLoad(event);
|
|
126
|
+
} : onLoad,
|
|
127
|
+
onError: onLoadEnd ? (event) => {
|
|
128
|
+
fallbackResult.current = {
|
|
129
|
+
ok: false,
|
|
130
|
+
error: String(event.nativeEvent.error)
|
|
131
|
+
};
|
|
132
|
+
onError === null || onError === void 0 || onError(event);
|
|
133
|
+
} : onError,
|
|
134
|
+
onLoadEnd: onLoadEnd && (() => {
|
|
135
|
+
var _fallbackResult$curre;
|
|
136
|
+
return onLoadEnd((_fallbackResult$curre = fallbackResult.current) !== null && _fallbackResult$curre !== void 0 ? _fallbackResult$curre : {
|
|
137
|
+
ok: false,
|
|
138
|
+
error: "Failed to load the image"
|
|
139
|
+
});
|
|
140
|
+
}),
|
|
109
141
|
resizeMode
|
|
110
142
|
}), children);
|
|
111
143
|
}
|
|
@@ -126,7 +158,7 @@ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgre
|
|
|
126
158
|
onFastImageProgress: onProgress,
|
|
127
159
|
onFastImageLoad: onLoad,
|
|
128
160
|
onFastImageError: onError,
|
|
129
|
-
onFastImageLoadEnd: onLoadEnd,
|
|
161
|
+
onFastImageLoadEnd: onLoadEnd && ((event) => onLoadEnd(loadResult(event.nativeEvent))),
|
|
130
162
|
resizeMode
|
|
131
163
|
}), children);
|
|
132
164
|
}
|
package/dist/index.cjs.js.flow
CHANGED
|
@@ -49,6 +49,10 @@ export type ResizeModes = $Values<ResizeMode>
|
|
|
49
49
|
export type Priorities = $Values<Priority>
|
|
50
50
|
export type CacheControls = $Values<CacheControl>
|
|
51
51
|
|
|
52
|
+
export type LoadResult =
|
|
53
|
+
| {| ok: true, width: number, height: number |}
|
|
54
|
+
| {| ok: false, error: string |}
|
|
55
|
+
|
|
52
56
|
export type PreloadSuccess = {|
|
|
53
57
|
uri: string,
|
|
54
58
|
ok: true,
|
|
@@ -78,7 +82,7 @@ export type FastImageProps = $ReadOnly<{|
|
|
|
78
82
|
...ViewProps,
|
|
79
83
|
onError?: ?(event: OnErrorEvent) => void,
|
|
80
84
|
onLoad?: ?(event: OnLoadEvent) => void,
|
|
81
|
-
onLoadEnd?: ?() => void,
|
|
85
|
+
onLoadEnd?: ?(result: LoadResult) => void,
|
|
82
86
|
onLoadStart?: ?() => void,
|
|
83
87
|
onProgress?: ?(event: OnProgressEvent) => void,
|
|
84
88
|
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,14 @@ export interface OnErrorEvent {
|
|
|
40
40
|
error: string;
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
+
export type LoadResult = {
|
|
44
|
+
ok: true;
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
} | {
|
|
48
|
+
ok: false;
|
|
49
|
+
error: string;
|
|
50
|
+
};
|
|
43
51
|
export interface OnProgressEvent {
|
|
44
52
|
nativeEvent: {
|
|
45
53
|
loaded: number;
|
|
@@ -105,7 +113,11 @@ export interface FastImageProps extends AccessibilityProps, ViewProps {
|
|
|
105
113
|
onProgress?(event: OnProgressEvent): void;
|
|
106
114
|
onLoad?(event: OnLoadEvent): void;
|
|
107
115
|
onError?(event: OnErrorEvent): void;
|
|
108
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Called once the image has loaded or failed to, with the result: `ok` and
|
|
118
|
+
* the image's size, or not `ok` and the error.
|
|
119
|
+
*/
|
|
120
|
+
onLoadEnd?(result: LoadResult): void;
|
|
109
121
|
/**
|
|
110
122
|
* onLayout function
|
|
111
123
|
*
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, memo } from "react";
|
|
1
|
+
import React, { forwardRef, memo, useRef } from "react";
|
|
2
2
|
import { Image, NativeModules, Platform, StyleSheet, View, requireNativeComponent } from "react-native";
|
|
3
3
|
//#region src/index.tsx
|
|
4
4
|
const resizeMode = {
|
|
@@ -46,12 +46,24 @@ function loopCount(loop) {
|
|
|
46
46
|
if (loop === false) return 1;
|
|
47
47
|
return Number.isFinite(loop) ? Math.max(1, Math.floor(loop)) : 0;
|
|
48
48
|
}
|
|
49
|
+
function loadResult(event) {
|
|
50
|
+
var _event$width, _event$height, _event$error;
|
|
51
|
+
return event.ok ? {
|
|
52
|
+
ok: true,
|
|
53
|
+
width: (_event$width = event.width) !== null && _event$width !== void 0 ? _event$width : 0,
|
|
54
|
+
height: (_event$height = event.height) !== null && _event$height !== void 0 ? _event$height : 0
|
|
55
|
+
} : {
|
|
56
|
+
ok: false,
|
|
57
|
+
error: (_event$error = event.error) !== null && _event$error !== void 0 ? _event$error : "Failed to load the image"
|
|
58
|
+
};
|
|
59
|
+
}
|
|
49
60
|
function withoutCache(source) {
|
|
50
61
|
const { cache: _cache, ...rest } = source || {};
|
|
51
62
|
return rest;
|
|
52
63
|
}
|
|
53
64
|
function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgress, onLoad, onError, onLoadEnd, style, fallback, children, resizeMode = "cover", loop, forwardedRef, onLayout, pointerEvents, ...viewProps }) {
|
|
54
65
|
const { onClick, ...props } = viewProps;
|
|
66
|
+
const fallbackResult = useRef(void 0);
|
|
55
67
|
const wrapperProps = {
|
|
56
68
|
onLayout,
|
|
57
69
|
onClick,
|
|
@@ -76,9 +88,29 @@ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgre
|
|
|
76
88
|
defaultSource,
|
|
77
89
|
onLoadStart,
|
|
78
90
|
onProgress,
|
|
79
|
-
onLoad
|
|
80
|
-
|
|
81
|
-
|
|
91
|
+
onLoad: onLoadEnd ? (event) => {
|
|
92
|
+
const { width, height } = event.nativeEvent.source;
|
|
93
|
+
fallbackResult.current = {
|
|
94
|
+
ok: true,
|
|
95
|
+
width,
|
|
96
|
+
height
|
|
97
|
+
};
|
|
98
|
+
onLoad === null || onLoad === void 0 || onLoad(event);
|
|
99
|
+
} : onLoad,
|
|
100
|
+
onError: onLoadEnd ? (event) => {
|
|
101
|
+
fallbackResult.current = {
|
|
102
|
+
ok: false,
|
|
103
|
+
error: String(event.nativeEvent.error)
|
|
104
|
+
};
|
|
105
|
+
onError === null || onError === void 0 || onError(event);
|
|
106
|
+
} : onError,
|
|
107
|
+
onLoadEnd: onLoadEnd && (() => {
|
|
108
|
+
var _fallbackResult$curre;
|
|
109
|
+
return onLoadEnd((_fallbackResult$curre = fallbackResult.current) !== null && _fallbackResult$curre !== void 0 ? _fallbackResult$curre : {
|
|
110
|
+
ok: false,
|
|
111
|
+
error: "Failed to load the image"
|
|
112
|
+
});
|
|
113
|
+
}),
|
|
82
114
|
resizeMode
|
|
83
115
|
}), children);
|
|
84
116
|
}
|
|
@@ -99,7 +131,7 @@ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgre
|
|
|
99
131
|
onFastImageProgress: onProgress,
|
|
100
132
|
onFastImageLoad: onLoad,
|
|
101
133
|
onFastImageError: onError,
|
|
102
|
-
onFastImageLoadEnd: onLoadEnd,
|
|
134
|
+
onFastImageLoadEnd: onLoadEnd && ((event) => onLoadEnd(loadResult(event.nativeEvent))),
|
|
103
135
|
resizeMode
|
|
104
136
|
}), children);
|
|
105
137
|
}
|
package/dist/index.js.flow
CHANGED
|
@@ -49,6 +49,10 @@ export type ResizeModes = $Values<ResizeMode>
|
|
|
49
49
|
export type Priorities = $Values<Priority>
|
|
50
50
|
export type CacheControls = $Values<CacheControl>
|
|
51
51
|
|
|
52
|
+
export type LoadResult =
|
|
53
|
+
| {| ok: true, width: number, height: number |}
|
|
54
|
+
| {| ok: false, error: string |}
|
|
55
|
+
|
|
52
56
|
export type PreloadSuccess = {|
|
|
53
57
|
uri: string,
|
|
54
58
|
ok: true,
|
|
@@ -78,7 +82,7 @@ export type FastImageProps = $ReadOnly<{|
|
|
|
78
82
|
...ViewProps,
|
|
79
83
|
onError?: ?(event: OnErrorEvent) => void,
|
|
80
84
|
onLoad?: ?(event: OnLoadEvent) => void,
|
|
81
|
-
onLoadEnd?: ?() => void,
|
|
85
|
+
onLoadEnd?: ?(result: LoadResult) => void,
|
|
82
86
|
onLoadStart?: ?() => void,
|
|
83
87
|
onProgress?: ?(event: OnProgressEvent) => void,
|
|
84
88
|
|
|
@@ -161,7 +161,7 @@ static CFTimeInterval FFFEnteredBackgroundAt = 0;
|
|
|
161
161
|
- (void) setOnFastImageLoadEnd: (RCTDirectEventBlock)onFastImageLoadEnd {
|
|
162
162
|
_onFastImageLoadEnd = onFastImageLoadEnd;
|
|
163
163
|
if (self.hasCompleted && _onFastImageLoadEnd) {
|
|
164
|
-
_onFastImageLoadEnd(
|
|
164
|
+
_onFastImageLoadEnd([self loadEndEvent: YES]);
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
|
|
@@ -284,6 +284,14 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
+
// onLoadEnd's event: the load's result, as onLoad or onError sent it (ok: its
|
|
288
|
+
// size, or not ok: the error).
|
|
289
|
+
- (NSDictionary*) loadEndEvent: (BOOL)ok {
|
|
290
|
+
NSMutableDictionary* event = [NSMutableDictionary dictionaryWithDictionary: (ok ? self.onLoadEvent : self.onErrorEvent) ?: @{}];
|
|
291
|
+
event[@"ok"] = @(ok);
|
|
292
|
+
return event;
|
|
293
|
+
}
|
|
294
|
+
|
|
287
295
|
- (void) setSource: (FFFastImageSource*)source {
|
|
288
296
|
if (_source != source) {
|
|
289
297
|
_source = source;
|
|
@@ -429,7 +437,7 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
429
437
|
self.showsLoadedImage = NO;
|
|
430
438
|
[self sendOnError: @"Failed to decode the image"];
|
|
431
439
|
if (self.onFastImageLoadEnd) {
|
|
432
|
-
self.onFastImageLoadEnd(
|
|
440
|
+
self.onFastImageLoadEnd([self loadEndEvent: NO]);
|
|
433
441
|
}
|
|
434
442
|
return;
|
|
435
443
|
}
|
|
@@ -445,7 +453,7 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
445
453
|
[self sendOnLoad: image];
|
|
446
454
|
|
|
447
455
|
if (self.onFastImageLoadEnd) {
|
|
448
|
-
self.onFastImageLoadEnd(
|
|
456
|
+
self.onFastImageLoadEnd([self loadEndEvent: YES]);
|
|
449
457
|
}
|
|
450
458
|
return;
|
|
451
459
|
}
|
|
@@ -621,14 +629,14 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
621
629
|
weakSelf.showsLoadedImage = NO;
|
|
622
630
|
[weakSelf sendOnError: FFFErrorMessage(error)];
|
|
623
631
|
if (weakSelf.onFastImageLoadEnd) {
|
|
624
|
-
weakSelf.onFastImageLoadEnd(
|
|
632
|
+
weakSelf.onFastImageLoadEnd([weakSelf loadEndEvent: NO]);
|
|
625
633
|
}
|
|
626
634
|
} else {
|
|
627
635
|
weakSelf.hasCompleted = YES;
|
|
628
636
|
weakSelf.showsLoadedImage = YES;
|
|
629
637
|
[weakSelf sendOnLoad: image];
|
|
630
638
|
if (weakSelf.onFastImageLoadEnd) {
|
|
631
|
-
weakSelf.onFastImageLoadEnd(
|
|
639
|
+
weakSelf.onFastImageLoadEnd([weakSelf loadEndEvent: YES]);
|
|
632
640
|
}
|
|
633
641
|
}
|
|
634
642
|
}];
|