react-native-fast-image 9.3.6 → 10.0.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 +87 -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 +3 -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 +36 -9
- 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 +1 -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 +7 -8
- package/android/src/main/java/com/fastimage/FastImageViewManager.java +591 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewModule.java +31 -28
- package/android/src/main/java/com/fastimage/FastImageViewPackage.java +51 -0
- package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewWithUrl.java +362 -129
- 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 +33 -17
- package/dist/index.cjs.web.js +211 -61
- package/dist/index.cjs.web.js.flow +33 -17
- package/dist/index.d.ts +83 -58
- package/dist/index.js +278 -159
- package/dist/index.js.flow +33 -17
- package/dist/index.web.js +212 -62
- package/dist/index.web.js.flow +33 -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} +70 -59
- package/ios/FastImage/FFFastImageView.h +36 -7
- package/ios/FastImage/FFFastImageView.m +201 -164
- 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 +7 -10
- package/package.json +28 -9
- package/src/constants.ts +28 -0
- package/src/index.js.flow +179 -0
- package/src/index.tsx +1103 -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
package/dist/index.cjs.web.js
CHANGED
|
@@ -62,13 +62,6 @@ function fromStyle(style, key) {
|
|
|
62
62
|
}
|
|
63
63
|
return style && typeof style === "object" ? style[key] : void 0;
|
|
64
64
|
}
|
|
65
|
-
const RESIZE_MODE_FIT = {
|
|
66
|
-
contain: "contain",
|
|
67
|
-
cover: "cover",
|
|
68
|
-
stretch: "fill",
|
|
69
|
-
center: "center",
|
|
70
|
-
repeat: "repeat"
|
|
71
|
-
};
|
|
72
65
|
const FITS = {
|
|
73
66
|
fill: true,
|
|
74
67
|
contain: true,
|
|
@@ -76,11 +69,202 @@ const FITS = {
|
|
|
76
69
|
none: true,
|
|
77
70
|
"scale-down": true
|
|
78
71
|
};
|
|
79
|
-
function resolveObjectFit(objectFit, style
|
|
80
|
-
var _RESIZE_MODE_FIT$resi;
|
|
72
|
+
function resolveObjectFit(objectFit, style) {
|
|
81
73
|
const fit = objectFit != null ? objectFit : fromStyle(style, "objectFit");
|
|
82
|
-
|
|
83
|
-
|
|
74
|
+
return fit && FITS[fit] === true ? fit : "cover";
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/warnings.ts
|
|
78
|
+
const warned = /* @__PURE__ */ new Set();
|
|
79
|
+
function warnOnce(key, message, level) {
|
|
80
|
+
if (!warned.has(key)) {
|
|
81
|
+
warned.add(key);
|
|
82
|
+
console[level](message);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function warnIfChildren(children) {
|
|
86
|
+
if (react.Children.toArray(children).length > 0) warnOnce("children", "react-native-fast-image: FastImage doesn't render children (since 10.0): use FastImageBackground for content over an image.", "error");
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/objectPosition.ts
|
|
90
|
+
const START = {
|
|
91
|
+
fraction: 0,
|
|
92
|
+
offset: 0
|
|
93
|
+
};
|
|
94
|
+
const CENTER = {
|
|
95
|
+
fraction: .5,
|
|
96
|
+
offset: 0
|
|
97
|
+
};
|
|
98
|
+
const END = {
|
|
99
|
+
fraction: 1,
|
|
100
|
+
offset: 0
|
|
101
|
+
};
|
|
102
|
+
/** The default, `50% 50%`. */
|
|
103
|
+
const CENTERED = {
|
|
104
|
+
x: CENTER,
|
|
105
|
+
y: CENTER
|
|
106
|
+
};
|
|
107
|
+
const NUMBER = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i;
|
|
108
|
+
function length(text) {
|
|
109
|
+
const lower = text.toLowerCase();
|
|
110
|
+
if (lower.endsWith("%")) {
|
|
111
|
+
const number = lower.slice(0, -1);
|
|
112
|
+
return NUMBER.test(number) ? {
|
|
113
|
+
fraction: Number(number) / 100,
|
|
114
|
+
offset: 0
|
|
115
|
+
} : null;
|
|
116
|
+
}
|
|
117
|
+
if (lower.endsWith("px")) {
|
|
118
|
+
const number = lower.slice(0, -2);
|
|
119
|
+
return NUMBER.test(number) ? {
|
|
120
|
+
fraction: 0,
|
|
121
|
+
offset: Number(number)
|
|
122
|
+
} : null;
|
|
123
|
+
}
|
|
124
|
+
return NUMBER.test(lower) && Number(lower) === 0 ? START : null;
|
|
125
|
+
}
|
|
126
|
+
function token(text) {
|
|
127
|
+
const lower = text.toLowerCase();
|
|
128
|
+
if (lower === "left" || lower === "right" || lower === "top" || lower === "bottom" || lower === "center") return { keyword: lower };
|
|
129
|
+
const axis = length(text);
|
|
130
|
+
return axis ? { length: axis } : null;
|
|
131
|
+
}
|
|
132
|
+
const X = {
|
|
133
|
+
left: START,
|
|
134
|
+
center: CENTER,
|
|
135
|
+
right: END
|
|
136
|
+
};
|
|
137
|
+
const Y = {
|
|
138
|
+
top: START,
|
|
139
|
+
center: CENTER,
|
|
140
|
+
bottom: END
|
|
141
|
+
};
|
|
142
|
+
const x = (t) => "length" in t ? t.length : X[t.keyword];
|
|
143
|
+
const y = (t) => "length" in t ? t.length : Y[t.keyword];
|
|
144
|
+
function fromEdge(edge, axis) {
|
|
145
|
+
return edge === "left" || edge === "top" ? axis : {
|
|
146
|
+
fraction: 1 - axis.fraction,
|
|
147
|
+
offset: -axis.offset || 0
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function parse(text) {
|
|
151
|
+
const tokens = [];
|
|
152
|
+
for (const part of text.trim().split(/\s+/)) {
|
|
153
|
+
const t = token(part);
|
|
154
|
+
if (!t) return null;
|
|
155
|
+
tokens.push(t);
|
|
156
|
+
}
|
|
157
|
+
if (tokens.length === 1) {
|
|
158
|
+
const [a] = tokens;
|
|
159
|
+
if ("keyword" in a && (a.keyword === "top" || a.keyword === "bottom")) return {
|
|
160
|
+
x: CENTER,
|
|
161
|
+
y: Y[a.keyword]
|
|
162
|
+
};
|
|
163
|
+
return {
|
|
164
|
+
x: x(a),
|
|
165
|
+
y: CENTER
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (tokens.length === 2) {
|
|
169
|
+
const [a, b] = tokens;
|
|
170
|
+
const ax = x(a);
|
|
171
|
+
const by = y(b);
|
|
172
|
+
if (ax && by) return {
|
|
173
|
+
x: ax,
|
|
174
|
+
y: by
|
|
175
|
+
};
|
|
176
|
+
if ("keyword" in a && "keyword" in b) {
|
|
177
|
+
const bx = X[b.keyword];
|
|
178
|
+
const ay = Y[a.keyword];
|
|
179
|
+
if (bx && ay) return {
|
|
180
|
+
x: bx,
|
|
181
|
+
y: ay
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
if (tokens.length === 4) {
|
|
187
|
+
const [a, b, c, d] = tokens;
|
|
188
|
+
if (!("keyword" in a && "length" in b && "keyword" in c && "length" in d)) return null;
|
|
189
|
+
const horizontal = (k) => k === "left" || k === "right";
|
|
190
|
+
const vertical = (k) => k === "top" || k === "bottom";
|
|
191
|
+
if (horizontal(a.keyword) && vertical(c.keyword)) return {
|
|
192
|
+
x: fromEdge(a.keyword, b.length),
|
|
193
|
+
y: fromEdge(c.keyword, d.length)
|
|
194
|
+
};
|
|
195
|
+
if (vertical(a.keyword) && horizontal(c.keyword)) return {
|
|
196
|
+
x: fromEdge(c.keyword, d.length),
|
|
197
|
+
y: fromEdge(a.keyword, b.length)
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
const parsed = /* @__PURE__ */ new Map();
|
|
203
|
+
function objectLength(value) {
|
|
204
|
+
if (typeof value === "number") return Number.isFinite(value) ? {
|
|
205
|
+
fraction: 0,
|
|
206
|
+
offset: value
|
|
207
|
+
} : null;
|
|
208
|
+
return typeof value === "string" && value.endsWith("%") ? length(value) : null;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* The position for objectPosition, or null if it isn't valid. A string is
|
|
212
|
+
* CSS's syntax; an object has one of `top` and `bottom` and one of `left`
|
|
213
|
+
* and `right`, each in points or a percentage, and a missing axis is
|
|
214
|
+
* centered. Unset is centered.
|
|
215
|
+
*/
|
|
216
|
+
function resolveObjectPosition(position) {
|
|
217
|
+
if (position == null) return CENTERED;
|
|
218
|
+
if (typeof position === "string") {
|
|
219
|
+
let result = parsed.get(position);
|
|
220
|
+
if (result === void 0) {
|
|
221
|
+
result = parse(position);
|
|
222
|
+
if (parsed.size < 100) parsed.set(position, result);
|
|
223
|
+
}
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
if (typeof position !== "object") return null;
|
|
227
|
+
const edges = position;
|
|
228
|
+
const axis = (start, end) => {
|
|
229
|
+
const hasStart = edges[start] != null;
|
|
230
|
+
const hasEnd = edges[end] != null;
|
|
231
|
+
if (hasStart && hasEnd) return null;
|
|
232
|
+
if (!hasStart && !hasEnd) return CENTER;
|
|
233
|
+
const edge = hasStart ? start : end;
|
|
234
|
+
const value = objectLength(edges[edge]);
|
|
235
|
+
return value && fromEdge(edge, value);
|
|
236
|
+
};
|
|
237
|
+
const resolvedX = axis("left", "right");
|
|
238
|
+
const resolvedY = axis("top", "bottom");
|
|
239
|
+
return resolvedX && resolvedY ? {
|
|
240
|
+
x: resolvedX,
|
|
241
|
+
y: resolvedY
|
|
242
|
+
} : null;
|
|
243
|
+
}
|
|
244
|
+
const round = (n) => Math.round(n * 1e6) / 1e6;
|
|
245
|
+
/**
|
|
246
|
+
* The position for objectPosition, or centered if it isn't valid (as CSS
|
|
247
|
+
* ignores it), with a warning in development.
|
|
248
|
+
*/
|
|
249
|
+
function objectPositionOrCentered(position) {
|
|
250
|
+
const resolved = resolveObjectPosition(position);
|
|
251
|
+
if (resolved) return resolved;
|
|
252
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
253
|
+
const value = JSON.stringify(position);
|
|
254
|
+
warnOnce(`objectPosition ${value}`, `react-native-fast-image: objectPosition ${value} isn't a position, so the image is centered. Use CSS's syntax with px or % (e.g. 'right 10px bottom 20%'), or { top | bottom, left | right } in points or percentages.`, "warn");
|
|
255
|
+
}
|
|
256
|
+
return CENTERED;
|
|
257
|
+
}
|
|
258
|
+
/** The position as CSS (for the web version's object-position). */
|
|
259
|
+
function cssPosition({ x, y }) {
|
|
260
|
+
const axis = ({ fraction, offset }) => {
|
|
261
|
+
const percent = round(fraction * 100);
|
|
262
|
+
const px = round(offset);
|
|
263
|
+
if (px === 0) return `${percent}%`;
|
|
264
|
+
if (percent === 0) return `${px}px`;
|
|
265
|
+
return `calc(${percent}% ${px < 0 ? "-" : "+"} ${Math.abs(px)}px)`;
|
|
266
|
+
};
|
|
267
|
+
return `${axis(x)} ${axis(y)}`;
|
|
84
268
|
}
|
|
85
269
|
//#endregion
|
|
86
270
|
//#region src/index.web.tsx
|
|
@@ -93,8 +277,9 @@ let ids = 0;
|
|
|
93
277
|
const useCounterId = () => (0, react.useState)(() => `${++ids}`)[0];
|
|
94
278
|
const useSvgId = (_useId = react.default.useId) !== null && _useId !== void 0 ? _useId : useCounterId;
|
|
95
279
|
const useClientLayoutEffect = globalThis.document === void 0 ? react.useEffect : react.useLayoutEffect;
|
|
96
|
-
function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadStart, onLoad, onError, onLoadEnd, style, children, objectFit,
|
|
97
|
-
|
|
280
|
+
function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadStart, onLoad, onError, onLoadEnd, style, children, objectFit, objectPosition, forwardedRef, onLayout, pointerEvents, recyclingKey: _recyclingKey, loop: _loop, imageRendering: _imageRendering, paused: _paused, transition: _transition, downsample: _downsample, onProgress: _onProgress, ...props }) {
|
|
281
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) warnIfChildren(children);
|
|
282
|
+
const { accessibilityLabel, "aria-label": ariaLabel, resizeMode: _resizeMode, ...viewProps } = props;
|
|
98
283
|
const label = ariaLabel || accessibilityLabel || void 0;
|
|
99
284
|
const several = Array.isArray(source) && source.length > 1 ? source : void 0;
|
|
100
285
|
const sized = several ? sizedSources(several) : void 0;
|
|
@@ -105,8 +290,8 @@ function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadSta
|
|
|
105
290
|
const [result, setResult] = (0, react.useState)();
|
|
106
291
|
const ok = result && result.key === key ? result.ok : void 0;
|
|
107
292
|
const tintId = `fast-image-tint-${useSvgId().replace(/[^\w-]/g, "")}`;
|
|
108
|
-
const
|
|
109
|
-
const
|
|
293
|
+
const fit = resolveObjectFit(objectFit, style);
|
|
294
|
+
const position = cssPosition(objectPositionOrCentered(objectPosition));
|
|
110
295
|
const filter = [blurRadius ? `blur(${blurRadius}px)` : "", tintColor ? `url(#${tintId})` : ""].filter(Boolean).join(" ") || void 0;
|
|
111
296
|
const showDefault = !!defaultUri && ok !== true;
|
|
112
297
|
useClientLayoutEffect(() => {
|
|
@@ -123,6 +308,7 @@ function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadSta
|
|
|
123
308
|
key: `default ${defaultUri}`,
|
|
124
309
|
src: defaultUri,
|
|
125
310
|
fit,
|
|
311
|
+
position,
|
|
126
312
|
filter,
|
|
127
313
|
alt: key ? "" : label !== null && label !== void 0 ? label : ""
|
|
128
314
|
}) : null, key && src ? /* @__PURE__ */ react.default.createElement(Picture, {
|
|
@@ -131,6 +317,7 @@ function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadSta
|
|
|
131
317
|
srcSet,
|
|
132
318
|
lazy: !!several,
|
|
133
319
|
fit,
|
|
320
|
+
position,
|
|
134
321
|
filter,
|
|
135
322
|
hidden: ok === false,
|
|
136
323
|
alt: label !== null && label !== void 0 ? label : "",
|
|
@@ -165,7 +352,7 @@ function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadSta
|
|
|
165
352
|
}) : null, tintColor ? /* @__PURE__ */ react.default.createElement(TintFilter, {
|
|
166
353
|
id: tintId,
|
|
167
354
|
color: tintColor
|
|
168
|
-
}) : null
|
|
355
|
+
}) : null);
|
|
169
356
|
}
|
|
170
357
|
function resolveUri(source) {
|
|
171
358
|
let uri;
|
|
@@ -213,14 +400,10 @@ const fill = {
|
|
|
213
400
|
width: "100%",
|
|
214
401
|
height: "100%"
|
|
215
402
|
};
|
|
216
|
-
function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError }) {
|
|
217
|
-
const repeat = fit === "repeat";
|
|
403
|
+
function Picture({ src, srcSet, lazy, fit, position, filter, hidden, alt, onLoad, onError }) {
|
|
218
404
|
const image = (0, react.useRef)(null);
|
|
219
|
-
const tiles = (0, react.useRef)(null);
|
|
220
405
|
const mounted = (0, react.useRef)(true);
|
|
221
406
|
const handled = (0, react.useRef)(void 0);
|
|
222
|
-
const [natural, setNatural] = (0, react.useState)();
|
|
223
|
-
const [box, setBox] = (0, react.useState)();
|
|
224
407
|
const loaded = (target) => {
|
|
225
408
|
var _handled$current, _target$decode;
|
|
226
409
|
const file = target.currentSrc || src;
|
|
@@ -230,10 +413,6 @@ function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError
|
|
|
230
413
|
sources,
|
|
231
414
|
file
|
|
232
415
|
};
|
|
233
|
-
setNatural({
|
|
234
|
-
width: target.naturalWidth,
|
|
235
|
-
height: target.naturalHeight
|
|
236
|
-
});
|
|
237
416
|
const done = () => {
|
|
238
417
|
if (mounted.current) onLoad === null || onLoad === void 0 || onLoad(target);
|
|
239
418
|
};
|
|
@@ -254,21 +433,7 @@ function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError
|
|
|
254
433
|
if (mounted.current) onError === null || onError === void 0 || onError(target.currentSrc || src);
|
|
255
434
|
});
|
|
256
435
|
}, []);
|
|
257
|
-
|
|
258
|
-
const Observer = globalThis.ResizeObserver;
|
|
259
|
-
const node = tiles.current;
|
|
260
|
-
if (!repeat || !node || !Observer) return;
|
|
261
|
-
const observer = new Observer((entries) => {
|
|
262
|
-
const { width, height } = entries[0].contentRect;
|
|
263
|
-
setBox({
|
|
264
|
-
width,
|
|
265
|
-
height
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
observer.observe(node);
|
|
269
|
-
return () => observer.disconnect();
|
|
270
|
-
}, [repeat]);
|
|
271
|
-
const img = /* @__PURE__ */ react.default.createElement("img", {
|
|
436
|
+
return /* @__PURE__ */ react.default.createElement("img", {
|
|
272
437
|
ref: image,
|
|
273
438
|
src,
|
|
274
439
|
srcSet,
|
|
@@ -278,9 +443,10 @@ function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError
|
|
|
278
443
|
draggable: false,
|
|
279
444
|
style: {
|
|
280
445
|
...fill,
|
|
281
|
-
objectFit:
|
|
282
|
-
|
|
283
|
-
|
|
446
|
+
objectFit: fit,
|
|
447
|
+
objectPosition: position,
|
|
448
|
+
filter,
|
|
449
|
+
opacity: hidden ? 0 : void 0
|
|
284
450
|
},
|
|
285
451
|
onLoad: (event) => loaded(event.currentTarget),
|
|
286
452
|
onError: (event) => {
|
|
@@ -288,23 +454,6 @@ function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError
|
|
|
288
454
|
if (mounted.current) onError === null || onError === void 0 || onError((target === null || target === void 0 ? void 0 : target.currentSrc) || src);
|
|
289
455
|
}
|
|
290
456
|
});
|
|
291
|
-
return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, repeat ? /* @__PURE__ */ react.default.createElement("div", {
|
|
292
|
-
ref: tiles,
|
|
293
|
-
style: {
|
|
294
|
-
...fill,
|
|
295
|
-
backgroundImage: `url("${src}")`,
|
|
296
|
-
backgroundRepeat: "repeat",
|
|
297
|
-
backgroundPosition: "0",
|
|
298
|
-
backgroundSize: tileSize(natural, box),
|
|
299
|
-
filter,
|
|
300
|
-
opacity: hidden ? 0 : void 0
|
|
301
|
-
}
|
|
302
|
-
}) : null, img);
|
|
303
|
-
}
|
|
304
|
-
function tileSize(natural, box) {
|
|
305
|
-
if (!(natural === null || natural === void 0 ? void 0 : natural.width) || !natural.height || !(box === null || box === void 0 ? void 0 : box.width) || !box.height) return;
|
|
306
|
-
const scale = Math.min(1, box.width / natural.width, box.height / natural.height);
|
|
307
|
-
return `${Math.ceil(scale * natural.width)}px ${Math.ceil(scale * natural.height)}px`;
|
|
308
457
|
}
|
|
309
458
|
function TintFilter({ id, color }) {
|
|
310
459
|
return /* @__PURE__ */ react.default.createElement("svg", { style: tintStyle }, /* @__PURE__ */ react.default.createElement("defs", null, /* @__PURE__ */ react.default.createElement("filter", { id }, /* @__PURE__ */ react.default.createElement("feFlood", {
|
|
@@ -339,9 +488,9 @@ function getSize(uri) {
|
|
|
339
488
|
});
|
|
340
489
|
}
|
|
341
490
|
const FastImage = FastImageComponent;
|
|
342
|
-
FastImage.resizeMode = resizeMode;
|
|
343
491
|
FastImage.cacheControl = cacheControl;
|
|
344
492
|
FastImage.priority = priority;
|
|
493
|
+
FastImage.resizeMode = resizeMode;
|
|
345
494
|
FastImage.preload = (sources) => Promise.all(sources.map((source) => {
|
|
346
495
|
const uri = source ? source.uri : void 0;
|
|
347
496
|
if (typeof uri !== "string" || !uri) return Promise.resolve({
|
|
@@ -362,6 +511,7 @@ FastImage.preload = (sources) => Promise.all(sources.map((source) => {
|
|
|
362
511
|
FastImage.clearMemoryCache = () => Promise.resolve(notSupported);
|
|
363
512
|
FastImage.clearDiskCache = () => Promise.resolve(notSupported);
|
|
364
513
|
FastImage.configureCache = () => Promise.resolve({});
|
|
514
|
+
FastImage.setDefaults = () => {};
|
|
365
515
|
FastImage.writeToCache = () => Promise.resolve(notSupported);
|
|
366
516
|
FastImage.getCachePath = () => Promise.resolve(notSupported);
|
|
367
517
|
const styles = react_native.StyleSheet.create({ container: { overflow: "hidden" } });
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import type { ViewProps } from 'react-native
|
|
4
|
-
import type { SyntheticEvent } from 'react-native/Libraries/Types/CoreEventTypes'
|
|
3
|
+
import type { NativeSyntheticEvent, ViewProps } from 'react-native'
|
|
5
4
|
|
|
6
|
-
export type OnLoadEvent =
|
|
5
|
+
export type OnLoadEvent = NativeSyntheticEvent<
|
|
7
6
|
$ReadOnly<{
|
|
8
7
|
width: number,
|
|
9
8
|
height: number,
|
|
10
|
-
// The view's React tag
|
|
11
|
-
// TODO: make it required once the New Architecture is the minimum.
|
|
9
|
+
// The view's React tag (on iOS and Android; not on the web).
|
|
12
10
|
target?: number,
|
|
13
11
|
}>,
|
|
14
12
|
>
|
|
15
13
|
|
|
16
|
-
export type OnErrorEvent =
|
|
14
|
+
export type OnErrorEvent = NativeSyntheticEvent<
|
|
17
15
|
$ReadOnly<{|
|
|
18
16
|
error: string,
|
|
19
17
|
|}>,
|
|
20
18
|
>
|
|
21
19
|
|
|
22
|
-
export type OnProgressEvent =
|
|
20
|
+
export type OnProgressEvent = NativeSyntheticEvent<
|
|
23
21
|
$ReadOnly<{|
|
|
24
22
|
loaded: number,
|
|
25
23
|
total: number,
|
|
@@ -28,6 +26,12 @@ export type OnProgressEvent = SyntheticEvent<
|
|
|
28
26
|
|}>,
|
|
29
27
|
>
|
|
30
28
|
|
|
29
|
+
export type Priority = $ReadOnly<{|
|
|
30
|
+
low: 'low',
|
|
31
|
+
normal: 'normal',
|
|
32
|
+
high: 'high',
|
|
33
|
+
|}>
|
|
34
|
+
|
|
31
35
|
export type ResizeMode = $ReadOnly<{|
|
|
32
36
|
contain: 'contain',
|
|
33
37
|
cover: 'cover',
|
|
@@ -36,20 +40,22 @@ export type ResizeMode = $ReadOnly<{|
|
|
|
36
40
|
repeat: 'repeat',
|
|
37
41
|
|}>
|
|
38
42
|
|
|
39
|
-
export type Priority = $ReadOnly<{|
|
|
40
|
-
low: 'low',
|
|
41
|
-
normal: 'normal',
|
|
42
|
-
high: 'high',
|
|
43
|
-
|}>
|
|
44
|
-
|
|
45
43
|
export type CacheControl = $ReadOnly<{|
|
|
46
44
|
immutable: 'immutable',
|
|
47
45
|
web: 'web',
|
|
48
46
|
cacheOnly: 'cacheOnly',
|
|
49
47
|
|}>
|
|
50
48
|
|
|
51
|
-
export type ResizeModes = $Values<ResizeMode>
|
|
52
49
|
export type ObjectFit = 'fill' | 'contain' | 'cover' | 'none' | 'scale-down'
|
|
50
|
+
export type PositionLength = number | string
|
|
51
|
+
export type ObjectPosition =
|
|
52
|
+
| string
|
|
53
|
+
| $ReadOnly<{|
|
|
54
|
+
top?: PositionLength,
|
|
55
|
+
bottom?: PositionLength,
|
|
56
|
+
left?: PositionLength,
|
|
57
|
+
right?: PositionLength,
|
|
58
|
+
|}>
|
|
53
59
|
export type Priorities = $Values<Priority>
|
|
54
60
|
export type CacheControls = $Values<CacheControl>
|
|
55
61
|
|
|
@@ -82,6 +88,10 @@ export type Transition = $ReadOnly<{|
|
|
|
82
88
|
skipOnCacheHit?: ?('none' | 'memory' | 'all'),
|
|
83
89
|
|}>
|
|
84
90
|
|
|
91
|
+
export type FastImageDefaults = $ReadOnly<{|
|
|
92
|
+
transition?: ?(boolean | number | Transition),
|
|
93
|
+
|}>
|
|
94
|
+
|
|
85
95
|
export type PreloadSuccess = {|
|
|
86
96
|
uri: string,
|
|
87
97
|
ok: true,
|
|
@@ -125,9 +135,7 @@ export type FastImageProps = $ReadOnly<{|
|
|
|
125
135
|
|
|
126
136
|
tintColor?: number | string,
|
|
127
137
|
objectFit?: ?ObjectFit,
|
|
128
|
-
|
|
129
|
-
resizeMode?: ?ResizeModes,
|
|
130
|
-
fallback?: ?boolean,
|
|
138
|
+
objectPosition?: ?ObjectPosition,
|
|
131
139
|
recyclingKey?: ?string,
|
|
132
140
|
loop?: ?(boolean | number),
|
|
133
141
|
imageRendering?: ?('auto' | 'smooth' | 'pixelated'),
|
|
@@ -136,6 +144,9 @@ export type FastImageProps = $ReadOnly<{|
|
|
|
136
144
|
downsample?: ?boolean,
|
|
137
145
|
blurRadius?: ?number,
|
|
138
146
|
testID?: ?string,
|
|
147
|
+
// FastImage is a single native view, which doesn't take children (since
|
|
148
|
+
// 10.0): use FastImageBackground.
|
|
149
|
+
children?: "FastImage doesn't take children: use FastImageBackground for content over an image",
|
|
139
150
|
|}>
|
|
140
151
|
|
|
141
152
|
export type FastImageBackgroundProps = $ReadOnly<{|
|
|
@@ -148,14 +159,19 @@ export type FastImageBackgroundProps = $ReadOnly<{|
|
|
|
148
159
|
declare export var FastImageBackground: React$ComponentType<FastImageBackgroundProps>
|
|
149
160
|
|
|
150
161
|
declare export default class FastImage extends React$Component<FastImageProps> {
|
|
162
|
+
// Deprecated: removed in 10.0, and a resizeMode prop is ignored; use
|
|
163
|
+
// objectFit. Kept so code that reads it doesn't throw.
|
|
151
164
|
static resizeMode: ResizeMode;
|
|
165
|
+
// Deprecated: use the strings instead, e.g. priority: 'high'.
|
|
152
166
|
static priority: Priority;
|
|
167
|
+
// Deprecated: use the strings instead, e.g. cache: 'immutable'.
|
|
153
168
|
static cacheControl: CacheControl;
|
|
154
169
|
static preload: PreloadFn;
|
|
155
170
|
static clearMemoryCache: () => Promise<ClearCacheResult>;
|
|
156
171
|
static clearDiskCache: () => Promise<ClearCacheResult>;
|
|
157
172
|
static getCachePath: (source: FastImageSource) => Promise<CachePathResult>;
|
|
158
173
|
static configureCache: (limits?: CacheLimits) => Promise<CacheState>;
|
|
174
|
+
static setDefaults: (defaults: FastImageDefaults) => void;
|
|
159
175
|
static writeToCache: (
|
|
160
176
|
source: FastImageSource,
|
|
161
177
|
file: string,
|