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.
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 +362 -129
  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
@@ -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, resizeMode) {
80
- var _RESIZE_MODE_FIT$resi;
72
+ function resolveObjectFit(objectFit, style) {
81
73
  const fit = objectFit != null ? objectFit : fromStyle(style, "objectFit");
82
- if (fit && FITS[fit] === true) return fit;
83
- return (_RESIZE_MODE_FIT$resi = RESIZE_MODE_FIT[resizeMode]) !== null && _RESIZE_MODE_FIT$resi !== void 0 ? _RESIZE_MODE_FIT$resi : "cover";
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, resizeMode: mode = "cover", forwardedRef, onLayout, pointerEvents, fallback: _fallback, recyclingKey: _recyclingKey, loop: _loop, imageRendering: _imageRendering, paused: _paused, transition: _transition, downsample: _downsample, onProgress: _onProgress, ...props }) {
97
- const { accessibilityLabel, "aria-label": ariaLabel, ...viewProps } = props;
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 resolved = resolveObjectFit(objectFit, style, mode);
109
- const fit = resolved === "center" ? "scale-down" : several && resolved === "repeat" ? "cover" : resolved;
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, children);
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
- useClientLayoutEffect(() => {
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: repeat ? "cover" : fit,
282
- filter: repeat ? void 0 : filter,
283
- opacity: repeat || hidden ? 0 : void 0
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/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,