react-native-fast-image 9.3.7 → 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.
Files changed (76) hide show
  1. package/README.md +87 -61
  2. package/RNFastImage.podspec +14 -9
  3. package/android/build.gradle +21 -47
  4. package/android/consumer-rules.pro +7 -7
  5. package/android/src/main/AndroidManifest.xml +1 -2
  6. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimatable.java +1 -1
  7. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageAnimated.java +2 -2
  8. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageApng.java +2 -2
  9. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageBlur.java +4 -6
  10. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheControl.java +1 -1
  11. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheLimits.java +4 -1
  12. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageCacheWrite.java +1 -1
  13. package/android/src/main/java/com/fastimage/FastImageCrop.java +92 -0
  14. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageEvent.java +2 -3
  15. package/android/src/main/java/com/fastimage/FastImageEvents.java +74 -0
  16. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGif.java +1 -1
  17. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlide.java +3 -3
  18. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageGlideModule.java +1 -1
  19. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageKeyedGlideUrl.java +1 -1
  20. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageOkHttpProgressGlideModule.java +36 -9
  21. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageRequestListener.java +6 -1
  22. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSharedDownloads.java +1 -1
  23. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSource.java +1 -1
  24. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSourceSize.java +12 -2
  25. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvg.java +3 -3
  26. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageSvgRenderer.java +1 -1
  27. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageUrl.java +1 -1
  28. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewConverter.java +7 -8
  29. package/android/src/main/java/com/fastimage/FastImageViewManager.java +591 -0
  30. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewModule.java +31 -28
  31. package/android/src/main/java/com/fastimage/FastImageViewPackage.java +51 -0
  32. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageViewWithUrl.java +352 -126
  33. package/android/src/main/java/com/{dylanvann/fastimage → fastimage}/FastImageWebGlideUrl.java +1 -1
  34. package/app.plugin.js +2 -7
  35. package/dist/index.cjs.js +276 -157
  36. package/dist/index.cjs.js.flow +33 -17
  37. package/dist/index.cjs.web.js +211 -61
  38. package/dist/index.cjs.web.js.flow +33 -17
  39. package/dist/index.d.ts +83 -58
  40. package/dist/index.js +278 -159
  41. package/dist/index.js.flow +33 -17
  42. package/dist/index.web.js +212 -62
  43. package/dist/index.web.js.flow +33 -17
  44. package/dist/objectFit.d.ts +2 -2
  45. package/dist/objectPosition.d.ts +42 -0
  46. package/dist/specs/FastImageViewNativeComponent.d.ts +48 -0
  47. package/dist/specs/NativeFastImageModule.d.ts +11 -0
  48. package/dist/warnings.d.ts +3 -0
  49. package/ios/FastImage/FFFDownsampledImage.h +4 -8
  50. package/ios/FastImage/FFFDownsampledImage.m +0 -34
  51. package/ios/FastImage/FFFastImageModule.h +8 -0
  52. package/ios/FastImage/{FFFastImageViewManager.m → FFFastImageModule.mm} +70 -59
  53. package/ios/FastImage/FFFastImageView.h +36 -7
  54. package/ios/FastImage/FFFastImageView.m +201 -164
  55. package/ios/FastImage/FFFastImageViewComponentView.h +11 -0
  56. package/ios/FastImage/FFFastImageViewComponentView.mm +325 -0
  57. package/ios/FastImage/RCTConvert+FFFastImage.h +1 -1
  58. package/ios/FastImage/RCTConvert+FFFastImage.m +7 -10
  59. package/package.json +28 -9
  60. package/src/constants.ts +28 -0
  61. package/src/index.js.flow +179 -0
  62. package/src/index.tsx +1103 -0
  63. package/src/index.web.tsx +548 -0
  64. package/src/objectFit.ts +48 -0
  65. package/src/objectPosition.ts +243 -0
  66. package/src/specs/FastImageViewNativeComponent.ts +83 -0
  67. package/src/specs/NativeFastImageModule.ts +35 -0
  68. package/src/warnings.ts +37 -0
  69. package/android/src/main/AndroidManifestNew.xml +0 -3
  70. package/android/src/main/java/com/dylanvann/fastimage/FastImageCookieHandler.java +0 -63
  71. package/android/src/main/java/com/dylanvann/fastimage/FastImageEvents.java +0 -49
  72. package/android/src/main/java/com/dylanvann/fastimage/FastImageProgressListener.java +0 -18
  73. package/android/src/main/java/com/dylanvann/fastimage/FastImageShadowNode.java +0 -21
  74. package/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java +0 -379
  75. package/android/src/main/java/com/dylanvann/fastimage/FastImageViewPackage.java +0 -27
  76. package/ios/FastImage/FFFastImageViewManager.h +0 -5
package/dist/index.web.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, memo, useEffect, useLayoutEffect, useRef, useState } from "react";
1
+ import React, { Children, forwardRef, memo, useEffect, useLayoutEffect, useRef, useState } from "react";
2
2
  import { Image, PixelRatio, StyleSheet, View } from "react-native";
3
3
  import { getAssetByID } from "react-native-web/dist/modules/AssetRegistry";
4
4
  //#region src/constants.ts
@@ -35,13 +35,6 @@ function fromStyle(style, key) {
35
35
  }
36
36
  return style && typeof style === "object" ? style[key] : void 0;
37
37
  }
38
- const RESIZE_MODE_FIT = {
39
- contain: "contain",
40
- cover: "cover",
41
- stretch: "fill",
42
- center: "center",
43
- repeat: "repeat"
44
- };
45
38
  const FITS = {
46
39
  fill: true,
47
40
  contain: true,
@@ -49,11 +42,202 @@ const FITS = {
49
42
  none: true,
50
43
  "scale-down": true
51
44
  };
52
- function resolveObjectFit(objectFit, style, resizeMode) {
53
- var _RESIZE_MODE_FIT$resi;
45
+ function resolveObjectFit(objectFit, style) {
54
46
  const fit = objectFit != null ? objectFit : fromStyle(style, "objectFit");
55
- if (fit && FITS[fit] === true) return fit;
56
- return (_RESIZE_MODE_FIT$resi = RESIZE_MODE_FIT[resizeMode]) !== null && _RESIZE_MODE_FIT$resi !== void 0 ? _RESIZE_MODE_FIT$resi : "cover";
47
+ return fit && FITS[fit] === true ? fit : "cover";
48
+ }
49
+ //#endregion
50
+ //#region src/warnings.ts
51
+ const warned = /* @__PURE__ */ new Set();
52
+ function warnOnce(key, message, level) {
53
+ if (!warned.has(key)) {
54
+ warned.add(key);
55
+ console[level](message);
56
+ }
57
+ }
58
+ function warnIfChildren(children) {
59
+ if (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");
60
+ }
61
+ //#endregion
62
+ //#region src/objectPosition.ts
63
+ const START = {
64
+ fraction: 0,
65
+ offset: 0
66
+ };
67
+ const CENTER = {
68
+ fraction: .5,
69
+ offset: 0
70
+ };
71
+ const END = {
72
+ fraction: 1,
73
+ offset: 0
74
+ };
75
+ /** The default, `50% 50%`. */
76
+ const CENTERED = {
77
+ x: CENTER,
78
+ y: CENTER
79
+ };
80
+ const NUMBER = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i;
81
+ function length(text) {
82
+ const lower = text.toLowerCase();
83
+ if (lower.endsWith("%")) {
84
+ const number = lower.slice(0, -1);
85
+ return NUMBER.test(number) ? {
86
+ fraction: Number(number) / 100,
87
+ offset: 0
88
+ } : null;
89
+ }
90
+ if (lower.endsWith("px")) {
91
+ const number = lower.slice(0, -2);
92
+ return NUMBER.test(number) ? {
93
+ fraction: 0,
94
+ offset: Number(number)
95
+ } : null;
96
+ }
97
+ return NUMBER.test(lower) && Number(lower) === 0 ? START : null;
98
+ }
99
+ function token(text) {
100
+ const lower = text.toLowerCase();
101
+ if (lower === "left" || lower === "right" || lower === "top" || lower === "bottom" || lower === "center") return { keyword: lower };
102
+ const axis = length(text);
103
+ return axis ? { length: axis } : null;
104
+ }
105
+ const X = {
106
+ left: START,
107
+ center: CENTER,
108
+ right: END
109
+ };
110
+ const Y = {
111
+ top: START,
112
+ center: CENTER,
113
+ bottom: END
114
+ };
115
+ const x = (t) => "length" in t ? t.length : X[t.keyword];
116
+ const y = (t) => "length" in t ? t.length : Y[t.keyword];
117
+ function fromEdge(edge, axis) {
118
+ return edge === "left" || edge === "top" ? axis : {
119
+ fraction: 1 - axis.fraction,
120
+ offset: -axis.offset || 0
121
+ };
122
+ }
123
+ function parse(text) {
124
+ const tokens = [];
125
+ for (const part of text.trim().split(/\s+/)) {
126
+ const t = token(part);
127
+ if (!t) return null;
128
+ tokens.push(t);
129
+ }
130
+ if (tokens.length === 1) {
131
+ const [a] = tokens;
132
+ if ("keyword" in a && (a.keyword === "top" || a.keyword === "bottom")) return {
133
+ x: CENTER,
134
+ y: Y[a.keyword]
135
+ };
136
+ return {
137
+ x: x(a),
138
+ y: CENTER
139
+ };
140
+ }
141
+ if (tokens.length === 2) {
142
+ const [a, b] = tokens;
143
+ const ax = x(a);
144
+ const by = y(b);
145
+ if (ax && by) return {
146
+ x: ax,
147
+ y: by
148
+ };
149
+ if ("keyword" in a && "keyword" in b) {
150
+ const bx = X[b.keyword];
151
+ const ay = Y[a.keyword];
152
+ if (bx && ay) return {
153
+ x: bx,
154
+ y: ay
155
+ };
156
+ }
157
+ return null;
158
+ }
159
+ if (tokens.length === 4) {
160
+ const [a, b, c, d] = tokens;
161
+ if (!("keyword" in a && "length" in b && "keyword" in c && "length" in d)) return null;
162
+ const horizontal = (k) => k === "left" || k === "right";
163
+ const vertical = (k) => k === "top" || k === "bottom";
164
+ if (horizontal(a.keyword) && vertical(c.keyword)) return {
165
+ x: fromEdge(a.keyword, b.length),
166
+ y: fromEdge(c.keyword, d.length)
167
+ };
168
+ if (vertical(a.keyword) && horizontal(c.keyword)) return {
169
+ x: fromEdge(c.keyword, d.length),
170
+ y: fromEdge(a.keyword, b.length)
171
+ };
172
+ }
173
+ return null;
174
+ }
175
+ const parsed = /* @__PURE__ */ new Map();
176
+ function objectLength(value) {
177
+ if (typeof value === "number") return Number.isFinite(value) ? {
178
+ fraction: 0,
179
+ offset: value
180
+ } : null;
181
+ return typeof value === "string" && value.endsWith("%") ? length(value) : null;
182
+ }
183
+ /**
184
+ * The position for objectPosition, or null if it isn't valid. A string is
185
+ * CSS's syntax; an object has one of `top` and `bottom` and one of `left`
186
+ * and `right`, each in points or a percentage, and a missing axis is
187
+ * centered. Unset is centered.
188
+ */
189
+ function resolveObjectPosition(position) {
190
+ if (position == null) return CENTERED;
191
+ if (typeof position === "string") {
192
+ let result = parsed.get(position);
193
+ if (result === void 0) {
194
+ result = parse(position);
195
+ if (parsed.size < 100) parsed.set(position, result);
196
+ }
197
+ return result;
198
+ }
199
+ if (typeof position !== "object") return null;
200
+ const edges = position;
201
+ const axis = (start, end) => {
202
+ const hasStart = edges[start] != null;
203
+ const hasEnd = edges[end] != null;
204
+ if (hasStart && hasEnd) return null;
205
+ if (!hasStart && !hasEnd) return CENTER;
206
+ const edge = hasStart ? start : end;
207
+ const value = objectLength(edges[edge]);
208
+ return value && fromEdge(edge, value);
209
+ };
210
+ const resolvedX = axis("left", "right");
211
+ const resolvedY = axis("top", "bottom");
212
+ return resolvedX && resolvedY ? {
213
+ x: resolvedX,
214
+ y: resolvedY
215
+ } : null;
216
+ }
217
+ const round = (n) => Math.round(n * 1e6) / 1e6;
218
+ /**
219
+ * The position for objectPosition, or centered if it isn't valid (as CSS
220
+ * ignores it), with a warning in development.
221
+ */
222
+ function objectPositionOrCentered(position) {
223
+ const resolved = resolveObjectPosition(position);
224
+ if (resolved) return resolved;
225
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
226
+ const value = JSON.stringify(position);
227
+ 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");
228
+ }
229
+ return CENTERED;
230
+ }
231
+ /** The position as CSS (for the web version's object-position). */
232
+ function cssPosition({ x, y }) {
233
+ const axis = ({ fraction, offset }) => {
234
+ const percent = round(fraction * 100);
235
+ const px = round(offset);
236
+ if (px === 0) return `${percent}%`;
237
+ if (percent === 0) return `${px}px`;
238
+ return `calc(${percent}% ${px < 0 ? "-" : "+"} ${Math.abs(px)}px)`;
239
+ };
240
+ return `${axis(x)} ${axis(y)}`;
57
241
  }
58
242
  //#endregion
59
243
  //#region src/index.web.tsx
@@ -66,8 +250,9 @@ let ids = 0;
66
250
  const useCounterId = () => useState(() => `${++ids}`)[0];
67
251
  const useSvgId = (_useId = React.useId) !== null && _useId !== void 0 ? _useId : useCounterId;
68
252
  const useClientLayoutEffect = globalThis.document === void 0 ? useEffect : useLayoutEffect;
69
- function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadStart, onLoad, onError, onLoadEnd, style, children, objectFit, resizeMode: mode = "cover", forwardedRef, onLayout, pointerEvents, fallback: _fallback, recyclingKey: _recyclingKey, loop: _loop, imageRendering: _imageRendering, paused: _paused, transition: _transition, downsample: _downsample, onProgress: _onProgress, ...props }) {
70
- const { accessibilityLabel, "aria-label": ariaLabel, ...viewProps } = props;
253
+ 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 }) {
254
+ if (typeof __DEV__ !== "undefined" && __DEV__) warnIfChildren(children);
255
+ const { accessibilityLabel, "aria-label": ariaLabel, resizeMode: _resizeMode, ...viewProps } = props;
71
256
  const label = ariaLabel || accessibilityLabel || void 0;
72
257
  const several = Array.isArray(source) && source.length > 1 ? source : void 0;
73
258
  const sized = several ? sizedSources(several) : void 0;
@@ -78,8 +263,8 @@ function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadSta
78
263
  const [result, setResult] = useState();
79
264
  const ok = result && result.key === key ? result.ok : void 0;
80
265
  const tintId = `fast-image-tint-${useSvgId().replace(/[^\w-]/g, "")}`;
81
- const resolved = resolveObjectFit(objectFit, style, mode);
82
- const fit = resolved === "center" ? "scale-down" : several && resolved === "repeat" ? "cover" : resolved;
266
+ const fit = resolveObjectFit(objectFit, style);
267
+ const position = cssPosition(objectPositionOrCentered(objectPosition));
83
268
  const filter = [blurRadius ? `blur(${blurRadius}px)` : "", tintColor ? `url(#${tintId})` : ""].filter(Boolean).join(" ") || void 0;
84
269
  const showDefault = !!defaultUri && ok !== true;
85
270
  useClientLayoutEffect(() => {
@@ -96,6 +281,7 @@ function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadSta
96
281
  key: `default ${defaultUri}`,
97
282
  src: defaultUri,
98
283
  fit,
284
+ position,
99
285
  filter,
100
286
  alt: key ? "" : label !== null && label !== void 0 ? label : ""
101
287
  }) : null, key && src ? /* @__PURE__ */ React.createElement(Picture, {
@@ -104,6 +290,7 @@ function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadSta
104
290
  srcSet,
105
291
  lazy: !!several,
106
292
  fit,
293
+ position,
107
294
  filter,
108
295
  hidden: ok === false,
109
296
  alt: label !== null && label !== void 0 ? label : "",
@@ -138,7 +325,7 @@ function FastImageBase({ source, defaultSource, tintColor, blurRadius, onLoadSta
138
325
  }) : null, tintColor ? /* @__PURE__ */ React.createElement(TintFilter, {
139
326
  id: tintId,
140
327
  color: tintColor
141
- }) : null, children);
328
+ }) : null);
142
329
  }
143
330
  function resolveUri(source) {
144
331
  let uri;
@@ -186,14 +373,10 @@ const fill = {
186
373
  width: "100%",
187
374
  height: "100%"
188
375
  };
189
- function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError }) {
190
- const repeat = fit === "repeat";
376
+ function Picture({ src, srcSet, lazy, fit, position, filter, hidden, alt, onLoad, onError }) {
191
377
  const image = useRef(null);
192
- const tiles = useRef(null);
193
378
  const mounted = useRef(true);
194
379
  const handled = useRef(void 0);
195
- const [natural, setNatural] = useState();
196
- const [box, setBox] = useState();
197
380
  const loaded = (target) => {
198
381
  var _handled$current, _target$decode;
199
382
  const file = target.currentSrc || src;
@@ -203,10 +386,6 @@ function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError
203
386
  sources,
204
387
  file
205
388
  };
206
- setNatural({
207
- width: target.naturalWidth,
208
- height: target.naturalHeight
209
- });
210
389
  const done = () => {
211
390
  if (mounted.current) onLoad === null || onLoad === void 0 || onLoad(target);
212
391
  };
@@ -227,21 +406,7 @@ function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError
227
406
  if (mounted.current) onError === null || onError === void 0 || onError(target.currentSrc || src);
228
407
  });
229
408
  }, []);
230
- useClientLayoutEffect(() => {
231
- const Observer = globalThis.ResizeObserver;
232
- const node = tiles.current;
233
- if (!repeat || !node || !Observer) return;
234
- const observer = new Observer((entries) => {
235
- const { width, height } = entries[0].contentRect;
236
- setBox({
237
- width,
238
- height
239
- });
240
- });
241
- observer.observe(node);
242
- return () => observer.disconnect();
243
- }, [repeat]);
244
- const img = /* @__PURE__ */ React.createElement("img", {
409
+ return /* @__PURE__ */ React.createElement("img", {
245
410
  ref: image,
246
411
  src,
247
412
  srcSet,
@@ -251,9 +416,10 @@ function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError
251
416
  draggable: false,
252
417
  style: {
253
418
  ...fill,
254
- objectFit: repeat ? "cover" : fit,
255
- filter: repeat ? void 0 : filter,
256
- opacity: repeat || hidden ? 0 : void 0
419
+ objectFit: fit,
420
+ objectPosition: position,
421
+ filter,
422
+ opacity: hidden ? 0 : void 0
257
423
  },
258
424
  onLoad: (event) => loaded(event.currentTarget),
259
425
  onError: (event) => {
@@ -261,23 +427,6 @@ function Picture({ src, srcSet, lazy, fit, filter, hidden, alt, onLoad, onError
261
427
  if (mounted.current) onError === null || onError === void 0 || onError((target === null || target === void 0 ? void 0 : target.currentSrc) || src);
262
428
  }
263
429
  });
264
- return /* @__PURE__ */ React.createElement(React.Fragment, null, repeat ? /* @__PURE__ */ React.createElement("div", {
265
- ref: tiles,
266
- style: {
267
- ...fill,
268
- backgroundImage: `url("${src}")`,
269
- backgroundRepeat: "repeat",
270
- backgroundPosition: "0",
271
- backgroundSize: tileSize(natural, box),
272
- filter,
273
- opacity: hidden ? 0 : void 0
274
- }
275
- }) : null, img);
276
- }
277
- function tileSize(natural, box) {
278
- if (!(natural === null || natural === void 0 ? void 0 : natural.width) || !natural.height || !(box === null || box === void 0 ? void 0 : box.width) || !box.height) return;
279
- const scale = Math.min(1, box.width / natural.width, box.height / natural.height);
280
- return `${Math.ceil(scale * natural.width)}px ${Math.ceil(scale * natural.height)}px`;
281
430
  }
282
431
  function TintFilter({ id, color }) {
283
432
  return /* @__PURE__ */ React.createElement("svg", { style: tintStyle }, /* @__PURE__ */ React.createElement("defs", null, /* @__PURE__ */ React.createElement("filter", { id }, /* @__PURE__ */ React.createElement("feFlood", {
@@ -312,9 +461,9 @@ function getSize(uri) {
312
461
  });
313
462
  }
314
463
  const FastImage = FastImageComponent;
315
- FastImage.resizeMode = resizeMode;
316
464
  FastImage.cacheControl = cacheControl;
317
465
  FastImage.priority = priority;
466
+ FastImage.resizeMode = resizeMode;
318
467
  FastImage.preload = (sources) => Promise.all(sources.map((source) => {
319
468
  const uri = source ? source.uri : void 0;
320
469
  if (typeof uri !== "string" || !uri) return Promise.resolve({
@@ -335,6 +484,7 @@ FastImage.preload = (sources) => Promise.all(sources.map((source) => {
335
484
  FastImage.clearMemoryCache = () => Promise.resolve(notSupported);
336
485
  FastImage.clearDiskCache = () => Promise.resolve(notSupported);
337
486
  FastImage.configureCache = () => Promise.resolve({});
487
+ FastImage.setDefaults = () => {};
338
488
  FastImage.writeToCache = () => Promise.resolve(notSupported);
339
489
  FastImage.getCachePath = () => Promise.resolve(notSupported);
340
490
  const styles = StyleSheet.create({ container: { overflow: "hidden" } });
@@ -1,25 +1,23 @@
1
1
  // @flow
2
2
 
3
- import type { ViewProps } from 'react-native/Libraries/Components/View/ViewPropTypes'
4
- import type { SyntheticEvent } from 'react-native/Libraries/Types/CoreEventTypes'
3
+ import type { NativeSyntheticEvent, ViewProps } from 'react-native'
5
4
 
6
- export type OnLoadEvent = SyntheticEvent<
5
+ export type OnLoadEvent = NativeSyntheticEvent<
7
6
  $ReadOnly<{
8
7
  width: number,
9
8
  height: number,
10
- // The view's React tag. Missing on Android with the legacy architecture.
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 = SyntheticEvent<
14
+ export type OnErrorEvent = NativeSyntheticEvent<
17
15
  $ReadOnly<{|
18
16
  error: string,
19
17
  |}>,
20
18
  >
21
19
 
22
- export type OnProgressEvent = SyntheticEvent<
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
- // Deprecated: use objectFit.
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,
@@ -1,3 +1,3 @@
1
- import type { ImageStyle, ObjectFit, ResizeMode } from './index';
1
+ import type { ImageStyle, ObjectFit } from './index';
2
2
  export declare function fromStyle<K extends 'tintColor' | 'objectFit'>(style: unknown, key: K): ImageStyle[K];
3
- export declare function resolveObjectFit(objectFit: ObjectFit | null | undefined, style: unknown, resizeMode: ResizeMode): ObjectFit | 'repeat' | 'center';
3
+ export declare function resolveObjectFit(objectFit: ObjectFit | null | undefined, style: unknown): ObjectFit;
@@ -0,0 +1,42 @@
1
+ /** A length in points (dp on Android), or a percentage: see [`objectPosition`](#objectposition). */
2
+ export type PositionLength = number | `${number}%`;
3
+ /**
4
+ * Where the image is in the view: see [`objectPosition`](#objectposition).
5
+ */
6
+ export type ObjectPosition = string | (({
7
+ top?: PositionLength;
8
+ bottom?: never;
9
+ } | {
10
+ bottom: PositionLength;
11
+ top?: never;
12
+ }) & ({
13
+ left?: PositionLength;
14
+ right?: never;
15
+ } | {
16
+ right: PositionLength;
17
+ left?: never;
18
+ }));
19
+ export type ResolvedAxis = {
20
+ fraction: number;
21
+ offset: number;
22
+ };
23
+ export type ResolvedPosition = {
24
+ x: ResolvedAxis;
25
+ y: ResolvedAxis;
26
+ };
27
+ /** The default, `50% 50%`. */
28
+ export declare const CENTERED: ResolvedPosition;
29
+ /**
30
+ * The position for objectPosition, or null if it isn't valid. A string is
31
+ * CSS's syntax; an object has one of `top` and `bottom` and one of `left`
32
+ * and `right`, each in points or a percentage, and a missing axis is
33
+ * centered. Unset is centered.
34
+ */
35
+ export declare function resolveObjectPosition(position: ObjectPosition | null | undefined): ResolvedPosition | null;
36
+ /**
37
+ * The position for objectPosition, or centered if it isn't valid (as CSS
38
+ * ignores it), with a warning in development.
39
+ */
40
+ export declare function objectPositionOrCentered(position: ObjectPosition | null | undefined): ResolvedPosition;
41
+ /** The position as CSS (for the web version's object-position). */
42
+ export declare function cssPosition({ x, y }: ResolvedPosition): string;
@@ -0,0 +1,48 @@
1
+ import type { CodegenTypes, ColorValue, HostComponent, ViewProps } from 'react-native';
2
+ type LoadStartEvent = Readonly<{}>;
3
+ type ProgressEvent = Readonly<{
4
+ loaded: CodegenTypes.Double;
5
+ total: CodegenTypes.Double;
6
+ progress: CodegenTypes.Double;
7
+ }>;
8
+ type LoadEvent = Readonly<{
9
+ width: CodegenTypes.Double;
10
+ height: CodegenTypes.Double;
11
+ }>;
12
+ type ErrorEvent = Readonly<{
13
+ error: string;
14
+ }>;
15
+ type LoadEndEvent = Readonly<{
16
+ ok: boolean;
17
+ width?: CodegenTypes.Double;
18
+ height?: CodegenTypes.Double;
19
+ error?: string;
20
+ }>;
21
+ export interface NativeProps extends ViewProps {
22
+ source?: CodegenTypes.UnsafeMixed;
23
+ sources?: CodegenTypes.UnsafeMixed;
24
+ defaultSource?: CodegenTypes.UnsafeMixed;
25
+ objectFit?: CodegenTypes.WithDefault<string, 'cover'>;
26
+ objectPositionX?: CodegenTypes.WithDefault<CodegenTypes.Float, 0.5>;
27
+ objectPositionXOffset?: CodegenTypes.Float;
28
+ objectPositionY?: CodegenTypes.WithDefault<CodegenTypes.Float, 0.5>;
29
+ objectPositionYOffset?: CodegenTypes.Float;
30
+ tintColor?: ColorValue;
31
+ recyclingKey?: string;
32
+ loopCount?: CodegenTypes.WithDefault<CodegenTypes.Int32, -1>;
33
+ imageRendering?: string;
34
+ paused?: boolean;
35
+ transitionDuration?: CodegenTypes.Double;
36
+ transitionBetweenImages?: boolean;
37
+ transitionSkipOnCacheHit?: string;
38
+ downsample?: CodegenTypes.WithDefault<boolean, true>;
39
+ blurRadius?: CodegenTypes.Float;
40
+ handledEvents?: CodegenTypes.Int32;
41
+ onFastImageLoadStart?: CodegenTypes.DirectEventHandler<LoadStartEvent>;
42
+ onFastImageProgress?: CodegenTypes.DirectEventHandler<ProgressEvent>;
43
+ onFastImageLoad?: CodegenTypes.DirectEventHandler<LoadEvent>;
44
+ onFastImageError?: CodegenTypes.DirectEventHandler<ErrorEvent>;
45
+ onFastImageLoadEnd?: CodegenTypes.DirectEventHandler<LoadEndEvent>;
46
+ }
47
+ declare const _default: HostComponent<NativeProps>;
48
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import type { CodegenTypes, TurboModule } from 'react-native';
2
+ export interface Spec extends TurboModule {
3
+ preload(sources: Array<CodegenTypes.UnsafeObject>): Promise<Array<CodegenTypes.UnsafeObject>>;
4
+ getCachePath(source: CodegenTypes.UnsafeObject): Promise<CodegenTypes.UnsafeObject>;
5
+ writeToCache(source: CodegenTypes.UnsafeObject, file: string): Promise<CodegenTypes.UnsafeObject>;
6
+ configureCache(limits: CodegenTypes.UnsafeObject): Promise<CodegenTypes.UnsafeObject>;
7
+ clearMemoryCache(): Promise<CodegenTypes.UnsafeObject>;
8
+ clearDiskCache(): Promise<CodegenTypes.UnsafeObject>;
9
+ }
10
+ declare const _default: Spec | null;
11
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export declare function warnOnce(key: string, message: string, level: 'warn' | 'error'): void;
2
+ export declare function resetWarnings(): void;
3
+ export declare function warnIfChildren(children: unknown): void;
@@ -4,8 +4,8 @@
4
4
  // An image decoded at about the size it's shown at (the `downsample`
5
5
  // prop), instead of at full size. The view asks for it with SDWebImage's
6
6
  // thumbnail context: the box to fill (the view's size in pixels), and
7
- // preserveAspectRatio NO when the image has to cover the box (resizeMode
8
- // cover or stretch) rather than fit in it (contain or center). SDWebImage's
7
+ // preserveAspectRatio NO when the image has to cover the box (objectFit
8
+ // cover or fill) rather than fit in it (contain or scale-down). SDWebImage's
9
9
  // own thumbnail decoding can only fit, so this class works out the size from
10
10
  // the image's header before it decodes, as React Native's Image does.
11
11
  @interface FFFDownsampledImage : SDAnimatedImage
@@ -14,8 +14,8 @@
14
14
  // or fit in.
15
15
  + (void) addToContext: (SDWebImageMutableContext*)context box: (CGSize)box cover: (BOOL)cover;
16
16
 
17
- // Sets a load's context to decode the image at full size, through this class
18
- // when it's supported. Every FastImage load uses it, so loads of the same url
17
+ // Sets a load's context to decode the image at full size, through this class.
18
+ // Every FastImage load uses it, so loads of the same url
19
19
  // can share a download: SDWebImage's downloader decodes each load of a
20
20
  // download with the first load's image class (and each with its own size),
21
21
  // and SDWebImage's own thumbnail decoding can't cover a box.
@@ -33,8 +33,4 @@
33
33
  // decodes the file from the disk cache. Call it before a full-size load.
34
34
  + (void) forgetSmallerFullSizeImageForURL: (NSURL*)url context: (SDWebImageContext*)context;
35
35
 
36
- // Whether this version of SDWebImage can decode through this class: it
37
- // decodes static images through the animated image class since 5.19.
38
- + (BOOL) isSupported;
39
-
40
36
  @end