Image.ios.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @flow
  8. * @format
  9. */
  10. 'use strict';
  11. const DeprecatedImagePropType = require('../DeprecatedPropTypes/DeprecatedImagePropType');
  12. const React = require('react');
  13. const ReactNative = require('../Renderer/shims/ReactNative'); // eslint-disable-line no-unused-vars
  14. const StyleSheet = require('../StyleSheet/StyleSheet');
  15. const flattenStyle = require('../StyleSheet/flattenStyle');
  16. const resolveAssetSource = require('./resolveAssetSource');
  17. import type {ImageProps as ImagePropsType} from './ImageProps';
  18. import type {ImageStyleProp} from '../StyleSheet/StyleSheet';
  19. import NativeImageLoaderIOS from './NativeImageLoaderIOS';
  20. import ImageViewNativeComponent from './ImageViewNativeComponent';
  21. function getSize(
  22. uri: string,
  23. success: (width: number, height: number) => void,
  24. failure?: (error: any) => void,
  25. ) {
  26. NativeImageLoaderIOS.getSize(uri)
  27. .then(([width, height]) => success(width, height))
  28. .catch(
  29. failure ||
  30. function() {
  31. console.warn('Failed to get size for image ' + uri);
  32. },
  33. );
  34. }
  35. function getSizeWithHeaders(
  36. uri: string,
  37. headers: {[string]: string, ...},
  38. success: (width: number, height: number) => void,
  39. failure?: (error: any) => void,
  40. ): any {
  41. return NativeImageLoaderIOS.getSizeWithHeaders(uri, headers)
  42. .then(function(sizes) {
  43. success(sizes.width, sizes.height);
  44. })
  45. .catch(
  46. failure ||
  47. function() {
  48. console.warn('Failed to get size for image: ' + uri);
  49. },
  50. );
  51. }
  52. function prefetch(url: string): any {
  53. return NativeImageLoaderIOS.prefetchImage(url);
  54. }
  55. async function queryCache(
  56. urls: Array<string>,
  57. ): Promise<{[string]: 'memory' | 'disk' | 'disk/memory', ...}> {
  58. return await NativeImageLoaderIOS.queryCache(urls);
  59. }
  60. type ImageComponentStatics = $ReadOnly<{|
  61. getSize: typeof getSize,
  62. getSizeWithHeaders: typeof getSizeWithHeaders,
  63. prefetch: typeof prefetch,
  64. queryCache: typeof queryCache,
  65. resolveAssetSource: typeof resolveAssetSource,
  66. propTypes: typeof DeprecatedImagePropType,
  67. |}>;
  68. /**
  69. * A React component for displaying different types of images,
  70. * including network images, static resources, temporary local images, and
  71. * images from local disk, such as the camera roll.
  72. *
  73. * See https://reactnative.dev/docs/image.html
  74. */
  75. let Image = (props: ImagePropsType, forwardedRef) => {
  76. const source = resolveAssetSource(props.source) || {
  77. uri: undefined,
  78. width: undefined,
  79. height: undefined,
  80. };
  81. let sources;
  82. let style: ImageStyleProp;
  83. if (Array.isArray(source)) {
  84. // $FlowFixMe flattenStyle is not strong enough
  85. style = flattenStyle([styles.base, props.style]) || {};
  86. sources = source;
  87. } else {
  88. const {width, height, uri} = source;
  89. // $FlowFixMe flattenStyle is not strong enough
  90. style = flattenStyle([{width, height}, styles.base, props.style]) || {};
  91. sources = [source];
  92. if (uri === '') {
  93. console.warn('source.uri should not be an empty string');
  94. }
  95. }
  96. const resizeMode = props.resizeMode || style.resizeMode || 'cover';
  97. const tintColor = style.tintColor;
  98. if (props.src != null) {
  99. console.warn(
  100. 'The <Image> component requires a `source` property rather than `src`.',
  101. );
  102. }
  103. if (props.children != null) {
  104. throw new Error(
  105. 'The <Image> component cannot contain children. If you want to render content on top of the image, consider using the <ImageBackground> component or absolute positioning.',
  106. );
  107. }
  108. return (
  109. <ImageViewNativeComponent
  110. {...props}
  111. ref={forwardedRef}
  112. style={style}
  113. resizeMode={resizeMode}
  114. tintColor={tintColor}
  115. source={sources}
  116. />
  117. );
  118. };
  119. Image = React.forwardRef<
  120. ImagePropsType,
  121. React.ElementRef<typeof ImageViewNativeComponent>,
  122. >(Image);
  123. Image.displayName = 'Image';
  124. /**
  125. * Retrieve the width and height (in pixels) of an image prior to displaying it.
  126. *
  127. * See https://reactnative.dev/docs/image.html#getsize
  128. */
  129. /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an
  130. * error found when Flow v0.89 was deployed. To see the error, delete this
  131. * comment and run Flow. */
  132. Image.getSize = getSize;
  133. /**
  134. * Retrieve the width and height (in pixels) of an image prior to displaying it
  135. * with the ability to provide the headers for the request.
  136. *
  137. * See https://reactnative.dev/docs/image.html#getsizewithheaders
  138. */
  139. /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an
  140. * error found when Flow v0.89 was deployed. To see the error, delete this
  141. * comment and run Flow. */
  142. Image.getSizeWithHeaders = getSizeWithHeaders;
  143. /**
  144. * Prefetches a remote image for later use by downloading it to the disk
  145. * cache.
  146. *
  147. * See https://reactnative.dev/docs/image.html#prefetch
  148. */
  149. /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an
  150. * error found when Flow v0.89 was deployed. To see the error, delete this
  151. * comment and run Flow. */
  152. Image.prefetch = prefetch;
  153. /**
  154. * Performs cache interrogation.
  155. *
  156. * See https://reactnative.dev/docs/image.html#querycache
  157. */
  158. /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an
  159. * error found when Flow v0.89 was deployed. To see the error, delete this
  160. * comment and run Flow. */
  161. Image.queryCache = queryCache;
  162. /**
  163. * Resolves an asset reference into an object.
  164. *
  165. * See https://reactnative.dev/docs/image.html#resolveassetsource
  166. */
  167. /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an
  168. * error found when Flow v0.89 was deployed. To see the error, delete this
  169. * comment and run Flow. */
  170. Image.resolveAssetSource = resolveAssetSource;
  171. /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an
  172. * error found when Flow v0.89 was deployed. To see the error, delete this
  173. * comment and run Flow. */
  174. Image.propTypes = DeprecatedImagePropType;
  175. const styles = StyleSheet.create({
  176. base: {
  177. overflow: 'hidden',
  178. },
  179. });
  180. module.exports = ((Image: any): React.AbstractComponent<
  181. ImagePropsType,
  182. React.ElementRef<typeof ImageViewNativeComponent>,
  183. > &
  184. ImageComponentStatics);