@amazon-devices/expo-image 2.0.1758683737

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 (289) hide show
  1. package/.eslintrc.js +2 -0
  2. package/CHANGELOG.md +285 -0
  3. package/CMakeLists.txt +91 -0
  4. package/LICENSE +7 -0
  5. package/README.kepler.md +123 -0
  6. package/README.md +54 -0
  7. package/THIRD_PARTY_NOTICES.txt +24 -0
  8. package/android/build.gradle +124 -0
  9. package/android/proguard-rules.pro +28 -0
  10. package/android/src/main/AndroidManifest.xml +15 -0
  11. package/android/src/main/java/expo/modules/image/Exceptions.kt +9 -0
  12. package/android/src/main/java/expo/modules/image/ExpoImageAppGlideModule.kt +19 -0
  13. package/android/src/main/java/expo/modules/image/ExpoImageModule.kt +192 -0
  14. package/android/src/main/java/expo/modules/image/ExpoImageView.kt +220 -0
  15. package/android/src/main/java/expo/modules/image/ExpoImageViewWrapper.kt +652 -0
  16. package/android/src/main/java/expo/modules/image/GlideModel.kt +73 -0
  17. package/android/src/main/java/expo/modules/image/ImageUtils.kt +50 -0
  18. package/android/src/main/java/expo/modules/image/ImageViewWrapperTarget.kt +313 -0
  19. package/android/src/main/java/expo/modules/image/ResourceIdHelper.kt +47 -0
  20. package/android/src/main/java/expo/modules/image/ThumbnailRequestCoordinatorExtension.kt +21 -0
  21. package/android/src/main/java/expo/modules/image/YogaUtils.kt +20 -0
  22. package/android/src/main/java/expo/modules/image/blurhash/BlurHashFetcher.kt +32 -0
  23. package/android/src/main/java/expo/modules/image/blurhash/BlurhashDecoder.kt +189 -0
  24. package/android/src/main/java/expo/modules/image/blurhash/BlurhashModelLoader.kt +30 -0
  25. package/android/src/main/java/expo/modules/image/blurhash/BlurhashModelLoaderFactory.kt +14 -0
  26. package/android/src/main/java/expo/modules/image/blurhash/BlurhashModule.kt +17 -0
  27. package/android/src/main/java/expo/modules/image/dataurls/Base64DataFetcher.kt +27 -0
  28. package/android/src/main/java/expo/modules/image/dataurls/Base64ModelLoader.kt +24 -0
  29. package/android/src/main/java/expo/modules/image/dataurls/Base64ModelLoaderFactory.kt +12 -0
  30. package/android/src/main/java/expo/modules/image/dataurls/Base64Module.kt +16 -0
  31. package/android/src/main/java/expo/modules/image/drawing/OutlineProvider.kt +201 -0
  32. package/android/src/main/java/expo/modules/image/enums/ContentFit.kt +89 -0
  33. package/android/src/main/java/expo/modules/image/enums/ImageCacheType.kt +14 -0
  34. package/android/src/main/java/expo/modules/image/enums/Priority.kt +15 -0
  35. package/android/src/main/java/expo/modules/image/events/GlideRequestListener.kt +64 -0
  36. package/android/src/main/java/expo/modules/image/events/OkHttpProgressListener.kt +26 -0
  37. package/android/src/main/java/expo/modules/image/okhttp/ExpoImageOkHttpClientGlideModule.kt +80 -0
  38. package/android/src/main/java/expo/modules/image/okhttp/GlideUrlWrapperLoader.kt +55 -0
  39. package/android/src/main/java/expo/modules/image/records/CachePolicy.kt +10 -0
  40. package/android/src/main/java/expo/modules/image/records/ContentPosition.kt +89 -0
  41. package/android/src/main/java/expo/modules/image/records/ImageTransition.kt +8 -0
  42. package/android/src/main/java/expo/modules/image/records/SourceMap.kt +160 -0
  43. package/android/src/main/java/expo/modules/image/records/events.kt +25 -0
  44. package/android/src/main/java/expo/modules/image/svg/SVGDecoder.kt +33 -0
  45. package/android/src/main/java/expo/modules/image/svg/SVGDrawableTranscoder.kt +37 -0
  46. package/android/src/main/java/expo/modules/image/svg/SVGModule.kt +26 -0
  47. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashDecoder.kt +365 -0
  48. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashFetcher.kt +31 -0
  49. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashModelLoader.kt +26 -0
  50. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashModelLoaderFactory.kt +14 -0
  51. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashModule.kt +17 -0
  52. package/build/ExpoImage.d.ts +15 -0
  53. package/build/ExpoImage.d.ts.map +1 -0
  54. package/build/ExpoImage.js +75 -0
  55. package/build/ExpoImage.js.map +1 -0
  56. package/build/ExpoImage.kepler.d.ts +23 -0
  57. package/build/ExpoImage.kepler.d.ts.map +1 -0
  58. package/build/ExpoImage.kepler.js +71 -0
  59. package/build/ExpoImage.kepler.js.map +1 -0
  60. package/build/ExpoImage.web.d.ts +9 -0
  61. package/build/ExpoImage.web.d.ts.map +1 -0
  62. package/build/ExpoImage.web.js +90 -0
  63. package/build/ExpoImage.web.js.map +1 -0
  64. package/build/ExpoImageModules.d.ts +3 -0
  65. package/build/ExpoImageModules.d.ts.map +1 -0
  66. package/build/ExpoImageModules.js +4 -0
  67. package/build/ExpoImageModules.js.map +1 -0
  68. package/build/ExpoImageModules.kepler.d.ts +6 -0
  69. package/build/ExpoImageModules.kepler.d.ts.map +1 -0
  70. package/build/ExpoImageModules.kepler.js +5 -0
  71. package/build/ExpoImageModules.kepler.js.map +1 -0
  72. package/build/Image.d.ts +30 -0
  73. package/build/Image.d.ts.map +1 -0
  74. package/build/Image.js +49 -0
  75. package/build/Image.js.map +1 -0
  76. package/build/Image.types.d.ts +374 -0
  77. package/build/Image.types.d.ts.map +1 -0
  78. package/build/Image.types.js +2 -0
  79. package/build/Image.types.js.map +1 -0
  80. package/build/ImageBackground.d.ts +6 -0
  81. package/build/ImageBackground.d.ts.map +1 -0
  82. package/build/ImageBackground.js +13 -0
  83. package/build/ImageBackground.js.map +1 -0
  84. package/build/ImageViewNativeComponent.d.ts +20 -0
  85. package/build/ImageViewNativeComponent.d.ts.map +1 -0
  86. package/build/ImageViewNativeComponent.js +42 -0
  87. package/build/ImageViewNativeComponent.js.map +1 -0
  88. package/build/NativeImageLoaderKepler.d.ts +18 -0
  89. package/build/NativeImageLoaderKepler.d.ts.map +1 -0
  90. package/build/NativeImageLoaderKepler.js +3 -0
  91. package/build/NativeImageLoaderKepler.js.map +1 -0
  92. package/build/fabric/registerNativeComponent.d.ts +15 -0
  93. package/build/fabric/registerNativeComponent.d.ts.map +1 -0
  94. package/build/fabric/registerNativeComponent.js +47 -0
  95. package/build/fabric/registerNativeComponent.js.map +1 -0
  96. package/build/index.d.ts +4 -0
  97. package/build/index.d.ts.map +1 -0
  98. package/build/index.js +4 -0
  99. package/build/index.js.map +1 -0
  100. package/build/utils/AssetSourceResolver.web.d.ts +24 -0
  101. package/build/utils/AssetSourceResolver.web.d.ts.map +1 -0
  102. package/build/utils/AssetSourceResolver.web.js +67 -0
  103. package/build/utils/AssetSourceResolver.web.js.map +1 -0
  104. package/build/utils/blurhash/base83.d.ts +3 -0
  105. package/build/utils/blurhash/base83.d.ts.map +1 -0
  106. package/build/utils/blurhash/base83.js +103 -0
  107. package/build/utils/blurhash/base83.js.map +1 -0
  108. package/build/utils/blurhash/decode.d.ts +7 -0
  109. package/build/utils/blurhash/decode.d.ts.map +1 -0
  110. package/build/utils/blurhash/decode.js +92 -0
  111. package/build/utils/blurhash/decode.js.map +1 -0
  112. package/build/utils/blurhash/error.d.ts +4 -0
  113. package/build/utils/blurhash/error.d.ts.map +1 -0
  114. package/build/utils/blurhash/error.js +8 -0
  115. package/build/utils/blurhash/error.js.map +1 -0
  116. package/build/utils/blurhash/useBlurhash.d.ts +8 -0
  117. package/build/utils/blurhash/useBlurhash.d.ts.map +1 -0
  118. package/build/utils/blurhash/useBlurhash.js +64 -0
  119. package/build/utils/blurhash/useBlurhash.js.map +1 -0
  120. package/build/utils/blurhash/utils.d.ts +5 -0
  121. package/build/utils/blurhash/utils.d.ts.map +1 -0
  122. package/build/utils/blurhash/utils.js +21 -0
  123. package/build/utils/blurhash/utils.js.map +1 -0
  124. package/build/utils/resolveAssetSource.d.ts +3 -0
  125. package/build/utils/resolveAssetSource.d.ts.map +1 -0
  126. package/build/utils/resolveAssetSource.js +3 -0
  127. package/build/utils/resolveAssetSource.js.map +1 -0
  128. package/build/utils/resolveAssetSource.web.d.ts +9 -0
  129. package/build/utils/resolveAssetSource.web.d.ts.map +1 -0
  130. package/build/utils/resolveAssetSource.web.js +31 -0
  131. package/build/utils/resolveAssetSource.web.js.map +1 -0
  132. package/build/utils/resolveHashString.d.ts +14 -0
  133. package/build/utils/resolveHashString.d.ts.map +1 -0
  134. package/build/utils/resolveHashString.js +31 -0
  135. package/build/utils/resolveHashString.js.map +1 -0
  136. package/build/utils/resolveHashString.web.d.ts +20 -0
  137. package/build/utils/resolveHashString.web.d.ts.map +1 -0
  138. package/build/utils/resolveHashString.web.js +31 -0
  139. package/build/utils/resolveHashString.web.js.map +1 -0
  140. package/build/utils/resolveSources.d.ts +8 -0
  141. package/build/utils/resolveSources.d.ts.map +1 -0
  142. package/build/utils/resolveSources.js +45 -0
  143. package/build/utils/resolveSources.js.map +1 -0
  144. package/build/utils/thumbhash/thumbhash.d.ts +66 -0
  145. package/build/utils/thumbhash/thumbhash.d.ts.map +1 -0
  146. package/build/utils/thumbhash/thumbhash.js +338 -0
  147. package/build/utils/thumbhash/thumbhash.js.map +1 -0
  148. package/build/utils.d.ts +17 -0
  149. package/build/utils.d.ts.map +1 -0
  150. package/build/utils.js +85 -0
  151. package/build/utils.js.map +1 -0
  152. package/build/web/AnimationManager.d.ts +37 -0
  153. package/build/web/AnimationManager.d.ts.map +1 -0
  154. package/build/web/AnimationManager.js +155 -0
  155. package/build/web/AnimationManager.js.map +1 -0
  156. package/build/web/ColorTintFilter.d.ts +12 -0
  157. package/build/web/ColorTintFilter.d.ts.map +1 -0
  158. package/build/web/ColorTintFilter.js +30 -0
  159. package/build/web/ColorTintFilter.js.map +1 -0
  160. package/build/web/ImageWrapper.d.ts +5 -0
  161. package/build/web/ImageWrapper.d.ts.map +1 -0
  162. package/build/web/ImageWrapper.js +44 -0
  163. package/build/web/ImageWrapper.js.map +1 -0
  164. package/build/web/ImageWrapper.types.d.ts +29 -0
  165. package/build/web/ImageWrapper.types.d.ts.map +1 -0
  166. package/build/web/ImageWrapper.types.js +2 -0
  167. package/build/web/ImageWrapper.types.js.map +1 -0
  168. package/build/web/getImageWrapperEventHandler.d.ts +8 -0
  169. package/build/web/getImageWrapperEventHandler.d.ts.map +1 -0
  170. package/build/web/getImageWrapperEventHandler.js +25 -0
  171. package/build/web/getImageWrapperEventHandler.js.map +1 -0
  172. package/build/web/hooks.d.ts +13 -0
  173. package/build/web/hooks.d.ts.map +1 -0
  174. package/build/web/hooks.js +58 -0
  175. package/build/web/hooks.js.map +1 -0
  176. package/build/web/imageStyles.d.ts +2 -0
  177. package/build/web/imageStyles.d.ts.map +1 -0
  178. package/build/web/imageStyles.js +137 -0
  179. package/build/web/imageStyles.js.map +1 -0
  180. package/build/web/positioning.d.ts +11 -0
  181. package/build/web/positioning.d.ts.map +1 -0
  182. package/build/web/positioning.js +35 -0
  183. package/build/web/positioning.js.map +1 -0
  184. package/build/web/useSourceSelection.d.ts +14 -0
  185. package/build/web/useSourceSelection.d.ts.map +1 -0
  186. package/build/web/useSourceSelection.js +98 -0
  187. package/build/web/useSourceSelection.js.map +1 -0
  188. package/expo-module.config.json +9 -0
  189. package/ios/Blurhash.swift +326 -0
  190. package/ios/BlurhashLoader.swift +52 -0
  191. package/ios/ContentFit.swift +55 -0
  192. package/ios/ContentPosition.swift +108 -0
  193. package/ios/ExpoImage.podspec +30 -0
  194. package/ios/ImageCachePolicy.swift +24 -0
  195. package/ios/ImageCacheType.swift +21 -0
  196. package/ios/ImageModule.swift +127 -0
  197. package/ios/ImagePriority.swift +22 -0
  198. package/ios/ImageSource.swift +44 -0
  199. package/ios/ImageTransition.swift +67 -0
  200. package/ios/ImageUtils.swift +227 -0
  201. package/ios/ImageView.swift +469 -0
  202. package/ios/Loaders/PhotoLibraryAssetLoader.swift +146 -0
  203. package/ios/Thumbhash.swift +550 -0
  204. package/ios/ThumbhashLoader.swift +53 -0
  205. package/jest.config.js +3 -0
  206. package/kepler/ExpoImage.cpp +63 -0
  207. package/kepler/ExpoImage.h +29 -0
  208. package/kepler/ExpoImageCacheHandler.cpp +15 -0
  209. package/kepler/ExpoImageCacheHandler.h +28 -0
  210. package/kepler/ExpoImageComponent.cpp +579 -0
  211. package/kepler/ExpoImageComponent.h +199 -0
  212. package/kepler/ImageWrapper/BlurhashImageWrapper.cpp +37 -0
  213. package/kepler/ImageWrapper/BlurhashImageWrapper.h +23 -0
  214. package/kepler/ImageWrapper/CacheImageWrapper.cpp +80 -0
  215. package/kepler/ImageWrapper/CacheImageWrapper.h +41 -0
  216. package/kepler/ImageWrapper/HashImageWrapper.cpp +21 -0
  217. package/kepler/ImageWrapper/HashImageWrapper.h +22 -0
  218. package/kepler/ImageWrapper/ImageWrapper.cpp +24 -0
  219. package/kepler/ImageWrapper/ImageWrapper.h +33 -0
  220. package/kepler/ImageWrapper/LocalImageWrapper.cpp +61 -0
  221. package/kepler/ImageWrapper/LocalImageWrapper.h +30 -0
  222. package/kepler/ImageWrapper/ThumbhashImageWrapper.cpp +33 -0
  223. package/kepler/ImageWrapper/ThumbhashImageWrapper.h +20 -0
  224. package/kepler/KeplerImageViewComponent.h +64 -0
  225. package/kepler/KeplerInit.cpp +35 -0
  226. package/kepler/blurhash/common.h +32 -0
  227. package/kepler/blurhash/decode.cpp +187 -0
  228. package/kepler/blurhash/decode.h +58 -0
  229. package/kepler/contentposition/ImageContentPosition.cpp +86 -0
  230. package/kepler/contentposition/ImageContentPosition.h +48 -0
  231. package/kepler/enums/ImageContentFit.h +17 -0
  232. package/kepler/enums/ImagePriority.h +17 -0
  233. package/kepler/managers/ExpoImageManager.cpp +38 -0
  234. package/kepler/managers/ExpoImageManager.h +23 -0
  235. package/kepler/test/ExpoImage.cpp +73 -0
  236. package/kepler/test/ExpoImageComponent.cpp +290 -0
  237. package/kepler/test/blurhash/decode.cpp +39 -0
  238. package/kepler/test/contentposition/ImageContentPosition.cpp +100 -0
  239. package/kepler/test/managers/ExpoImageManager.cpp +39 -0
  240. package/kepler/test/thumbhash/decode.cpp +18 -0
  241. package/kepler/test/utils/LoaderDelegate.cpp +130 -0
  242. package/kepler/thumbhash/decode.cpp +166 -0
  243. package/kepler/thumbhash/decode.h +22 -0
  244. package/kepler/utils/PlaceholderImageLoaderDelegate.cpp +26 -0
  245. package/kepler/utils/PlaceholderImageLoaderDelegate.h +26 -0
  246. package/kepler/utils/PrefetchImageLoaderDelegate.cpp +55 -0
  247. package/kepler/utils/PrefetchImageLoaderDelegate.h +35 -0
  248. package/kepler/utils/SourceImageLoaderDelegate.cpp +47 -0
  249. package/kepler/utils/SourceImageLoaderDelegate.h +42 -0
  250. package/kepler/utils/SourceImageLoaderDelegateEmitter.cpp +15 -0
  251. package/kepler/utils/SourceImageLoaderDelegateEmitter.h +28 -0
  252. package/kepler-compatibility.json +8 -0
  253. package/package.json +1 -0
  254. package/react-native.config.js +22 -0
  255. package/src/ExpoImage.kepler.tsx +119 -0
  256. package/src/ExpoImage.tsx +119 -0
  257. package/src/ExpoImage.web.tsx +155 -0
  258. package/src/ExpoImageModules.kepler.ts +7 -0
  259. package/src/ExpoImageModules.ts +4 -0
  260. package/src/Image.tsx +82 -0
  261. package/src/Image.types.ts +450 -0
  262. package/src/ImageBackground.tsx +18 -0
  263. package/src/ImageViewNativeComponent.ts +59 -0
  264. package/src/NativeImageLoaderKepler.ts +22 -0
  265. package/src/fabric/registerNativeComponent.ts +70 -0
  266. package/src/index.ts +3 -0
  267. package/src/utils/AssetSourceResolver.web.ts +88 -0
  268. package/src/utils/blurhash/base83.ts +104 -0
  269. package/src/utils/blurhash/decode.ts +114 -0
  270. package/src/utils/blurhash/error.ts +7 -0
  271. package/src/utils/blurhash/useBlurhash.tsx +81 -0
  272. package/src/utils/blurhash/utils.ts +21 -0
  273. package/src/utils/resolveAssetSource.tsx +3 -0
  274. package/src/utils/resolveAssetSource.web.ts +40 -0
  275. package/src/utils/resolveHashString.tsx +36 -0
  276. package/src/utils/resolveHashString.web.tsx +33 -0
  277. package/src/utils/resolveSources.tsx +48 -0
  278. package/src/utils/thumbhash/thumbhash.ts +387 -0
  279. package/src/utils.ts +109 -0
  280. package/src/web/AnimationManager.tsx +224 -0
  281. package/src/web/ColorTintFilter.tsx +36 -0
  282. package/src/web/ImageWrapper.tsx +85 -0
  283. package/src/web/ImageWrapper.types.ts +36 -0
  284. package/src/web/getImageWrapperEventHandler.ts +29 -0
  285. package/src/web/hooks.ts +72 -0
  286. package/src/web/imageStyles.tsx +136 -0
  287. package/src/web/positioning.ts +48 -0
  288. package/src/web/useSourceSelection.ts +151 -0
  289. package/tsconfig.json +9 -0
@@ -0,0 +1,119 @@
1
+ import { requireNativeViewManager, requireNativeModule } from 'expo-modules-core';
2
+ import React from 'react';
3
+ import { NativeSyntheticEvent, StyleSheet, Platform, processColor } from 'react-native';
4
+
5
+ import {
6
+ ImageErrorEventData,
7
+ ImageLoadEventData,
8
+ ImageNativeProps,
9
+ ImageProgressEventData,
10
+ } from './Image.types';
11
+
12
+ const NativeExpoImage = requireNativeViewManager('ExpoImage');
13
+
14
+ const ExpoImageModule = requireNativeModule('ExpoImage');
15
+
16
+ function withDeprecatedNativeEvent<NativeEvent>(
17
+ event: NativeSyntheticEvent<NativeEvent>
18
+ ): NativeEvent {
19
+ Object.defineProperty(event.nativeEvent, 'nativeEvent', {
20
+ get() {
21
+ console.warn(
22
+ '[expo-image]: Accessing event payload through "nativeEvent" is deprecated, it is now part of the event object itself'
23
+ );
24
+ return event.nativeEvent;
25
+ },
26
+ });
27
+ return event.nativeEvent;
28
+ }
29
+
30
+ class ExpoImage extends React.PureComponent<ImageNativeProps> {
31
+ onLoadStart = () => {
32
+ this.props.onLoadStart?.();
33
+ };
34
+
35
+ onLoad = (event: NativeSyntheticEvent<ImageLoadEventData>) => {
36
+ this.props.onLoad?.(withDeprecatedNativeEvent(event));
37
+ this.onLoadEnd();
38
+ };
39
+
40
+ onProgress = (event: NativeSyntheticEvent<ImageProgressEventData>) => {
41
+ this.props.onProgress?.(withDeprecatedNativeEvent(event));
42
+ };
43
+
44
+ onError = (event: NativeSyntheticEvent<ImageErrorEventData>) => {
45
+ this.props.onError?.(withDeprecatedNativeEvent(event));
46
+ this.onLoadEnd();
47
+ };
48
+
49
+ onLoadEnd = () => {
50
+ this.props.onLoadEnd?.();
51
+ };
52
+
53
+ render() {
54
+ const { style, accessibilityLabel, alt, ...props } = this.props;
55
+ const resolvedStyle = StyleSheet.flatten(style);
56
+
57
+ // Shadows behave different on iOS, Android & Web.
58
+ // Android uses the `elevation` prop, whereas iOS
59
+ // and web use the regular `shadow...` props.
60
+ if (Platform.OS === 'android') {
61
+ delete resolvedStyle.shadowColor;
62
+ delete resolvedStyle.shadowOffset;
63
+ delete resolvedStyle.shadowOpacity;
64
+ delete resolvedStyle.shadowRadius;
65
+ } else {
66
+ // @ts-expect-error
67
+ delete resolvedStyle.elevation;
68
+ }
69
+
70
+ // @ts-ignore
71
+ const backgroundColor = processColor(resolvedStyle.backgroundColor);
72
+ // On Android, we have to set the `backgroundColor` directly on the correct component.
73
+ // So we have to remove it from styles. Otherwise, the background color won't take into consideration the border-radius.
74
+ if (Platform.OS === 'android') {
75
+ delete resolvedStyle.backgroundColor;
76
+ }
77
+
78
+ const tintColor = processColor(props.tintColor || resolvedStyle.tintColor);
79
+
80
+ const borderColor = processColor(resolvedStyle.borderColor);
81
+ // @ts-ignore
82
+ const borderStartColor = processColor(resolvedStyle.borderStartColor);
83
+ // @ts-ignore
84
+ const borderEndColor = processColor(resolvedStyle.borderEndColor);
85
+ // @ts-ignore
86
+ const borderLeftColor = processColor(resolvedStyle.borderLeftColor);
87
+ // @ts-ignore
88
+ const borderRightColor = processColor(resolvedStyle.borderRightColor);
89
+ // @ts-ignore
90
+ const borderTopColor = processColor(resolvedStyle.borderTopColor);
91
+ // @ts-ignore
92
+ const borderBottomColor = processColor(resolvedStyle.borderBottomColor);
93
+
94
+ return (
95
+ <NativeExpoImage
96
+ {...props}
97
+ {...resolvedStyle}
98
+ accessibilityLabel={accessibilityLabel ?? alt}
99
+ style={resolvedStyle}
100
+ onLoadStart={this.onLoadStart}
101
+ onLoad={this.onLoad}
102
+ onProgress={this.onProgress}
103
+ onError={this.onError}
104
+ tintColor={tintColor}
105
+ borderColor={borderColor}
106
+ borderLeftColor={borderLeftColor}
107
+ borderRightColor={borderRightColor}
108
+ borderTopColor={borderTopColor}
109
+ borderBottomColor={borderBottomColor}
110
+ borderStartColor={borderStartColor}
111
+ borderEndColor={borderEndColor}
112
+ backgroundColor={backgroundColor}
113
+ />
114
+ );
115
+ }
116
+ }
117
+
118
+ export { ExpoImageModule };
119
+ export default ExpoImage;
@@ -0,0 +1,155 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native-web';
3
+
4
+ import { ImageNativeProps, ImageSource, ImageLoadEventData } from './Image.types';
5
+ import AnimationManager, { AnimationManagerNode } from './web/AnimationManager';
6
+ import ImageWrapper from './web/ImageWrapper';
7
+ import loadStyle from './web/imageStyles';
8
+ import useSourceSelection from './web/useSourceSelection';
9
+
10
+ loadStyle();
11
+
12
+ export const ExpoImageModule = {
13
+ prefetch(urls: string | string[]): void {
14
+ const urlsArray = Array.isArray(urls) ? urls : [urls];
15
+ urlsArray.forEach((url) => {
16
+ const img = new Image();
17
+ img.src = url;
18
+ });
19
+ },
20
+
21
+ async clearMemoryCache(): Promise<boolean> {
22
+ return false;
23
+ },
24
+
25
+ async clearDiskCache(): Promise<boolean> {
26
+ return false;
27
+ },
28
+ };
29
+
30
+ function onLoadAdapter(onLoad?: (event: ImageLoadEventData) => void) {
31
+ return (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
32
+ const target = event.target as HTMLImageElement;
33
+ onLoad?.({
34
+ source: {
35
+ url: target.currentSrc,
36
+ width: target.naturalWidth,
37
+ height: target.naturalHeight,
38
+ mediaType: null,
39
+ },
40
+ cacheType: 'none',
41
+ });
42
+ };
43
+ }
44
+
45
+ function onErrorAdapter(onError?: { (event: { error: string }): void }) {
46
+ return ({ source }: { source?: ImageSource | null }) => {
47
+ onError?.({
48
+ error: `Failed to load image from url: ${source?.uri}`,
49
+ });
50
+ };
51
+ }
52
+
53
+ // Used for some transitions to mimic native animations
54
+ const setCssVariables = (element: HTMLElement, size: DOMRect) => {
55
+ element?.style.setProperty('--expo-image-width', `${size.width}px`);
56
+ element?.style.setProperty('--expo-image-height', `${size.height}px`);
57
+ };
58
+
59
+ export default function ExpoImage({
60
+ source,
61
+ placeholder,
62
+ contentFit,
63
+ contentPosition,
64
+ placeholderContentFit,
65
+ cachePolicy,
66
+ onLoad,
67
+ transition,
68
+ onError,
69
+ responsivePolicy,
70
+ onLoadEnd,
71
+ priority,
72
+ blurRadius,
73
+ recyclingKey,
74
+ style,
75
+ ...props
76
+ }: ImageNativeProps) {
77
+ const imagePlaceholderContentFit = placeholderContentFit || 'scale-down';
78
+ const imageHashStyle = {
79
+ objectFit: placeholderContentFit || contentFit,
80
+ };
81
+ const { containerRef, source: selectedSource } = useSourceSelection(
82
+ source,
83
+ responsivePolicy,
84
+ setCssVariables
85
+ );
86
+
87
+ const initialNodeAnimationKey =
88
+ (recyclingKey ? `${recyclingKey}-${placeholder?.[0]?.uri}` : placeholder?.[0]?.uri) ?? '';
89
+
90
+ const initialNode: AnimationManagerNode | null = placeholder?.[0]?.uri
91
+ ? [
92
+ initialNodeAnimationKey,
93
+ ({ onAnimationFinished }) =>
94
+ (className, style) => (
95
+ <ImageWrapper
96
+ {...props}
97
+ source={placeholder?.[0]}
98
+ style={{
99
+ objectFit: imagePlaceholderContentFit,
100
+ ...(blurRadius ? { filter: `blur(${blurRadius}px)` } : {}),
101
+ ...style,
102
+ }}
103
+ className={className}
104
+ events={{
105
+ onTransitionEnd: [onAnimationFinished],
106
+ }}
107
+ contentPosition={{ left: '50%', top: '50%' }}
108
+ hashPlaceholderContentPosition={contentPosition}
109
+ hashPlaceholderStyle={imageHashStyle}
110
+ />
111
+ ),
112
+ ]
113
+ : null;
114
+
115
+ const currentNodeAnimationKey =
116
+ (recyclingKey
117
+ ? `${recyclingKey}-${selectedSource?.uri ?? placeholder?.[0]?.uri}`
118
+ : selectedSource?.uri ?? placeholder?.[0]?.uri) ?? '';
119
+
120
+ const currentNode: AnimationManagerNode = [
121
+ currentNodeAnimationKey,
122
+ ({ onAnimationFinished, onReady, onMount, onError: onErrorInner }) =>
123
+ (className, style) => (
124
+ <ImageWrapper
125
+ {...props}
126
+ source={selectedSource || placeholder?.[0]}
127
+ events={{
128
+ onError: [onErrorAdapter(onError), onLoadEnd, onErrorInner],
129
+ onLoad: [onLoadAdapter(onLoad), onLoadEnd, onReady],
130
+ onMount: [onMount],
131
+ onTransitionEnd: [onAnimationFinished],
132
+ }}
133
+ style={{
134
+ objectFit: selectedSource ? contentFit : imagePlaceholderContentFit,
135
+ ...(blurRadius ? { filter: `blur(${blurRadius}px)` } : {}),
136
+ ...style,
137
+ }}
138
+ className={className}
139
+ cachePolicy={cachePolicy}
140
+ priority={priority}
141
+ contentPosition={selectedSource ? contentPosition : { top: '50%', left: '50%' }}
142
+ hashPlaceholderContentPosition={contentPosition}
143
+ hashPlaceholderStyle={imageHashStyle}
144
+ accessibilityLabel={props.accessibilityLabel}
145
+ />
146
+ ),
147
+ ];
148
+ return (
149
+ <View ref={containerRef} dataSet={{ expoimage: true }} style={[{ overflow: 'hidden' }, style]}>
150
+ <AnimationManager transition={transition} recyclingKey={recyclingKey} initial={initialNode}>
151
+ {currentNode}
152
+ </AnimationManager>
153
+ </View>
154
+ );
155
+ }
@@ -0,0 +1,7 @@
1
+ import {KeplerTurboModule, TurboModuleRegistry} from '@amazon-devices/keplerscript-turbomodule-api';
2
+
3
+ import ExpoImageComponent from './ImageViewNativeComponent';
4
+
5
+ type Spec = KeplerTurboModule;
6
+ export const NativeExpoImage = ExpoImageComponent;
7
+ export const ExpoImageModule = TurboModuleRegistry.getEnforcing<Spec>('ExpoImage') as Spec;
@@ -0,0 +1,4 @@
1
+ import { requireNativeViewManager, requireNativeModule } from 'expo-modules-core';
2
+
3
+ export const NativeExpoImage = requireNativeViewManager('ExpoImage');
4
+ export const ExpoImageModule = requireNativeModule('ExpoImage');
package/src/Image.tsx ADDED
@@ -0,0 +1,82 @@
1
+ import React from 'react';
2
+ import { StyleSheet } from 'react-native';
3
+
4
+ import ExpoImage, { ExpoImageModule } from './ExpoImage';
5
+ import { ImageProps } from './Image.types';
6
+ import { resolveContentFit, resolveContentPosition, resolveTransition } from './utils';
7
+ import { resolveSources } from './utils/resolveSources';
8
+
9
+ let loggedDefaultSourceDeprecationWarning = false;
10
+
11
+ export class Image extends React.PureComponent<ImageProps> {
12
+ /**
13
+ * Preloads images at the given urls that can be later used in the image view.
14
+ * Preloaded images are always cached on the disk, so make sure to use
15
+ * `disk` (default) or `memory-disk` cache policy.
16
+ */
17
+ static prefetch(urls: string | string[]): void {
18
+ return ExpoImageModule.prefetch(Array.isArray(urls) ? urls : [urls]);
19
+ }
20
+
21
+ /**
22
+ * Asynchronously clears all images stored in memory.
23
+ * @platform android
24
+ * @platform ios
25
+ * @return A promise resolving to `true` when the operation succeeds.
26
+ * It may resolve to `false` on Android when the activity is no longer available.
27
+ * Resolves to `false` on Web.
28
+ */
29
+ static async clearMemoryCache(): Promise<boolean> {
30
+ return await ExpoImageModule.clearMemoryCache();
31
+ }
32
+
33
+ /**
34
+ * Asynchronously clears all images from the disk cache.
35
+ * @platform android
36
+ * @platform ios
37
+ * @return A promise resolving to `true` when the operation succeeds.
38
+ * It may resolve to `false` on Android when the activity is no longer available.
39
+ * Resolves to `false` on Web.
40
+ */
41
+ static async clearDiskCache(): Promise<boolean> {
42
+ return await ExpoImageModule.clearDiskCache();
43
+ }
44
+
45
+ render() {
46
+ const {
47
+ style,
48
+ source,
49
+ placeholder,
50
+ contentFit,
51
+ contentPosition,
52
+ transition,
53
+ fadeDuration,
54
+ resizeMode: resizeModeProp,
55
+ defaultSource,
56
+ loadingIndicatorSource,
57
+ ...restProps
58
+ } = this.props;
59
+
60
+ const { resizeMode: resizeModeStyle, ...restStyle } = StyleSheet.flatten(style) || {};
61
+ const resizeMode = resizeModeProp ?? resizeModeStyle;
62
+
63
+ if ((defaultSource || loadingIndicatorSource) && !loggedDefaultSourceDeprecationWarning) {
64
+ console.warn(
65
+ '[expo-image]: `defaultSource` and `loadingIndicatorSource` props are deprecated, use `placeholder` instead'
66
+ );
67
+ loggedDefaultSourceDeprecationWarning = true;
68
+ }
69
+
70
+ return (
71
+ <ExpoImage
72
+ {...restProps}
73
+ style={restStyle}
74
+ source={resolveSources(source)}
75
+ placeholder={resolveSources(placeholder ?? defaultSource ?? loadingIndicatorSource)}
76
+ contentFit={resolveContentFit(contentFit, resizeMode)}
77
+ contentPosition={resolveContentPosition(contentPosition)}
78
+ transition={resolveTransition(transition, fadeDuration)}
79
+ />
80
+ );
81
+ }
82
+ }