react-native-fast-image 10.5.0 → 10.7.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/src/index.js.flow CHANGED
@@ -145,7 +145,7 @@ export type FastImageProps = $ReadOnly<{|
145
145
  onLoadStart?: ?() => void,
146
146
  onProgress?: ?(event: OnProgressEvent) => void,
147
147
 
148
- source?: ?(FastImageSource | Array<FastImageSource> | number),
148
+ source?: ?(FastImageSource | Array<FastImageSource | number> | number),
149
149
  placeholder?: ?(number | string | SourcePlaceholder | PlaceholderSource),
150
150
  // Deprecated: use placeholder, which is the same.
151
151
  defaultSource?: ?number,
@@ -196,4 +196,6 @@ declare export default class FastImage extends React$Component<FastImageProps> {
196
196
  source: FastImageSource,
197
197
  file: string,
198
198
  ) => Promise<CachePathResult>;
199
+ // On a ref: loads the image again, e.g. to try again after onError.
200
+ reload(): void;
199
201
  }
package/src/index.tsx CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  import { cacheControl, priority, resizeMode } from './constants'
15
15
  import { fromStyle, resolveObjectFit } from './objectFit'
16
16
  import { objectPositionOrCentered, type ObjectPosition } from './objectPosition'
17
- import FastImageView from './specs/FastImageViewNativeComponent'
17
+ import FastImageView, { Commands } from './specs/FastImageViewNativeComponent'
18
18
  import NativeFastImageModule from './specs/NativeFastImageModule'
19
19
  import {
20
20
  dataUri,
@@ -22,6 +22,7 @@ import {
22
22
  isImageName,
23
23
  placeholderSource,
24
24
  } from './placeholders'
25
+ import { composeRefs } from './composeRefs'
25
26
  import { warnIfChildren, warnOnce } from './warnings'
26
27
 
27
28
  /** How the image fits the view: see [`objectFit`](#objectfit). */
@@ -362,9 +363,10 @@ export interface FastImageProps extends AccessibilityProps, ViewProps {
362
363
  * - `FastImage.preload`, `getCachePath` and `writeToCache` take one size:
363
364
  * pass the one a view will show. An array fails with
364
365
  * `{ ok: false, error }`.
366
+ * - A `require()`d image can be one of the sizes: its size is the file's.
365
367
  * - An array of one is the same as that source.
366
368
  */
367
- source?: Source | Source[] | ImageRequireSource
369
+ source?: Source | Array<Source | ImageRequireSource> | ImageRequireSource
368
370
  /**
369
371
  * A placeholder shown while the image loads, and if it fails to load:
370
372
  *
@@ -398,7 +400,8 @@ export interface FastImageProps extends AccessibilityProps, ViewProps {
398
400
  | SourcePlaceholder
399
401
  | PlaceholderSource
400
402
  /**
401
- * @deprecated Use `placeholder`, which does the same.
403
+ * @deprecated Use `placeholder`, which does the same. With both,
404
+ * `placeholder` shows.
402
405
  */
403
406
  defaultSource?: ImageRequireSource
404
407
  /**
@@ -707,25 +710,6 @@ export interface FastImageProps extends AccessibilityProps, ViewProps {
707
710
  children?: "FastImage doesn't take children: use FastImageBackground for content over an image"
708
711
  }
709
712
 
710
- // A source without its thumbhash and blurDataUri.
711
- function withoutPlaceholders<T>(source: T): T {
712
- if (!hasSourcePlaceholder(source)) return source
713
- const {
714
- thumbhash: _thumbhash,
715
- blurDataUri: _blurDataUri,
716
- ...rest
717
- } = source as Source
718
- return rest as T
719
- }
720
-
721
- // What the native view shows while a source loads: its ThumbHash (decoded
722
- // natively), or its blurDataUri, or '' for neither.
723
- function sourcePlaceholder(source: unknown): string {
724
- if (!source || typeof source !== 'object') return ''
725
- const { thumbhash, blurDataUri } = source as Source
726
- return thumbhash || dataUri(blurDataUri) || ''
727
- }
728
-
729
713
  const resolvePlaceholder = (
730
714
  // A source object here has no url (e.g. { uri: name }, a bundled image).
731
715
  placeholder?: ImageRequireSource | string | PlaceholderSource,
@@ -911,58 +895,41 @@ function FastImageBase({
911
895
  const fit = resolveObjectFit(objectFit, style)
912
896
  const position = objectPositionOrCentered(objectPosition)
913
897
 
914
- // Memoized on source, so an unchanged source reaches the native view as
915
- // the same objects, and React's prop diff stops at them.
916
- // `placeholder` as a thumbhash or blurDataUri, for the sources without
917
- // their own: a string, so an object made on every render doesn't make
918
- // new sourcePlaceholders.
919
- const shared = hasSourcePlaceholder(placeholder)
920
- ? sourcePlaceholder(placeholder)
921
- : ''
922
- const { resolvedSource, sources, sourcePlaceholders } = useMemo(() => {
923
- // Several sources are picked from natively, for the view's size; one
924
- // in an array is a plain source.
925
- const sources = Array.isArray(source)
926
- ? source.length === 1
927
- ? undefined
928
- : source
929
- : undefined
930
- const single = Array.isArray(source) ? source[0] : source
931
- // Sources' thumbhashes and blurDataUris go to the native view apart
932
- // from the sources, so a new one for the same image doesn't load it
933
- // again, by the source's index ('' for none). A source's own wins
934
- // over `placeholder`'s.
935
- const placeholders = (sources ?? [single]).map(
936
- (entry) => sourcePlaceholder(entry) || shared,
937
- )
938
- return {
939
- resolvedSource: sources
940
- ? undefined
941
- : Image.resolveAssetSource(withoutPlaceholders(single) as any),
942
- sources: sources?.some(hasSourcePlaceholder)
943
- ? sources.map(withoutPlaceholders)
944
- : sources,
945
- sourcePlaceholders: placeholders.some(Boolean)
946
- ? placeholders
947
- : undefined,
898
+ // One source, or several in an array, picked from natively for the
899
+ // view's size (one in an array is a plain source), with their thumbhashes
900
+ // and blurDataUris: the native view doesn't load the image again when
901
+ // only those change. Memoized on source, so an unchanged source reaches
902
+ // the native view as the same object, and React's prop diff stops at it.
903
+ const resolvedSource = useMemo(() => {
904
+ // A blurDataUri that isn't a data uri is ignored, with a warning.
905
+ for (const entry of [source].flat()) {
906
+ dataUri((entry as Source | undefined)?.blurDataUri)
948
907
  }
949
- }, [source, shared])
950
- // A url in `placeholder` goes to the native view as a source, loaded
951
- // apart from the image, in place of defaultSource. A thumbhash or
952
- // blurDataUri goes in sourcePlaceholders instead: it isn't an image to
953
- // show as it is, but defaultSource still is.
954
- const resolvedPlaceholder =
955
- placeholderSource(placeholder) ??
956
- resolvePlaceholder(
957
- hasSourcePlaceholder(placeholder)
958
- ? defaultSource
959
- : (placeholder ?? defaultSource),
960
- )
908
+ const single =
909
+ Array.isArray(source) && source.length === 1 ? source[0] : source
910
+ return Array.isArray(single)
911
+ ? single.map((entry) => Image.resolveAssetSource(entry as any))
912
+ : Image.resolveAssetSource(single as any)
913
+ }, [source])
914
+ // `placeholder` as the native view takes it: a thumbhash or blurDataUri
915
+ // as it is (for the sources without their own), a url as a source loaded
916
+ // apart from the image, or an image shown at once. defaultSource only
917
+ // applies without one (an empty thumbhash or blurDataUri is none).
918
+ const resolvedPlaceholder = hasSourcePlaceholder(placeholder)
919
+ ? placeholder.thumbhash || dataUri(placeholder.blurDataUri)
920
+ ? placeholder
921
+ : resolvePlaceholder(defaultSource)
922
+ : (placeholderSource(placeholder) ??
923
+ resolvePlaceholder(placeholder ?? defaultSource))
924
+ const ref = useMemo(
925
+ () => composeRefs<FastImageRef>(addReload, forwardedRef),
926
+ [forwardedRef],
927
+ )
961
928
 
962
929
  return (
963
930
  <FastImageView
964
931
  {...props}
965
- ref={forwardedRef}
932
+ ref={ref}
966
933
  // Clips the image to borderRadius by default, as React Native's
967
934
  // Image does.
968
935
  style={[styles.image, style]}
@@ -974,8 +941,6 @@ function FastImageBase({
974
941
  defaultTransition ?? builtInTransition(),
975
942
  )}
976
943
  source={resolvedSource}
977
- sources={sources}
978
- sourcePlaceholders={sourcePlaceholders}
979
944
  placeholder={resolvedPlaceholder}
980
945
  onFastImageLoadStart={onLoadStart}
981
946
  onFastImageProgress={onProgress}
@@ -1007,19 +972,37 @@ function FastImageBase({
1007
972
  )
1008
973
  }
1009
974
 
975
+ // The ref is the native view, with reload() added, as React Native's
976
+ // TextInput adds its methods to its native view.
977
+ function addReload(view: FastImageRef | null) {
978
+ if (view) view.reload = () => Commands.reload(view as any)
979
+ }
980
+
1010
981
  const FastImageMemo = memo(FastImageBase)
1011
982
 
1012
- // What a ref to FastImage or FastImageBackground gets: FastImage's native
1013
- // view, or FastImageBackground's view. Typed as a View's (they have the same
1014
- // methods, e.g. measure). ComponentRef, as
1015
- // React Native's types declare View as a class, and its Strict TypeScript API
1016
- // (opt-in from 0.80, the default from 0.87) as a function component that takes
1017
- // a ref.
983
+ // What a ref to FastImageBackground gets (its view), and, with reload(), one
984
+ // to FastImage (its native view, which has the same methods, e.g. measure).
985
+ // ComponentRef, as React Native's types declare View as a class, and its
986
+ // Strict TypeScript API (opt-in from 0.80, the default from 0.87) as a
987
+ // function component that takes a ref.
1018
988
  type ViewRef = React.ComponentRef<typeof View>
1019
989
 
990
+ /**
991
+ * What a ref to `FastImage` gets: its native view, with a View's methods
992
+ * (e.g. `measure`), and `reload()`. E.g. `useRef<FastImageRef>(null)`.
993
+ */
994
+ export type FastImageRef = ViewRef & {
995
+ /**
996
+ * Loads the image again, e.g. to try again after `onError`. The image
997
+ * showing stays until the new one has loaded, and the events are sent as
998
+ * for a new source. An image in the cache loads from it.
999
+ */
1000
+ reload(): void
1001
+ }
1002
+
1020
1003
  const FastImageComponent: React.ForwardRefExoticComponent<
1021
- FastImageProps & React.RefAttributes<ViewRef>
1022
- > = forwardRef((props: FastImageProps, ref: React.Ref<ViewRef>) => (
1004
+ FastImageProps & React.RefAttributes<FastImageRef>
1005
+ > = forwardRef((props: FastImageProps, ref: React.Ref<FastImageRef>) => (
1023
1006
  <FastImageMemo forwardedRef={ref} {...props} />
1024
1007
  ))
1025
1008
 
@@ -1152,7 +1135,7 @@ export interface FastImageDefaults {
1152
1135
  }
1153
1136
 
1154
1137
  const FastImage: React.ForwardRefExoticComponent<
1155
- FastImageProps & React.RefAttributes<ViewRef>
1138
+ FastImageProps & React.RefAttributes<FastImageRef>
1156
1139
  > &
1157
1140
  FastImageStaticProperties = FastImageComponent as any
1158
1141
 
@@ -1263,7 +1246,7 @@ export interface FastImageBackgroundProps extends Omit<
1263
1246
  /** The image's style. */
1264
1247
  imageStyle?: StyleProp<ImageStyle>
1265
1248
  /** A ref to the image (the FastImage inside). */
1266
- imageRef?: React.Ref<any>
1249
+ imageRef?: React.Ref<FastImageRef>
1267
1250
  /** Content shown on top of the image. */
1268
1251
  children?: React.ReactNode
1269
1252
  }
package/src/index.web.tsx CHANGED
@@ -23,6 +23,7 @@ import React, {
23
23
  useEffect,
24
24
  useId,
25
25
  useLayoutEffect,
26
+ useMemo,
26
27
  useRef,
27
28
  useState,
28
29
  } from 'react'
@@ -37,12 +38,14 @@ import {
37
38
  hasSourcePlaceholder,
38
39
  placeholderSource,
39
40
  } from './placeholders'
41
+ import { composeRefs } from './composeRefs'
40
42
  import { warnIfChildren, warnOnce } from './warnings'
41
43
  import type {
42
44
  CachePathResult,
43
45
  CacheState,
44
46
  FastImageBackgroundProps,
45
47
  FastImageProps,
48
+ FastImageRef,
46
49
  FastImageStaticProperties,
47
50
  ObjectFit,
48
51
  PreloadResult,
@@ -126,6 +129,17 @@ function FastImageBase({
126
129
  // one doesn't stay while it loads; with several sizes, the <img> stays,
127
130
  // and the browser shows the previous image until the new one has loaded.
128
131
  const key = srcSet ?? src
132
+ // Counts the ref's reload() calls: each gives the image a new <img>, which
133
+ // the browser loads again (as a new view would). The image showing stays
134
+ // (it has loaded), or stays hidden (it failed), until then.
135
+ const [reloads, setReloads] = useState(0)
136
+ const ref = useMemo(
137
+ () =>
138
+ composeRefs((view: FastImageRef | null) => {
139
+ if (view) view.reload = () => setReloads((count) => count + 1)
140
+ }, forwardedRef),
141
+ [forwardedRef],
142
+ )
129
143
  const priority = sourcePriority(source)
130
144
  // The source's blurDataUri, or its ThumbHash made into one (with
131
145
  // `react-native-fast-image/thumbhash`), shows blurred (see PreviewBlur)
@@ -140,15 +154,21 @@ function FastImageBase({
140
154
  // placeholders as it loads, as on iOS and Android. The browser loads it
141
155
  // like any image: it can't look in its cache only (cache: 'cacheOnly').
142
156
  const urlPlaceholder = placeholderSource(placeholder)?.uri
157
+ // reload() gives it a new <img> too, so one that failed is asked for again.
158
+ const placeholderKey = `${urlPlaceholder} ${reloads}`
143
159
  const [failedPlaceholder, setFailedPlaceholder] = useState<string>()
144
- // A thumbhash or blurDataUri in `placeholder` isn't an image to show as it
145
- // is, nor is a url (above): defaultSource still is.
160
+ // defaultSource only shows without `placeholder`, as on iOS and Android,
161
+ // or in place of a thumbhash or blurDataUri the web can't show (one of
162
+ // several sizes', or a thumbhash without react-native-fast-image/thumbhash,
163
+ // or an empty one). Not with a url (above).
146
164
  const defaultUri =
147
165
  blurUri ??
148
166
  resolveUri(
149
- preview || urlPlaceholder
167
+ preview
150
168
  ? defaultSource
151
- : (placeholder ?? defaultSource),
169
+ : urlPlaceholder
170
+ ? undefined
171
+ : (placeholder ?? defaultSource),
152
172
  )
153
173
  // Whether the image for `key` loaded, or failed.
154
174
  const [result, setResult] = useState<{ key: string; ok: boolean }>()
@@ -175,7 +195,7 @@ function FastImageBase({
175
195
  if (key) onLoadStart?.()
176
196
  // Once per image the browser is asked for.
177
197
  // eslint-disable-next-line react-hooks/exhaustive-deps
178
- }, [key])
198
+ }, [key, reloads])
179
199
 
180
200
  return (
181
201
  <View
@@ -184,7 +204,7 @@ function FastImageBase({
184
204
  style={[styles.container, style]}
185
205
  onLayout={onLayout}
186
206
  pointerEvents={pointerEvents}
187
- ref={forwardedRef}
207
+ ref={ref}
188
208
  >
189
209
  {defaultUri && showDefault ? (
190
210
  <Picture
@@ -222,7 +242,7 @@ function FastImageBase({
222
242
  ) : null}
223
243
  {urlPlaceholder && showDefault ? (
224
244
  <Picture
225
- key={`placeholder ${urlPlaceholder}`}
245
+ key={`placeholder ${placeholderKey}`}
226
246
  src={urlPlaceholder}
227
247
  loading={loading}
228
248
  // It only helps if it comes before the image, as on iOS
@@ -237,14 +257,14 @@ function FastImageBase({
237
257
  // Tinted, not blurred, as on iOS and Android.
238
258
  filter={tintColor ? `url(#${tintId})` : undefined}
239
259
  // Nothing (no broken image icon) if it fails.
240
- hidden={failedPlaceholder === urlPlaceholder}
241
- onError={() => setFailedPlaceholder(urlPlaceholder)}
260
+ hidden={failedPlaceholder === placeholderKey}
261
+ onError={() => setFailedPlaceholder(placeholderKey)}
242
262
  alt=""
243
263
  />
244
264
  ) : null}
245
265
  {key && src ? (
246
266
  <Picture
247
- key={several ? 'sizes' : key}
267
+ key={`${several ? 'sizes' : key} ${reloads}`}
248
268
  src={src}
249
269
  srcSet={srcSet}
250
270
  sizes={sizes}
@@ -341,14 +361,7 @@ function resolveUri(source: unknown): string | undefined {
341
361
  if (typeof source === 'number') {
342
362
  const asset: PackagerAsset | undefined = getAssetByID(source)
343
363
  if (!asset) return undefined
344
- const scale = asset.scales.reduce(
345
- (best, scale) =>
346
- Math.abs(scale - PixelRatio.get()) <
347
- Math.abs(best - PixelRatio.get())
348
- ? scale
349
- : best,
350
- asset.scales[0] ?? 1,
351
- )
364
+ const scale = assetScale(asset)
352
365
  const suffix = scale !== 1 ? `@${scale}x` : ''
353
366
  uri = `${asset.httpServerLocation}/${asset.name}${suffix}.${asset.type}`
354
367
  } else if (typeof source === 'string') {
@@ -370,6 +383,36 @@ type PackagerAsset = {
370
383
  name: string
371
384
  type: string
372
385
  scales: number[]
386
+ width?: number
387
+ height?: number
388
+ }
389
+
390
+ // The scale of an asset's file closest to the screen's.
391
+ function assetScale(asset: PackagerAsset): number {
392
+ return asset.scales.reduce(
393
+ (best, scale) =>
394
+ Math.abs(scale - PixelRatio.get()) <
395
+ Math.abs(best - PixelRatio.get())
396
+ ? scale
397
+ : best,
398
+ asset.scales[0] ?? 1,
399
+ )
400
+ }
401
+
402
+ // One of several sizes: a require()d image in react-native-web's asset
403
+ // registry as a source with its file's size (Expo's web builds make it a
404
+ // { uri, width, height } object already).
405
+ function sizedSource(source: Source | number): Source | undefined {
406
+ if (typeof source !== 'number') return source
407
+ const asset: PackagerAsset | undefined = getAssetByID(source)
408
+ return asset
409
+ ? {
410
+ uri: resolveUri(source),
411
+ width: asset.width,
412
+ height: asset.height,
413
+ scale: assetScale(asset),
414
+ }
415
+ : undefined
373
416
  }
374
417
 
375
418
  // Several sizes of an image, as a srcset (each size's width, times its
@@ -379,9 +422,10 @@ type PackagerAsset = {
379
422
  // is laid out at; it only applies to lazy images, and otherwise, or in
380
423
  // browsers without it, the next value, 100vw (the viewport's width). src is the largest, for browsers without
381
424
  // srcset.
382
- function sizedSources(sources: Source[]) {
425
+ function sizedSources(entries: (Source | number)[]) {
426
+ const sources = entries.map(sizedSource)
383
427
  const widths = sources
384
- .filter((source) => source?.uri && source.width)
428
+ .filter((source): source is Source => !!source?.uri && !!source.width)
385
429
  .map((source) => ({
386
430
  uri: source.uri as string,
387
431
  width: Math.round((source.width ?? 0) * (source.scale ?? 1)),
@@ -625,11 +669,15 @@ const tintStyle = {
625
669
 
626
670
  const FastImageMemo = memo(FastImageBase)
627
671
 
628
- const FastImageComponent: React.ComponentType<FastImageProps> = forwardRef(
629
- (props: FastImageProps, ref: React.Ref<any>) => (
630
- <FastImageMemo forwardedRef={ref} {...props} />
631
- ),
632
- )
672
+ // What a ref to FastImageBackground gets, as in index.tsx: a View's
673
+ // (react-native-web's element). FastImage's has reload() too (FastImageRef).
674
+ type ViewRef = React.ComponentRef<typeof View>
675
+
676
+ const FastImageComponent: React.ForwardRefExoticComponent<
677
+ FastImageProps & React.RefAttributes<FastImageRef>
678
+ > = forwardRef((props: FastImageProps, ref: React.Ref<FastImageRef>) => (
679
+ <FastImageMemo forwardedRef={ref} {...props} />
680
+ ))
633
681
 
634
682
  FastImageComponent.displayName = 'FastImage'
635
683
 
@@ -644,7 +692,9 @@ function getSize(uri: string) {
644
692
  })
645
693
  }
646
694
 
647
- const FastImage: React.ComponentType<FastImageProps> &
695
+ const FastImage: React.ForwardRefExoticComponent<
696
+ FastImageProps & React.RefAttributes<FastImageRef>
697
+ > &
648
698
  FastImageStaticProperties = FastImageComponent as any
649
699
 
650
700
  FastImage.cacheControl = cacheControl
@@ -692,33 +742,29 @@ const styles = StyleSheet.create({
692
742
  },
693
743
  })
694
744
 
695
- // FastImage forwards its ref, which its type doesn't say.
696
- const FastImageWithRef = FastImageComponent as React.ComponentType<
697
- FastImageProps & { ref?: React.Ref<any> }
698
- >
699
-
700
- export const FastImageBackground: React.ComponentType<FastImageBackgroundProps> =
701
- forwardRef(
702
- (
703
- {
704
- style,
705
- imageStyle,
706
- imageRef,
707
- children,
708
- ...props
709
- }: FastImageBackgroundProps,
710
- ref: React.Ref<any>,
711
- ) => (
712
- <View style={style} ref={ref}>
713
- <FastImageWithRef
714
- {...props}
715
- style={[StyleSheet.absoluteFill, imageStyle]}
716
- ref={imageRef}
717
- />
718
- {children}
719
- </View>
720
- ),
721
- )
745
+ export const FastImageBackground: React.ForwardRefExoticComponent<
746
+ FastImageBackgroundProps & React.RefAttributes<ViewRef>
747
+ > = forwardRef(
748
+ (
749
+ {
750
+ style,
751
+ imageStyle,
752
+ imageRef,
753
+ children,
754
+ ...props
755
+ }: FastImageBackgroundProps,
756
+ ref: React.Ref<ViewRef>,
757
+ ) => (
758
+ <View style={style} ref={ref}>
759
+ <FastImageComponent
760
+ {...props}
761
+ style={[StyleSheet.absoluteFill, imageStyle]}
762
+ ref={imageRef}
763
+ />
764
+ {children}
765
+ </View>
766
+ ),
767
+ )
722
768
 
723
769
  FastImageBackground.displayName = 'FastImageBackground'
724
770
 
@@ -1,15 +1,16 @@
1
1
  // The native image view, from React Native's Codegen (the New Architecture's
2
2
  // component). FastImage (index.tsx) renders it as its only view, and turns
3
3
  // its props into these.
4
+ import type * as React from 'react'
4
5
  import type {
5
6
  CodegenTypes,
6
7
  ColorValue,
7
8
  HostComponent,
8
9
  ViewProps,
9
10
  } from 'react-native'
10
- // React Native's Babel plugin replaces the call below with the component's
11
- // view config, so the import isn't used when the app runs.
12
- import { codegenNativeComponent } from 'react-native'
11
+ // React Native's Babel plugin replaces the calls below with the component's
12
+ // view config and commands, so the imports aren't used when the app runs.
13
+ import { codegenNativeCommands, codegenNativeComponent } from 'react-native'
13
14
 
14
15
  type LoadStartEvent = Readonly<{}>
15
16
 
@@ -40,21 +41,18 @@ type LoadEndEvent = Readonly<{
40
41
  }>
41
42
 
42
43
  export interface NativeProps extends ViewProps {
43
- // A source ({ uri, headers, priority, cache, ... }), as the native
44
- // sides read it.
44
+ // The `source` prop: a source ({ uri, headers, priority, cache, ... },
45
+ // with its thumbhash or blurDataUri), or several (sizes of one image) in
46
+ // an array, picked from for the view's size. A change to the thumbhashes
47
+ // and blurDataUris only doesn't load the image again.
45
48
  source?: CodegenTypes.UnsafeMixed
46
- // Several sources (sizes of one image), picked from for the view's size.
47
- sources?: CodegenTypes.UnsafeMixed
48
- // The `placeholder` prop: a url to load apart from the image, as a source
49
- // ({ uri, headers, cacheKey, cache }), or an image shown at once: a
50
- // resolved asset source ({ uri, width, height, scale }) or a data uri
51
- // ({ uri } on iOS; the uri on Android, as a string).
49
+ // The `placeholder` prop: a thumbhash or blurDataUri ({ thumbhash } or
50
+ // { blurDataUri }, for the sources without their own), a url to load
51
+ // apart from the image, as a source ({ uri, headers, cacheKey, cache }),
52
+ // or an image shown at once: a resolved asset source ({ uri, width,
53
+ // height, scale }) or a data uri ({ uri } on iOS; the uri on Android, as
54
+ // a string).
52
55
  placeholder?: CodegenTypes.UnsafeMixed
53
- // What shows in place of placeholder while a source loads: its ThumbHash,
54
- // or its blurDataUri (blurred natively), by the source's index ('' for
55
- // none; one for a single source). Apart from the sources, so a new one
56
- // for the same image doesn't load it again.
57
- sourcePlaceholders?: ReadonlyArray<string>
58
56
  // objectFit, resolved (fill, contain, cover, none or scale-down).
59
57
  objectFit?: CodegenTypes.WithDefault<string, 'cover'>
60
58
  // objectPosition, as CSS computes it: on each axis the image's left or top
@@ -89,6 +87,17 @@ export interface NativeProps extends ViewProps {
89
87
  onFastImageLoadEnd?: CodegenTypes.DirectEventHandler<LoadEndEvent>
90
88
  }
91
89
 
90
+ interface NativeCommands {
91
+ // Loads the image again, as a new source would (with its events), keeping
92
+ // the image showing until then. ElementRef, which React Native 0.83's
93
+ // Codegen needs (later ones also take ComponentRef).
94
+ reload: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void
95
+ }
96
+
97
+ export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
98
+ supportedCommands: ['reload'],
99
+ })
100
+
92
101
  export default codegenNativeComponent<NativeProps>(
93
102
  'FastImageView',
94
103
  ) as HostComponent<NativeProps>