react-native-fast-image 8.6.31 → 8.6.32
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/android/src/main/java/com/dylanvann/fastimage/FastImageShadowNode.java +21 -0
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java +13 -0
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java +9 -0
- package/dist/index.cjs.js +137 -198
- package/dist/index.d.ts +15 -16
- package/dist/index.js +112 -189
- package/package.json +18 -23
- package/dist/index.d.ts.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.dylanvann.fastimage;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.uimanager.LayoutShadowNode;
|
|
4
|
+
import com.facebook.react.uimanager.UIViewOperationQueue;
|
|
5
|
+
|
|
6
|
+
// Legacy architecture only. React Native only lays out a view when its frame
|
|
7
|
+
// changes, so a view that stays 0×0 at its parent's origin is never laid out,
|
|
8
|
+
// and Glide waits for its size forever (#865). When the computed size is zero,
|
|
9
|
+
// tell the view, so it can lay itself out and load as it does on the New
|
|
10
|
+
// Architecture. Remove with legacy architecture support.
|
|
11
|
+
public class FastImageShadowNode extends LayoutShadowNode {
|
|
12
|
+
static final Object ZERO_LAYOUT = new Object();
|
|
13
|
+
|
|
14
|
+
@Override
|
|
15
|
+
public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) {
|
|
16
|
+
super.onCollectExtraUpdates(uiViewOperationQueue);
|
|
17
|
+
if (Math.round(getLayoutWidth()) == 0 && Math.round(getLayoutHeight()) == 0) {
|
|
18
|
+
uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), ZERO_LAYOUT);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -18,6 +18,7 @@ import com.facebook.react.bridge.ReadableMap;
|
|
|
18
18
|
import com.facebook.react.bridge.WritableMap;
|
|
19
19
|
import com.facebook.react.bridge.WritableNativeMap;
|
|
20
20
|
import com.facebook.react.common.MapBuilder;
|
|
21
|
+
import com.facebook.react.uimanager.LayoutShadowNode;
|
|
21
22
|
import com.facebook.react.uimanager.SimpleViewManager;
|
|
22
23
|
import com.facebook.react.bridge.ReactContext;
|
|
23
24
|
import com.facebook.react.uimanager.ThemedReactContext;
|
|
@@ -190,6 +191,18 @@ class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> imple
|
|
|
190
191
|
|
|
191
192
|
}
|
|
192
193
|
|
|
194
|
+
// Legacy architecture only; the New Architecture doesn't use shadow nodes.
|
|
195
|
+
@NonNull
|
|
196
|
+
@Override
|
|
197
|
+
public LayoutShadowNode createShadowNodeInstance() {
|
|
198
|
+
return new FastImageShadowNode();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@Override
|
|
202
|
+
public void updateExtraData(@NonNull FastImageViewWithUrl view, Object extraData) {
|
|
203
|
+
if (extraData == FastImageShadowNode.ZERO_LAYOUT) view.onZeroLayout();
|
|
204
|
+
}
|
|
205
|
+
|
|
193
206
|
@Override
|
|
194
207
|
protected void onAfterUpdateTransaction(@NonNull FastImageViewWithUrl view) {
|
|
195
208
|
super.onAfterUpdateTransaction(view);
|
|
@@ -9,6 +9,7 @@ import android.graphics.drawable.Drawable;
|
|
|
9
9
|
|
|
10
10
|
import androidx.annotation.Nullable;
|
|
11
11
|
import androidx.appcompat.widget.AppCompatImageView;
|
|
12
|
+
import androidx.core.view.ViewCompat;
|
|
12
13
|
|
|
13
14
|
import com.bumptech.glide.RequestBuilder;
|
|
14
15
|
import com.bumptech.glide.RequestManager;
|
|
@@ -48,6 +49,14 @@ class FastImageViewWithUrl extends AppCompatImageView {
|
|
|
48
49
|
mDefaultSource = source;
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
// Legacy architecture only (see FastImageShadowNode): the view's layout is
|
|
53
|
+
// 0×0 at its parent's origin, which React Native never applies. Lay it out
|
|
54
|
+
// at that size, as the New Architecture does, so Glide stops waiting for a
|
|
55
|
+
// size and loads it (#865).
|
|
56
|
+
void onZeroLayout() {
|
|
57
|
+
if (!ViewCompat.isLaidOut(this)) layout(0, 0, 0, 0);
|
|
58
|
+
}
|
|
59
|
+
|
|
51
60
|
// Glide crops or fits the bitmap for the scale type when it loads, so a
|
|
52
61
|
// new resizeMode needs a reload to take effect (#762).
|
|
53
62
|
public void setResizeMode(ScaleType scaleType) {
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,214 +1,153 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
//#endregion
|
|
23
|
+
let react = require("react");
|
|
24
|
+
react = __toESM(react);
|
|
25
|
+
let react_native = require("react-native");
|
|
26
|
+
//#region src/index.tsx
|
|
15
27
|
const resizeMode = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
contain: "contain",
|
|
29
|
+
cover: "cover",
|
|
30
|
+
stretch: "stretch",
|
|
31
|
+
center: "center"
|
|
20
32
|
};
|
|
21
33
|
const priority = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
low: "low",
|
|
35
|
+
normal: "normal",
|
|
36
|
+
high: "high"
|
|
25
37
|
};
|
|
26
38
|
const cacheControl = {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
39
|
+
immutable: "immutable",
|
|
40
|
+
web: "web",
|
|
41
|
+
cacheOnly: "cacheOnly"
|
|
42
|
+
};
|
|
43
|
+
const resolveDefaultSource = (defaultSource) => {
|
|
44
|
+
if (!defaultSource) return null;
|
|
45
|
+
if (react_native.Platform.OS === "android") {
|
|
46
|
+
const resolved = react_native.Image.resolveAssetSource(defaultSource);
|
|
47
|
+
if (resolved) return resolved.uri;
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
return defaultSource;
|
|
33
51
|
};
|
|
34
|
-
|
|
35
|
-
const resolveDefaultSource = defaultSource => {
|
|
36
|
-
if (!defaultSource) {
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (reactNative.Platform.OS === 'android') {
|
|
41
|
-
// Android receives a URI string, and resolves into a Drawable using RN's methods.
|
|
42
|
-
const resolved = reactNative.Image.resolveAssetSource(defaultSource);
|
|
43
|
-
|
|
44
|
-
if (resolved) {
|
|
45
|
-
return resolved.uri;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return null;
|
|
49
|
-
} // iOS or other number mapped assets
|
|
50
|
-
// In iOS the number is passed, and bridged automatically into a UIImage
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return defaultSource;
|
|
54
|
-
}; // Finds tintColor in a style prop, where the last style that sets it wins, as
|
|
55
|
-
// with StyleSheet.flatten, but without flattening (which allocates a merged
|
|
56
|
-
// object for an array style on every render).
|
|
57
|
-
|
|
58
|
-
|
|
59
52
|
function tintColorFromStyle(style) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return style && typeof style === 'object' ? style.tintColor : undefined;
|
|
76
|
-
} // A copy of the source without `cache`.
|
|
77
|
-
|
|
78
|
-
|
|
53
|
+
if (Array.isArray(style)) {
|
|
54
|
+
for (let i = style.length - 1; i >= 0; i--) {
|
|
55
|
+
const found = tintColorFromStyle(style[i]);
|
|
56
|
+
if (found !== void 0) return found;
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (typeof style === "number") {
|
|
61
|
+
const flattened = react_native.StyleSheet.flatten(style);
|
|
62
|
+
return flattened ? flattened.tintColor : void 0;
|
|
63
|
+
}
|
|
64
|
+
return style && typeof style === "object" ? style.tintColor : void 0;
|
|
65
|
+
}
|
|
79
66
|
function withoutCache(source) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
...rest
|
|
83
|
-
} = source || {};
|
|
84
|
-
return rest;
|
|
67
|
+
const { cache: _cache, ...rest } = source || {};
|
|
68
|
+
return rest;
|
|
85
69
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
ref: forwardedRef
|
|
138
|
-
}), /*#__PURE__*/React__default['default'].createElement(reactNative.Image, _extends__default['default']({}, imageProps, {
|
|
139
|
-
style: [styles.fallbackImage, {
|
|
140
|
-
tintColor: resolvedTintColor
|
|
141
|
-
}],
|
|
142
|
-
source: resolvedSource,
|
|
143
|
-
defaultSource: defaultSource,
|
|
144
|
-
onLoadStart: onLoadStart,
|
|
145
|
-
onProgress: onProgress,
|
|
146
|
-
onLoad: onLoad,
|
|
147
|
-
onError: onError,
|
|
148
|
-
onLoadEnd: onLoadEnd,
|
|
149
|
-
resizeMode: resizeMode
|
|
150
|
-
})), children);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const resolvedSource = reactNative.Image.resolveAssetSource(source);
|
|
154
|
-
const resolvedDefaultSource = resolveDefaultSource(defaultSource);
|
|
155
|
-
return /*#__PURE__*/React__default['default'].createElement(reactNative.View, _extends__default['default']({
|
|
156
|
-
style: [styles.imageContainer, style]
|
|
157
|
-
}, wrapperProps, {
|
|
158
|
-
ref: forwardedRef
|
|
159
|
-
}), /*#__PURE__*/React__default['default'].createElement(FastImageView, _extends__default['default']({}, imageProps, {
|
|
160
|
-
tintColor: resolvedTintColor,
|
|
161
|
-
style: reactNative.StyleSheet.absoluteFill,
|
|
162
|
-
source: resolvedSource,
|
|
163
|
-
defaultSource: resolvedDefaultSource,
|
|
164
|
-
onFastImageLoadStart: onLoadStart,
|
|
165
|
-
onFastImageProgress: onProgress,
|
|
166
|
-
onFastImageLoad: onLoad,
|
|
167
|
-
onFastImageError: onError,
|
|
168
|
-
onFastImageLoadEnd: onLoadEnd,
|
|
169
|
-
resizeMode: resizeMode
|
|
170
|
-
})), children);
|
|
70
|
+
function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgress, onLoad, onError, onLoadEnd, style, fallback, children, resizeMode = "cover", forwardedRef, onLayout, pointerEvents, ...viewProps }) {
|
|
71
|
+
const { onClick, ...props } = viewProps;
|
|
72
|
+
const wrapperProps = {
|
|
73
|
+
onLayout,
|
|
74
|
+
onClick,
|
|
75
|
+
pointerEvents
|
|
76
|
+
};
|
|
77
|
+
const imageProps = {
|
|
78
|
+
...props,
|
|
79
|
+
pointerEvents: pointerEvents === "box-none" ? "none" : void 0
|
|
80
|
+
};
|
|
81
|
+
const resolvedTintColor = tintColor != null ? tintColor : tintColorFromStyle(style);
|
|
82
|
+
if (fallback) {
|
|
83
|
+
const cleanedSource = typeof source === "number" ? source : withoutCache(source);
|
|
84
|
+
const resolvedSource = react_native.Image.resolveAssetSource(cleanedSource);
|
|
85
|
+
return /* @__PURE__ */ react.default.createElement(react_native.View, {
|
|
86
|
+
style: [styles.imageContainer, style],
|
|
87
|
+
...wrapperProps,
|
|
88
|
+
ref: forwardedRef
|
|
89
|
+
}, /* @__PURE__ */ react.default.createElement(react_native.Image, {
|
|
90
|
+
...imageProps,
|
|
91
|
+
style: [styles.fallbackImage, { tintColor: resolvedTintColor }],
|
|
92
|
+
source: resolvedSource,
|
|
93
|
+
defaultSource,
|
|
94
|
+
onLoadStart,
|
|
95
|
+
onProgress,
|
|
96
|
+
onLoad,
|
|
97
|
+
onError,
|
|
98
|
+
onLoadEnd,
|
|
99
|
+
resizeMode
|
|
100
|
+
}), children);
|
|
101
|
+
}
|
|
102
|
+
const resolvedSource = react_native.Image.resolveAssetSource(source);
|
|
103
|
+
const resolvedDefaultSource = resolveDefaultSource(defaultSource);
|
|
104
|
+
return /* @__PURE__ */ react.default.createElement(react_native.View, {
|
|
105
|
+
style: [styles.imageContainer, style],
|
|
106
|
+
...wrapperProps,
|
|
107
|
+
ref: forwardedRef
|
|
108
|
+
}, /* @__PURE__ */ react.default.createElement(FastImageView, {
|
|
109
|
+
...imageProps,
|
|
110
|
+
tintColor: resolvedTintColor,
|
|
111
|
+
style: react_native.StyleSheet.absoluteFill,
|
|
112
|
+
source: resolvedSource,
|
|
113
|
+
defaultSource: resolvedDefaultSource,
|
|
114
|
+
onFastImageLoadStart: onLoadStart,
|
|
115
|
+
onFastImageProgress: onProgress,
|
|
116
|
+
onFastImageLoad: onLoad,
|
|
117
|
+
onFastImageError: onError,
|
|
118
|
+
onFastImageLoadEnd: onLoadEnd,
|
|
119
|
+
resizeMode
|
|
120
|
+
}), children);
|
|
171
121
|
}
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
FastImageComponent.displayName =
|
|
122
|
+
const FastImageMemo = (0, react.memo)(FastImageBase);
|
|
123
|
+
const FastImageComponent = (0, react.forwardRef)((props, ref) => /* @__PURE__ */ react.default.createElement(FastImageMemo, {
|
|
124
|
+
forwardedRef: ref,
|
|
125
|
+
...props
|
|
126
|
+
}));
|
|
127
|
+
FastImageComponent.displayName = "FastImage";
|
|
178
128
|
const FastImage = FastImageComponent;
|
|
179
129
|
FastImage.resizeMode = resizeMode;
|
|
180
130
|
FastImage.cacheControl = cacheControl;
|
|
181
131
|
FastImage.priority = priority;
|
|
182
|
-
|
|
183
|
-
FastImage.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
top: 0,
|
|
195
|
-
left: 0,
|
|
196
|
-
width: '100%',
|
|
197
|
-
height: '100%'
|
|
198
|
-
},
|
|
199
|
-
imageContainer: {
|
|
200
|
-
overflow: 'hidden'
|
|
201
|
-
}
|
|
202
|
-
}); // Types of requireNativeComponent are not correct.
|
|
203
|
-
|
|
204
|
-
const FastImageView = reactNative.requireNativeComponent('FastImageView', FastImage, {
|
|
205
|
-
nativeOnly: {
|
|
206
|
-
onFastImageLoadStart: true,
|
|
207
|
-
onFastImageProgress: true,
|
|
208
|
-
onFastImageLoad: true,
|
|
209
|
-
onFastImageError: true,
|
|
210
|
-
onFastImageLoadEnd: true
|
|
211
|
-
}
|
|
132
|
+
FastImage.preload = (sources) => react_native.NativeModules.FastImageView.preload(sources);
|
|
133
|
+
FastImage.clearMemoryCache = () => react_native.NativeModules.FastImageView.clearMemoryCache();
|
|
134
|
+
FastImage.clearDiskCache = () => react_native.NativeModules.FastImageView.clearDiskCache();
|
|
135
|
+
const styles = react_native.StyleSheet.create({
|
|
136
|
+
fallbackImage: {
|
|
137
|
+
position: "absolute",
|
|
138
|
+
top: 0,
|
|
139
|
+
left: 0,
|
|
140
|
+
width: "100%",
|
|
141
|
+
height: "100%"
|
|
142
|
+
},
|
|
143
|
+
imageContainer: { overflow: "hidden" }
|
|
212
144
|
});
|
|
213
|
-
|
|
145
|
+
const FastImageView = (0, react_native.requireNativeComponent)("FastImageView", FastImage, { nativeOnly: {
|
|
146
|
+
onFastImageLoadStart: true,
|
|
147
|
+
onFastImageProgress: true,
|
|
148
|
+
onFastImageLoad: true,
|
|
149
|
+
onFastImageError: true,
|
|
150
|
+
onFastImageLoadEnd: true
|
|
151
|
+
} });
|
|
152
|
+
//#endregion
|
|
214
153
|
module.exports = FastImage;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { LayoutChangeEvent, StyleProp, ViewStyle, ImageRequireSource, AccessibilityProps, ViewProps } from 'react-native';
|
|
3
|
-
|
|
4
|
-
export
|
|
3
|
+
type ColorValue = NonNullable<ViewStyle['backgroundColor']>;
|
|
4
|
+
export type ResizeMode = 'contain' | 'cover' | 'stretch' | 'center';
|
|
5
5
|
declare const resizeMode: {
|
|
6
|
-
readonly contain:
|
|
7
|
-
readonly cover:
|
|
8
|
-
readonly stretch:
|
|
9
|
-
readonly center:
|
|
6
|
+
readonly contain: 'contain';
|
|
7
|
+
readonly cover: 'cover';
|
|
8
|
+
readonly stretch: 'stretch';
|
|
9
|
+
readonly center: 'center';
|
|
10
10
|
};
|
|
11
|
-
export
|
|
11
|
+
export type Priority = 'low' | 'normal' | 'high';
|
|
12
12
|
declare const priority: {
|
|
13
|
-
readonly low:
|
|
14
|
-
readonly normal:
|
|
15
|
-
readonly high:
|
|
13
|
+
readonly low: 'low';
|
|
14
|
+
readonly normal: 'normal';
|
|
15
|
+
readonly high: 'high';
|
|
16
16
|
};
|
|
17
|
-
export
|
|
17
|
+
export type Cache = 'immutable' | 'web' | 'cacheOnly';
|
|
18
18
|
declare const cacheControl: {
|
|
19
|
-
readonly immutable:
|
|
20
|
-
readonly web:
|
|
21
|
-
readonly cacheOnly:
|
|
19
|
+
readonly immutable: 'immutable';
|
|
20
|
+
readonly web: 'web';
|
|
21
|
+
readonly cacheOnly: 'cacheOnly';
|
|
22
22
|
};
|
|
23
|
-
export
|
|
23
|
+
export type Source = {
|
|
24
24
|
uri?: string;
|
|
25
25
|
headers?: {
|
|
26
26
|
[key: string]: string;
|
|
@@ -103,4 +103,3 @@ export interface FastImageStaticProperties {
|
|
|
103
103
|
}
|
|
104
104
|
declare const FastImage: React.ComponentType<FastImageProps> & FastImageStaticProperties;
|
|
105
105
|
export default FastImage;
|
|
106
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,207 +1,130 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// from ViewStyle so the types also work with older React Native types, where
|
|
6
|
-
// it's string.
|
|
7
|
-
|
|
1
|
+
import React, { forwardRef, memo } from "react";
|
|
2
|
+
import { Image, NativeModules, Platform, StyleSheet, View, requireNativeComponent } from "react-native";
|
|
3
|
+
//#region src/index.tsx
|
|
8
4
|
const resizeMode = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
contain: "contain",
|
|
6
|
+
cover: "cover",
|
|
7
|
+
stretch: "stretch",
|
|
8
|
+
center: "center"
|
|
13
9
|
};
|
|
14
10
|
const priority = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
low: "low",
|
|
12
|
+
normal: "normal",
|
|
13
|
+
high: "high"
|
|
18
14
|
};
|
|
19
15
|
const cacheControl = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
immutable: "immutable",
|
|
17
|
+
web: "web",
|
|
18
|
+
cacheOnly: "cacheOnly"
|
|
19
|
+
};
|
|
20
|
+
const resolveDefaultSource = (defaultSource) => {
|
|
21
|
+
if (!defaultSource) return null;
|
|
22
|
+
if (Platform.OS === "android") {
|
|
23
|
+
const resolved = Image.resolveAssetSource(defaultSource);
|
|
24
|
+
if (resolved) return resolved.uri;
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return defaultSource;
|
|
26
28
|
};
|
|
27
|
-
|
|
28
|
-
const resolveDefaultSource = defaultSource => {
|
|
29
|
-
if (!defaultSource) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (Platform.OS === 'android') {
|
|
34
|
-
// Android receives a URI string, and resolves into a Drawable using RN's methods.
|
|
35
|
-
const resolved = Image.resolveAssetSource(defaultSource);
|
|
36
|
-
|
|
37
|
-
if (resolved) {
|
|
38
|
-
return resolved.uri;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return null;
|
|
42
|
-
} // iOS or other number mapped assets
|
|
43
|
-
// In iOS the number is passed, and bridged automatically into a UIImage
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return defaultSource;
|
|
47
|
-
}; // Finds tintColor in a style prop, where the last style that sets it wins, as
|
|
48
|
-
// with StyleSheet.flatten, but without flattening (which allocates a merged
|
|
49
|
-
// object for an array style on every render).
|
|
50
|
-
|
|
51
|
-
|
|
52
29
|
function tintColorFromStyle(style) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return style && typeof style === 'object' ? style.tintColor : undefined;
|
|
69
|
-
} // A copy of the source without `cache`.
|
|
70
|
-
|
|
71
|
-
|
|
30
|
+
if (Array.isArray(style)) {
|
|
31
|
+
for (let i = style.length - 1; i >= 0; i--) {
|
|
32
|
+
const found = tintColorFromStyle(style[i]);
|
|
33
|
+
if (found !== void 0) return found;
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (typeof style === "number") {
|
|
38
|
+
const flattened = StyleSheet.flatten(style);
|
|
39
|
+
return flattened ? flattened.tintColor : void 0;
|
|
40
|
+
}
|
|
41
|
+
return style && typeof style === "object" ? style.tintColor : void 0;
|
|
42
|
+
}
|
|
72
43
|
function withoutCache(source) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
...rest
|
|
76
|
-
} = source || {};
|
|
77
|
-
return rest;
|
|
44
|
+
const { cache: _cache, ...rest } = source || {};
|
|
45
|
+
return rest;
|
|
78
46
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
ref: forwardedRef
|
|
131
|
-
}), /*#__PURE__*/React.createElement(Image, _extends({}, imageProps, {
|
|
132
|
-
style: [styles.fallbackImage, {
|
|
133
|
-
tintColor: resolvedTintColor
|
|
134
|
-
}],
|
|
135
|
-
source: resolvedSource,
|
|
136
|
-
defaultSource: defaultSource,
|
|
137
|
-
onLoadStart: onLoadStart,
|
|
138
|
-
onProgress: onProgress,
|
|
139
|
-
onLoad: onLoad,
|
|
140
|
-
onError: onError,
|
|
141
|
-
onLoadEnd: onLoadEnd,
|
|
142
|
-
resizeMode: resizeMode
|
|
143
|
-
})), children);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const resolvedSource = Image.resolveAssetSource(source);
|
|
147
|
-
const resolvedDefaultSource = resolveDefaultSource(defaultSource);
|
|
148
|
-
return /*#__PURE__*/React.createElement(View, _extends({
|
|
149
|
-
style: [styles.imageContainer, style]
|
|
150
|
-
}, wrapperProps, {
|
|
151
|
-
ref: forwardedRef
|
|
152
|
-
}), /*#__PURE__*/React.createElement(FastImageView, _extends({}, imageProps, {
|
|
153
|
-
tintColor: resolvedTintColor,
|
|
154
|
-
style: StyleSheet.absoluteFill,
|
|
155
|
-
source: resolvedSource,
|
|
156
|
-
defaultSource: resolvedDefaultSource,
|
|
157
|
-
onFastImageLoadStart: onLoadStart,
|
|
158
|
-
onFastImageProgress: onProgress,
|
|
159
|
-
onFastImageLoad: onLoad,
|
|
160
|
-
onFastImageError: onError,
|
|
161
|
-
onFastImageLoadEnd: onLoadEnd,
|
|
162
|
-
resizeMode: resizeMode
|
|
163
|
-
})), children);
|
|
47
|
+
function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgress, onLoad, onError, onLoadEnd, style, fallback, children, resizeMode = "cover", forwardedRef, onLayout, pointerEvents, ...viewProps }) {
|
|
48
|
+
const { onClick, ...props } = viewProps;
|
|
49
|
+
const wrapperProps = {
|
|
50
|
+
onLayout,
|
|
51
|
+
onClick,
|
|
52
|
+
pointerEvents
|
|
53
|
+
};
|
|
54
|
+
const imageProps = {
|
|
55
|
+
...props,
|
|
56
|
+
pointerEvents: pointerEvents === "box-none" ? "none" : void 0
|
|
57
|
+
};
|
|
58
|
+
const resolvedTintColor = tintColor != null ? tintColor : tintColorFromStyle(style);
|
|
59
|
+
if (fallback) {
|
|
60
|
+
const cleanedSource = typeof source === "number" ? source : withoutCache(source);
|
|
61
|
+
const resolvedSource = Image.resolveAssetSource(cleanedSource);
|
|
62
|
+
return /* @__PURE__ */ React.createElement(View, {
|
|
63
|
+
style: [styles.imageContainer, style],
|
|
64
|
+
...wrapperProps,
|
|
65
|
+
ref: forwardedRef
|
|
66
|
+
}, /* @__PURE__ */ React.createElement(Image, {
|
|
67
|
+
...imageProps,
|
|
68
|
+
style: [styles.fallbackImage, { tintColor: resolvedTintColor }],
|
|
69
|
+
source: resolvedSource,
|
|
70
|
+
defaultSource,
|
|
71
|
+
onLoadStart,
|
|
72
|
+
onProgress,
|
|
73
|
+
onLoad,
|
|
74
|
+
onError,
|
|
75
|
+
onLoadEnd,
|
|
76
|
+
resizeMode
|
|
77
|
+
}), children);
|
|
78
|
+
}
|
|
79
|
+
const resolvedSource = Image.resolveAssetSource(source);
|
|
80
|
+
const resolvedDefaultSource = resolveDefaultSource(defaultSource);
|
|
81
|
+
return /* @__PURE__ */ React.createElement(View, {
|
|
82
|
+
style: [styles.imageContainer, style],
|
|
83
|
+
...wrapperProps,
|
|
84
|
+
ref: forwardedRef
|
|
85
|
+
}, /* @__PURE__ */ React.createElement(FastImageView, {
|
|
86
|
+
...imageProps,
|
|
87
|
+
tintColor: resolvedTintColor,
|
|
88
|
+
style: StyleSheet.absoluteFill,
|
|
89
|
+
source: resolvedSource,
|
|
90
|
+
defaultSource: resolvedDefaultSource,
|
|
91
|
+
onFastImageLoadStart: onLoadStart,
|
|
92
|
+
onFastImageProgress: onProgress,
|
|
93
|
+
onFastImageLoad: onLoad,
|
|
94
|
+
onFastImageError: onError,
|
|
95
|
+
onFastImageLoadEnd: onLoadEnd,
|
|
96
|
+
resizeMode
|
|
97
|
+
}), children);
|
|
164
98
|
}
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
FastImageComponent.displayName =
|
|
99
|
+
const FastImageMemo = memo(FastImageBase);
|
|
100
|
+
const FastImageComponent = forwardRef((props, ref) => /* @__PURE__ */ React.createElement(FastImageMemo, {
|
|
101
|
+
forwardedRef: ref,
|
|
102
|
+
...props
|
|
103
|
+
}));
|
|
104
|
+
FastImageComponent.displayName = "FastImage";
|
|
171
105
|
const FastImage = FastImageComponent;
|
|
172
106
|
FastImage.resizeMode = resizeMode;
|
|
173
107
|
FastImage.cacheControl = cacheControl;
|
|
174
108
|
FastImage.priority = priority;
|
|
175
|
-
|
|
176
|
-
FastImage.preload = sources => NativeModules.FastImageView.preload(sources);
|
|
177
|
-
|
|
109
|
+
FastImage.preload = (sources) => NativeModules.FastImageView.preload(sources);
|
|
178
110
|
FastImage.clearMemoryCache = () => NativeModules.FastImageView.clearMemoryCache();
|
|
179
|
-
|
|
180
111
|
FastImage.clearDiskCache = () => NativeModules.FastImageView.clearDiskCache();
|
|
181
|
-
|
|
182
112
|
const styles = StyleSheet.create({
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
},
|
|
192
|
-
imageContainer: {
|
|
193
|
-
overflow: 'hidden'
|
|
194
|
-
}
|
|
195
|
-
}); // Types of requireNativeComponent are not correct.
|
|
196
|
-
|
|
197
|
-
const FastImageView = requireNativeComponent('FastImageView', FastImage, {
|
|
198
|
-
nativeOnly: {
|
|
199
|
-
onFastImageLoadStart: true,
|
|
200
|
-
onFastImageProgress: true,
|
|
201
|
-
onFastImageLoad: true,
|
|
202
|
-
onFastImageError: true,
|
|
203
|
-
onFastImageLoadEnd: true
|
|
204
|
-
}
|
|
113
|
+
fallbackImage: {
|
|
114
|
+
position: "absolute",
|
|
115
|
+
top: 0,
|
|
116
|
+
left: 0,
|
|
117
|
+
width: "100%",
|
|
118
|
+
height: "100%"
|
|
119
|
+
},
|
|
120
|
+
imageContainer: { overflow: "hidden" }
|
|
205
121
|
});
|
|
206
|
-
|
|
207
|
-
|
|
122
|
+
const FastImageView = requireNativeComponent("FastImageView", FastImage, { nativeOnly: {
|
|
123
|
+
onFastImageLoadStart: true,
|
|
124
|
+
onFastImageProgress: true,
|
|
125
|
+
onFastImageLoad: true,
|
|
126
|
+
onFastImageError: true,
|
|
127
|
+
onFastImageLoadEnd: true
|
|
128
|
+
} });
|
|
129
|
+
//#endregion
|
|
130
|
+
export { FastImage as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-fast-image",
|
|
3
|
-
"version": "8.6.
|
|
3
|
+
"version": "8.6.32",
|
|
4
4
|
"description": "🚩 FastImage, performant React Native image component.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cache",
|
|
@@ -23,48 +23,43 @@
|
|
|
23
23
|
"module": "dist/index.js",
|
|
24
24
|
"typings": "dist/index.d.ts",
|
|
25
25
|
"files": [
|
|
26
|
-
"android",
|
|
27
|
-
"
|
|
28
|
-
"ios",
|
|
29
|
-
"
|
|
26
|
+
"android/build.gradle",
|
|
27
|
+
"android/src/main",
|
|
28
|
+
"ios/FastImage",
|
|
29
|
+
"ios/FastImage.xcodeproj/project.pbxproj",
|
|
30
|
+
"ios/FastImage.xcodeproj/xcshareddata",
|
|
30
31
|
"dist",
|
|
31
32
|
"RNFastImage.podspec"
|
|
32
33
|
],
|
|
33
34
|
"scripts": {
|
|
34
|
-
"build": "
|
|
35
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && rolldown -c && cp src/index.js.flow dist/index.js.flow && cp src/index.js.flow dist/index.cjs.js.flow",
|
|
35
36
|
"lint": "oxlint",
|
|
36
|
-
"release": "
|
|
37
|
-
"test": "
|
|
37
|
+
"release": "semantic-release",
|
|
38
|
+
"test": "bun test",
|
|
39
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
38
40
|
"format": "oxfmt",
|
|
39
41
|
"format:check": "oxfmt --check"
|
|
40
42
|
},
|
|
41
43
|
"packageManager": "bun@1.4.2",
|
|
42
|
-
"jest": {
|
|
43
|
-
"modulePathIgnorePatterns": [
|
|
44
|
-
"ReactNativeFastImageExample*",
|
|
45
|
-
"ReactNativeFastImageExampleServer*"
|
|
46
|
-
],
|
|
47
|
-
"preset": "react-native"
|
|
48
|
-
},
|
|
49
44
|
"resolutions": {
|
|
50
|
-
"@
|
|
45
|
+
"@types/react": "^17.0.14"
|
|
51
46
|
},
|
|
52
47
|
"devDependencies": {
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
55
|
-
"@types/
|
|
48
|
+
"@semantic-release/changelog": "7.0.0",
|
|
49
|
+
"@semantic-release/git": "11.0.1",
|
|
50
|
+
"@types/bun": "^1.4.2",
|
|
56
51
|
"@types/react": "^17.0.14",
|
|
57
52
|
"@types/react-native": "^0.69.5",
|
|
58
53
|
"@types/react-test-renderer": "^17.0.1",
|
|
59
|
-
"dv-scripts": "^1.6.0",
|
|
60
54
|
"maestro-runner": "1.1.27",
|
|
61
|
-
"metro-react-native-babel-preset": "^0.66.1",
|
|
62
55
|
"oxfmt": "0.70.0",
|
|
63
56
|
"oxlint": "1.85.0",
|
|
57
|
+
"pretty-format": "^30.5.1",
|
|
64
58
|
"react": "17.0.2",
|
|
65
|
-
"react-native": "0.64.2",
|
|
66
59
|
"react-test-renderer": "17.0.2",
|
|
67
|
-
"
|
|
60
|
+
"rolldown": "1.2.11",
|
|
61
|
+
"semantic-release": "25.0.9",
|
|
62
|
+
"typescript": "7.0.2"
|
|
68
63
|
},
|
|
69
64
|
"peerDependencies": {
|
|
70
65
|
"react": "^17 || ^18 || ^19",
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAA;AAC/C,OAAO,EAMH,iBAAiB,EACjB,SAAS,EACT,SAAS,EACT,kBAAkB,EAElB,kBAAkB,EAClB,SAAS,EACZ,MAAM,cAAc,CAAA;AAKrB,aAAK,UAAU,GAAG,WAAW,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAA;AAE3D,oBAAY,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEnE,QAAA,MAAM,UAAU;;;;;CAKN,CAAA;AAEV,oBAAY,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEhD,QAAA,MAAM,QAAQ;;;;CAIJ,CAAA;AAEV,oBAAY,KAAK,GAAG,WAAW,GAAG,KAAK,GAAG,WAAW,CAAA;AAErD,QAAA,MAAM,YAAY;;;;CAOR,CAAA;AAEV,oBAAY,MAAM,GAAG;IACjB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACnC,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,KAAK,CAAC,EAAE,KAAK,CAAA;CAChB,CAAA;AAED,MAAM,WAAW,WAAW;IACxB,WAAW,EAAE;QACT,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;QAGd,MAAM,CAAC,EAAE,MAAM,CAAA;KAClB,CAAA;CACJ;AAED,MAAM,WAAW,eAAe;IAC5B,WAAW,EAAE;QACT,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE,MAAM,CAAA;KAChB,CAAA;CACJ;AAID,MAAM,WAAW,UAAW,SAAQ,SAAS;IACzC,kBAAkB,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;IACzC,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,eAAe,CAAC,EAAE,UAAU,CAAA;IAC5B,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,YAAY,CAAC,EAAE,UAAU,CAAA;IACzB,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,cAAe,SAAQ,kBAAkB,EAAE,SAAS;IACjE,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAAA;IACpC,aAAa,CAAC,EAAE,kBAAkB,CAAA;IAClC,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB,WAAW,CAAC,IAAI,IAAI,CAAA;IAEpB,UAAU,CAAC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAA;IAEzC,MAAM,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IAEjC,OAAO,CAAC,IAAI,IAAI,CAAA;IAEhB,SAAS,CAAC,IAAI,IAAI,CAAA;IAElB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAE7C;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAA;IAE7B;;;;OAIG;IAEH,SAAS,CAAC,EAAE,UAAU,CAAA;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC7B;AAmKD,MAAM,WAAW,yBAAyB;IACtC,UAAU,EAAE,OAAO,UAAU,CAAA;IAC7B,QAAQ,EAAE,OAAO,QAAQ,CAAA;IACzB,YAAY,EAAE,OAAO,YAAY,CAAA;IACjC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACpC,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAED,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,GAChD,yBAAqD,CAAA;AA8CzD,eAAe,SAAS,CAAA"}
|
package/dist/index.test.d.ts
DELETED
package/dist/index.test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.tsx"],"names":[],"mappings":""}
|