react-native-ensys-camera-x 1.0.7

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 (506) hide show
  1. package/CustomCamera.podspec +20 -0
  2. package/LICENSE +20 -0
  3. package/README.md +833 -0
  4. package/android/build.gradle +135 -0
  5. package/android/consumer-rules.pro +47 -0
  6. package/android/src/main/AndroidManifest.xml +72 -0
  7. package/android/src/main/java/android/print/PdfPrint.java +51 -0
  8. package/android/src/main/java/com/customcamera/AnimatedImageViewManager.kt +199 -0
  9. package/android/src/main/java/com/customcamera/AudioPlayerView.kt +322 -0
  10. package/android/src/main/java/com/customcamera/AudioRecorder.kt +506 -0
  11. package/android/src/main/java/com/customcamera/BarcodeScannerActivity.kt +361 -0
  12. package/android/src/main/java/com/customcamera/BlurBackgroundView.kt +199 -0
  13. package/android/src/main/java/com/customcamera/CacheCleanupManager.kt +386 -0
  14. package/android/src/main/java/com/customcamera/CameraAspectRatioMode.kt +77 -0
  15. package/android/src/main/java/com/customcamera/CameraAsset.kt +211 -0
  16. package/android/src/main/java/com/customcamera/CameraTheme.kt +479 -0
  17. package/android/src/main/java/com/customcamera/CompressionCacheStore.kt +504 -0
  18. package/android/src/main/java/com/customcamera/CompressionFileNameUtils.kt +7 -0
  19. package/android/src/main/java/com/customcamera/CompressionProfile.kt +195 -0
  20. package/android/src/main/java/com/customcamera/CustomCameraActivity.kt +7291 -0
  21. package/android/src/main/java/com/customcamera/CustomCameraFileProvider.kt +9 -0
  22. package/android/src/main/java/com/customcamera/CustomCameraModule.kt +2479 -0
  23. package/android/src/main/java/com/customcamera/CustomCameraPackage.kt +53 -0
  24. package/android/src/main/java/com/customcamera/DisplayUtils.kt +9 -0
  25. package/android/src/main/java/com/customcamera/DocumentPreviewView.kt +846 -0
  26. package/android/src/main/java/com/customcamera/DrawingView.kt +214 -0
  27. package/android/src/main/java/com/customcamera/EmojiPickerData.kt +228 -0
  28. package/android/src/main/java/com/customcamera/FilterStripAdapter.kt +158 -0
  29. package/android/src/main/java/com/customcamera/GifSupport.kt +215 -0
  30. package/android/src/main/java/com/customcamera/GlobalAudioPlayer.kt +320 -0
  31. package/android/src/main/java/com/customcamera/ImageExporter.kt +1394 -0
  32. package/android/src/main/java/com/customcamera/ImageFormatSupport.kt +163 -0
  33. package/android/src/main/java/com/customcamera/Localization.kt +206 -0
  34. package/android/src/main/java/com/customcamera/MediaAdapters.kt +758 -0
  35. package/android/src/main/java/com/customcamera/MediaCacheManager.kt +782 -0
  36. package/android/src/main/java/com/customcamera/MediaExportFormats.kt +201 -0
  37. package/android/src/main/java/com/customcamera/MediaFileIo.kt +310 -0
  38. package/android/src/main/java/com/customcamera/MediaMetadataStore.kt +494 -0
  39. package/android/src/main/java/com/customcamera/MediaPreviewEditor.kt +14865 -0
  40. package/android/src/main/java/com/customcamera/MediaPublisher.kt +423 -0
  41. package/android/src/main/java/com/customcamera/MediaStorageWorkflow.kt +722 -0
  42. package/android/src/main/java/com/customcamera/MediaStoreRepository.kt +378 -0
  43. package/android/src/main/java/com/customcamera/MediaThumbnailView.kt +286 -0
  44. package/android/src/main/java/com/customcamera/MediaUtils.kt +37 -0
  45. package/android/src/main/java/com/customcamera/NativeVideoViewManager.kt +845 -0
  46. package/android/src/main/java/com/customcamera/OfficeDocumentConverter.kt +2791 -0
  47. package/android/src/main/java/com/customcamera/PendingCaptureCrops.kt +88 -0
  48. package/android/src/main/java/com/customcamera/PowerPointPreview.kt +4077 -0
  49. package/android/src/main/java/com/customcamera/RecentPickerStore.kt +74 -0
  50. package/android/src/main/java/com/customcamera/SecureFileEraser.kt +411 -0
  51. package/android/src/main/java/com/customcamera/SecureKeyModule.kt +88 -0
  52. package/android/src/main/java/com/customcamera/SecureMediaDeleter.kt +493 -0
  53. package/android/src/main/java/com/customcamera/StickerPickerData.kt +107 -0
  54. package/android/src/main/java/com/customcamera/SvgDrawable.kt +175 -0
  55. package/android/src/main/java/com/customcamera/SvgIconViewManager.kt +77 -0
  56. package/android/src/main/java/com/customcamera/TextEntryController.kt +553 -0
  57. package/android/src/main/java/com/customcamera/ThumbnailLoader.kt +455 -0
  58. package/android/src/main/java/com/customcamera/UploadService.kt +909 -0
  59. package/android/src/main/java/com/customcamera/VideoEditUtils.kt +210 -0
  60. package/android/src/main/java/com/customcamera/VideoRotationTranscoder.kt +1992 -0
  61. package/android/src/main/java/com/customcamera/gif/AnimatedGifEncoder.kt +473 -0
  62. package/android/src/main/java/com/customcamera/gif/GifDecoder.kt +690 -0
  63. package/android/src/main/java/com/customcamera/gif/GifFramesDrawable.kt +160 -0
  64. package/android/src/main/java/com/customcamera/gif/GifHttp.kt +112 -0
  65. package/android/src/main/java/com/customcamera/gif/GifImageLoader.kt +186 -0
  66. package/android/src/main/java/com/customcamera/gif/GifModels.kt +74 -0
  67. package/android/src/main/java/com/customcamera/gif/GifProvider.kt +49 -0
  68. package/android/src/main/java/com/customcamera/gif/GifProviders.kt +27 -0
  69. package/android/src/main/java/com/customcamera/gif/GifRepository.kt +124 -0
  70. package/android/src/main/java/com/customcamera/gif/GifSafety.kt +33 -0
  71. package/android/src/main/java/com/customcamera/gif/GiphyGifProvider.kt +146 -0
  72. package/android/src/main/java/com/customcamera/gif/LZWEncoder.kt +258 -0
  73. package/android/src/main/java/com/customcamera/gif/NeuQuant.kt +435 -0
  74. package/android/src/main/java/com/customcamera/gif/TenorGifProvider.kt +147 -0
  75. package/android/src/main/res/drawable/bg_brush_selected.xml +5 -0
  76. package/android/src/main/res/drawable/bg_color_swatch.xml +5 -0
  77. package/android/src/main/res/drawable/bg_editor_toolbar.xml +6 -0
  78. package/android/src/main/res/drawable/bg_icon_circle.xml +5 -0
  79. package/android/src/main/res/drawable/bg_icon_circle_light.xml +5 -0
  80. package/android/src/main/res/drawable/bg_mode_tab_active.xml +6 -0
  81. package/android/src/main/res/drawable/bg_pill.xml +6 -0
  82. package/android/src/main/res/drawable/bg_recording_dot.xml +6 -0
  83. package/android/src/main/res/drawable/bg_selection_badge.xml +8 -0
  84. package/android/src/main/res/drawable/bg_send_button.xml +5 -0
  85. package/android/src/main/res/drawable/bg_shutter_inner.xml +5 -0
  86. package/android/src/main/res/drawable/bg_shutter_recording.xml +6 -0
  87. package/android/src/main/res/drawable/bg_shutter_ring.xml +8 -0
  88. package/android/src/main/res/drawable/bg_shutter_video_idle.xml +5 -0
  89. package/android/src/main/res/drawable/bg_thumbnail.xml +9 -0
  90. package/android/src/main/res/drawable/ic_aspect_ratio.xml +17 -0
  91. package/android/src/main/res/drawable/ic_audio.xml +10 -0
  92. package/android/src/main/res/drawable/ic_back.xml +10 -0
  93. package/android/src/main/res/drawable/ic_brush_medium.xml +12 -0
  94. package/android/src/main/res/drawable/ic_brush_thick.xml +12 -0
  95. package/android/src/main/res/drawable/ic_brush_thin.xml +12 -0
  96. package/android/src/main/res/drawable/ic_check.xml +17 -0
  97. package/android/src/main/res/drawable/ic_chevron_down.xml +10 -0
  98. package/android/src/main/res/drawable/ic_chevron_up.xml +13 -0
  99. package/android/src/main/res/drawable/ic_clear_drawing.xml +10 -0
  100. package/android/src/main/res/drawable/ic_close.xml +10 -0
  101. package/android/src/main/res/drawable/ic_cover.xml +9 -0
  102. package/android/src/main/res/drawable/ic_crop.xml +10 -0
  103. package/android/src/main/res/drawable/ic_delete.xml +9 -0
  104. package/android/src/main/res/drawable/ic_document.xml +10 -0
  105. package/android/src/main/res/drawable/ic_done.xml +10 -0
  106. package/android/src/main/res/drawable/ic_download.xml +10 -0
  107. package/android/src/main/res/drawable/ic_emoji.xml +10 -0
  108. package/android/src/main/res/drawable/ic_filter.xml +10 -0
  109. package/android/src/main/res/drawable/ic_flash_auto.xml +7 -0
  110. package/android/src/main/res/drawable/ic_flash_off.xml +23 -0
  111. package/android/src/main/res/drawable/ic_flash_on.xml +16 -0
  112. package/android/src/main/res/drawable/ic_flip.xml +15 -0
  113. package/android/src/main/res/drawable/ic_gallery.xml +10 -0
  114. package/android/src/main/res/drawable/ic_gif.xml +24 -0
  115. package/android/src/main/res/drawable/ic_lock.xml +19 -0
  116. package/android/src/main/res/drawable/ic_lock_open.xml +22 -0
  117. package/android/src/main/res/drawable/ic_marker.xml +10 -0
  118. package/android/src/main/res/drawable/ic_more_vert.xml +18 -0
  119. package/android/src/main/res/drawable/ic_overlay_close.xml +19 -0
  120. package/android/src/main/res/drawable/ic_overlay_resize.xml +18 -0
  121. package/android/src/main/res/drawable/ic_pause.xml +10 -0
  122. package/android/src/main/res/drawable/ic_photo_mode.xml +10 -0
  123. package/android/src/main/res/drawable/ic_play.xml +10 -0
  124. package/android/src/main/res/drawable/ic_redo.xml +10 -0
  125. package/android/src/main/res/drawable/ic_rotate.xml +9 -0
  126. package/android/src/main/res/drawable/ic_send.xml +10 -0
  127. package/android/src/main/res/drawable/ic_share.xml +10 -0
  128. package/android/src/main/res/drawable/ic_stat_upload.xml +10 -0
  129. package/android/src/main/res/drawable/ic_sticker.xml +24 -0
  130. package/android/src/main/res/drawable/ic_text.xml +10 -0
  131. package/android/src/main/res/drawable/ic_text_align_center.xml +11 -0
  132. package/android/src/main/res/drawable/ic_text_align_left.xml +11 -0
  133. package/android/src/main/res/drawable/ic_text_align_right.xml +11 -0
  134. package/android/src/main/res/drawable/ic_text_bg.xml +11 -0
  135. package/android/src/main/res/drawable/ic_trim.xml +23 -0
  136. package/android/src/main/res/drawable/ic_undo.xml +10 -0
  137. package/android/src/main/res/drawable/ic_video_mode.xml +10 -0
  138. package/android/src/main/res/drawable/ic_video_note.xml +13 -0
  139. package/android/src/main/res/drawable/ic_volume_off.xml +9 -0
  140. package/android/src/main/res/drawable/ic_volume_on.xml +9 -0
  141. package/android/src/main/res/drawable/sticker_heart.xml +9 -0
  142. package/android/src/main/res/drawable/sticker_smile.xml +9 -0
  143. package/android/src/main/res/drawable/sticker_star.xml +9 -0
  144. package/android/src/main/res/drawable/sticker_thumbsup.xml +9 -0
  145. package/android/src/main/res/values/colors.xml +34 -0
  146. package/android/src/main/res/values/ids.xml +15 -0
  147. package/android/src/main/res/values/strings.xml +15 -0
  148. package/android/src/main/res/values/styles.xml +20 -0
  149. package/android/src/main/res/xml/file_paths.xml +34 -0
  150. package/ios/CustomCamera.h +5 -0
  151. package/ios/CustomCamera.mm +214 -0
  152. package/lib/module/AudioPlayerContext.js +233 -0
  153. package/lib/module/AudioPlayerContext.js.map +1 -0
  154. package/lib/module/CameraPreview.js +304 -0
  155. package/lib/module/CameraPreview.js.map +1 -0
  156. package/lib/module/NativeAnimatedImageView.js +41 -0
  157. package/lib/module/NativeAnimatedImageView.js.map +1 -0
  158. package/lib/module/NativeAudioPlayerView.js +33 -0
  159. package/lib/module/NativeAudioPlayerView.js.map +1 -0
  160. package/lib/module/NativeBlurView.js +35 -0
  161. package/lib/module/NativeBlurView.js.map +1 -0
  162. package/lib/module/NativeCustomCamera.js +128 -0
  163. package/lib/module/NativeCustomCamera.js.map +1 -0
  164. package/lib/module/NativeCustomCamera.web.js +143 -0
  165. package/lib/module/NativeCustomCamera.web.js.map +1 -0
  166. package/lib/module/NativeCustomVideoView.js +5 -0
  167. package/lib/module/NativeCustomVideoView.js.map +1 -0
  168. package/lib/module/NativeDocumentPreviewView.js +156 -0
  169. package/lib/module/NativeDocumentPreviewView.js.map +1 -0
  170. package/lib/module/NativeMediaThumbnailView.js +110 -0
  171. package/lib/module/NativeMediaThumbnailView.js.map +1 -0
  172. package/lib/module/NativeSvgIcon.js +32 -0
  173. package/lib/module/NativeSvgIcon.js.map +1 -0
  174. package/lib/module/ResponsivePreviewContainer.js +171 -0
  175. package/lib/module/ResponsivePreviewContainer.js.map +1 -0
  176. package/lib/module/accessibility.js +61 -0
  177. package/lib/module/accessibility.js.map +1 -0
  178. package/lib/module/config.js +352 -0
  179. package/lib/module/config.js.map +1 -0
  180. package/lib/module/cpuOptimization.js +296 -0
  181. package/lib/module/cpuOptimization.js.map +1 -0
  182. package/lib/module/db/DatabaseManager.js +191 -0
  183. package/lib/module/db/DatabaseManager.js.map +1 -0
  184. package/lib/module/db/MediaMapper.js +284 -0
  185. package/lib/module/db/MediaMapper.js.map +1 -0
  186. package/lib/module/db/MediaRepository.js +242 -0
  187. package/lib/module/db/MediaRepository.js.map +1 -0
  188. package/lib/module/db/index.js +41 -0
  189. package/lib/module/db/index.js.map +1 -0
  190. package/lib/module/db/migrations.js +180 -0
  191. package/lib/module/db/migrations.js.map +1 -0
  192. package/lib/module/db/react-native-sqlcipher.d.js +2 -0
  193. package/lib/module/db/react-native-sqlcipher.d.js.map +1 -0
  194. package/lib/module/db/secureKey.js +87 -0
  195. package/lib/module/db/secureKey.js.map +1 -0
  196. package/lib/module/db/types.js +57 -0
  197. package/lib/module/db/types.js.map +1 -0
  198. package/lib/module/db/useMediaDatabase.js +123 -0
  199. package/lib/module/db/useMediaDatabase.js.map +1 -0
  200. package/lib/module/defaultIcons.js +2259 -0
  201. package/lib/module/defaultIcons.js.map +1 -0
  202. package/lib/module/deviceCapabilities.js +408 -0
  203. package/lib/module/deviceCapabilities.js.map +1 -0
  204. package/lib/module/errors.js +267 -0
  205. package/lib/module/errors.js.map +1 -0
  206. package/lib/module/iconConfig.js +796 -0
  207. package/lib/module/iconConfig.js.map +1 -0
  208. package/lib/module/icons.js +514 -0
  209. package/lib/module/icons.js.map +1 -0
  210. package/lib/module/index.js +251 -0
  211. package/lib/module/index.js.map +1 -0
  212. package/lib/module/jest-globals.d.js +2 -0
  213. package/lib/module/jest-globals.d.js.map +1 -0
  214. package/lib/module/library/MediaLibrary.js +107 -0
  215. package/lib/module/library/MediaLibrary.js.map +1 -0
  216. package/lib/module/library/MediaLibraryScreen.js +2597 -0
  217. package/lib/module/library/MediaLibraryScreen.js.map +1 -0
  218. package/lib/module/library/components/AudioPreview.js +74 -0
  219. package/lib/module/library/components/AudioPreview.js.map +1 -0
  220. package/lib/module/library/components/DocumentPreview.js +331 -0
  221. package/lib/module/library/components/DocumentPreview.js.map +1 -0
  222. package/lib/module/library/components/ExpandableFab.js +343 -0
  223. package/lib/module/library/components/ExpandableFab.js.map +1 -0
  224. package/lib/module/library/components/FileTiles.js +251 -0
  225. package/lib/module/library/components/FileTiles.js.map +1 -0
  226. package/lib/module/library/components/ImagePreview.js +70 -0
  227. package/lib/module/library/components/ImagePreview.js.map +1 -0
  228. package/lib/module/library/components/MediaMetadataHeader.js +175 -0
  229. package/lib/module/library/components/MediaMetadataHeader.js.map +1 -0
  230. package/lib/module/library/components/RecordAudioScreen.js +816 -0
  231. package/lib/module/library/components/RecordAudioScreen.js.map +1 -0
  232. package/lib/module/library/components/VideoPreview.js +453 -0
  233. package/lib/module/library/components/VideoPreview.js.map +1 -0
  234. package/lib/module/library/components/ViewerCounter.js +55 -0
  235. package/lib/module/library/components/ViewerCounter.js.map +1 -0
  236. package/lib/module/library/compressionEstimate.js +507 -0
  237. package/lib/module/library/compressionEstimate.js.map +1 -0
  238. package/lib/module/library/fileMetadata.js +196 -0
  239. package/lib/module/library/fileMetadata.js.map +1 -0
  240. package/lib/module/library/index.js +42 -0
  241. package/lib/module/library/index.js.map +1 -0
  242. package/lib/module/library/libraryIconRegistry.js +69 -0
  243. package/lib/module/library/libraryIconRegistry.js.map +1 -0
  244. package/lib/module/library/libraryIcons.js +858 -0
  245. package/lib/module/library/libraryIcons.js.map +1 -0
  246. package/lib/module/library/localizedFormat.js +181 -0
  247. package/lib/module/library/localizedFormat.js.map +1 -0
  248. package/lib/module/library/palette.js +225 -0
  249. package/lib/module/library/palette.js.map +1 -0
  250. package/lib/module/library/responsive.js +53 -0
  251. package/lib/module/library/responsive.js.map +1 -0
  252. package/lib/module/locales.js +416 -0
  253. package/lib/module/locales.js.map +1 -0
  254. package/lib/module/localization.js +1064 -0
  255. package/lib/module/localization.js.map +1 -0
  256. package/lib/module/logger.js +20 -0
  257. package/lib/module/logger.js.map +1 -0
  258. package/lib/module/lowMemoryCache.js +206 -0
  259. package/lib/module/lowMemoryCache.js.map +1 -0
  260. package/lib/module/mediaHistory.js +33 -0
  261. package/lib/module/mediaHistory.js.map +1 -0
  262. package/lib/module/mediaStorageService.js +402 -0
  263. package/lib/module/mediaStorageService.js.map +1 -0
  264. package/lib/module/memory.js +79 -0
  265. package/lib/module/memory.js.map +1 -0
  266. package/lib/module/nativeActions.js +307 -0
  267. package/lib/module/nativeActions.js.map +1 -0
  268. package/lib/module/nativeComponentSupport.js +61 -0
  269. package/lib/module/nativeComponentSupport.js.map +1 -0
  270. package/lib/module/networkPerformance.js +24 -0
  271. package/lib/module/networkPerformance.js.map +1 -0
  272. package/lib/module/package.json +1 -0
  273. package/lib/module/performance.js +104 -0
  274. package/lib/module/performance.js.map +1 -0
  275. package/lib/module/performanceMonitor.js +155 -0
  276. package/lib/module/performanceMonitor.js.map +1 -0
  277. package/lib/module/permissions.js +370 -0
  278. package/lib/module/permissions.js.map +1 -0
  279. package/lib/module/rendering.js +40 -0
  280. package/lib/module/rendering.js.map +1 -0
  281. package/lib/module/security.js +18 -0
  282. package/lib/module/security.js.map +1 -0
  283. package/lib/module/state.js +266 -0
  284. package/lib/module/state.js.map +1 -0
  285. package/lib/module/storage.js +400 -0
  286. package/lib/module/storage.js.map +1 -0
  287. package/lib/module/theme.js +390 -0
  288. package/lib/module/theme.js.map +1 -0
  289. package/lib/module/types.js +4 -0
  290. package/lib/module/types.js.map +1 -0
  291. package/lib/module/utils.js +115 -0
  292. package/lib/module/utils.js.map +1 -0
  293. package/lib/module/validation.js +288 -0
  294. package/lib/module/validation.js.map +1 -0
  295. package/lib/typescript/package.json +1 -0
  296. package/lib/typescript/src/AudioPlayerContext.d.ts +27 -0
  297. package/lib/typescript/src/AudioPlayerContext.d.ts.map +1 -0
  298. package/lib/typescript/src/CameraPreview.d.ts +13 -0
  299. package/lib/typescript/src/CameraPreview.d.ts.map +1 -0
  300. package/lib/typescript/src/NativeAnimatedImageView.d.ts +33 -0
  301. package/lib/typescript/src/NativeAnimatedImageView.d.ts.map +1 -0
  302. package/lib/typescript/src/NativeAudioPlayerView.d.ts +12 -0
  303. package/lib/typescript/src/NativeAudioPlayerView.d.ts.map +1 -0
  304. package/lib/typescript/src/NativeBlurView.d.ts +12 -0
  305. package/lib/typescript/src/NativeBlurView.d.ts.map +1 -0
  306. package/lib/typescript/src/NativeCustomCamera.d.ts +167 -0
  307. package/lib/typescript/src/NativeCustomCamera.d.ts.map +1 -0
  308. package/lib/typescript/src/NativeCustomCamera.web.d.ts +47 -0
  309. package/lib/typescript/src/NativeCustomCamera.web.d.ts.map +1 -0
  310. package/lib/typescript/src/NativeCustomVideoView.d.ts +30 -0
  311. package/lib/typescript/src/NativeCustomVideoView.d.ts.map +1 -0
  312. package/lib/typescript/src/NativeDocumentPreviewView.d.ts +48 -0
  313. package/lib/typescript/src/NativeDocumentPreviewView.d.ts.map +1 -0
  314. package/lib/typescript/src/NativeMediaThumbnailView.d.ts +54 -0
  315. package/lib/typescript/src/NativeMediaThumbnailView.d.ts.map +1 -0
  316. package/lib/typescript/src/NativeSvgIcon.d.ts +25 -0
  317. package/lib/typescript/src/NativeSvgIcon.d.ts.map +1 -0
  318. package/lib/typescript/src/ResponsivePreviewContainer.d.ts +92 -0
  319. package/lib/typescript/src/ResponsivePreviewContainer.d.ts.map +1 -0
  320. package/lib/typescript/src/accessibility.d.ts +20 -0
  321. package/lib/typescript/src/accessibility.d.ts.map +1 -0
  322. package/lib/typescript/src/config.d.ts +145 -0
  323. package/lib/typescript/src/config.d.ts.map +1 -0
  324. package/lib/typescript/src/cpuOptimization.d.ts +63 -0
  325. package/lib/typescript/src/cpuOptimization.d.ts.map +1 -0
  326. package/lib/typescript/src/db/DatabaseManager.d.ts +48 -0
  327. package/lib/typescript/src/db/DatabaseManager.d.ts.map +1 -0
  328. package/lib/typescript/src/db/MediaMapper.d.ts +77 -0
  329. package/lib/typescript/src/db/MediaMapper.d.ts.map +1 -0
  330. package/lib/typescript/src/db/MediaRepository.d.ts +66 -0
  331. package/lib/typescript/src/db/MediaRepository.d.ts.map +1 -0
  332. package/lib/typescript/src/db/index.d.ts +23 -0
  333. package/lib/typescript/src/db/index.d.ts.map +1 -0
  334. package/lib/typescript/src/db/migrations.d.ts +31 -0
  335. package/lib/typescript/src/db/migrations.d.ts.map +1 -0
  336. package/lib/typescript/src/db/secureKey.d.ts +10 -0
  337. package/lib/typescript/src/db/secureKey.d.ts.map +1 -0
  338. package/lib/typescript/src/db/types.d.ts +115 -0
  339. package/lib/typescript/src/db/types.d.ts.map +1 -0
  340. package/lib/typescript/src/db/useMediaDatabase.d.ts +41 -0
  341. package/lib/typescript/src/db/useMediaDatabase.d.ts.map +1 -0
  342. package/lib/typescript/src/defaultIcons.d.ts +139 -0
  343. package/lib/typescript/src/defaultIcons.d.ts.map +1 -0
  344. package/lib/typescript/src/deviceCapabilities.d.ts +92 -0
  345. package/lib/typescript/src/deviceCapabilities.d.ts.map +1 -0
  346. package/lib/typescript/src/errors.d.ts +95 -0
  347. package/lib/typescript/src/errors.d.ts.map +1 -0
  348. package/lib/typescript/src/iconConfig.d.ts +176 -0
  349. package/lib/typescript/src/iconConfig.d.ts.map +1 -0
  350. package/lib/typescript/src/icons.d.ts +217 -0
  351. package/lib/typescript/src/icons.d.ts.map +1 -0
  352. package/lib/typescript/src/index.d.ts +104 -0
  353. package/lib/typescript/src/index.d.ts.map +1 -0
  354. package/lib/typescript/src/library/MediaLibrary.d.ts +57 -0
  355. package/lib/typescript/src/library/MediaLibrary.d.ts.map +1 -0
  356. package/lib/typescript/src/library/MediaLibraryScreen.d.ts +51 -0
  357. package/lib/typescript/src/library/MediaLibraryScreen.d.ts.map +1 -0
  358. package/lib/typescript/src/library/components/AudioPreview.d.ts +6 -0
  359. package/lib/typescript/src/library/components/AudioPreview.d.ts.map +1 -0
  360. package/lib/typescript/src/library/components/DocumentPreview.d.ts +10 -0
  361. package/lib/typescript/src/library/components/DocumentPreview.d.ts.map +1 -0
  362. package/lib/typescript/src/library/components/ExpandableFab.d.ts +39 -0
  363. package/lib/typescript/src/library/components/ExpandableFab.d.ts.map +1 -0
  364. package/lib/typescript/src/library/components/FileTiles.d.ts +8 -0
  365. package/lib/typescript/src/library/components/FileTiles.d.ts.map +1 -0
  366. package/lib/typescript/src/library/components/ImagePreview.d.ts +5 -0
  367. package/lib/typescript/src/library/components/ImagePreview.d.ts.map +1 -0
  368. package/lib/typescript/src/library/components/MediaMetadataHeader.d.ts +16 -0
  369. package/lib/typescript/src/library/components/MediaMetadataHeader.d.ts.map +1 -0
  370. package/lib/typescript/src/library/components/RecordAudioScreen.d.ts +8 -0
  371. package/lib/typescript/src/library/components/RecordAudioScreen.d.ts.map +1 -0
  372. package/lib/typescript/src/library/components/VideoPreview.d.ts +20 -0
  373. package/lib/typescript/src/library/components/VideoPreview.d.ts.map +1 -0
  374. package/lib/typescript/src/library/components/ViewerCounter.d.ts +13 -0
  375. package/lib/typescript/src/library/components/ViewerCounter.d.ts.map +1 -0
  376. package/lib/typescript/src/library/compressionEstimate.d.ts +313 -0
  377. package/lib/typescript/src/library/compressionEstimate.d.ts.map +1 -0
  378. package/lib/typescript/src/library/fileMetadata.d.ts +33 -0
  379. package/lib/typescript/src/library/fileMetadata.d.ts.map +1 -0
  380. package/lib/typescript/src/library/index.d.ts +40 -0
  381. package/lib/typescript/src/library/index.d.ts.map +1 -0
  382. package/lib/typescript/src/library/libraryIconRegistry.d.ts +35 -0
  383. package/lib/typescript/src/library/libraryIconRegistry.d.ts.map +1 -0
  384. package/lib/typescript/src/library/libraryIcons.d.ts +85 -0
  385. package/lib/typescript/src/library/libraryIcons.d.ts.map +1 -0
  386. package/lib/typescript/src/library/localizedFormat.d.ts +49 -0
  387. package/lib/typescript/src/library/localizedFormat.d.ts.map +1 -0
  388. package/lib/typescript/src/library/palette.d.ts +104 -0
  389. package/lib/typescript/src/library/palette.d.ts.map +1 -0
  390. package/lib/typescript/src/library/responsive.d.ts +15 -0
  391. package/lib/typescript/src/library/responsive.d.ts.map +1 -0
  392. package/lib/typescript/src/locales.d.ts +103 -0
  393. package/lib/typescript/src/locales.d.ts.map +1 -0
  394. package/lib/typescript/src/localization.d.ts +1051 -0
  395. package/lib/typescript/src/localization.d.ts.map +1 -0
  396. package/lib/typescript/src/logger.d.ts +4 -0
  397. package/lib/typescript/src/logger.d.ts.map +1 -0
  398. package/lib/typescript/src/lowMemoryCache.d.ts +64 -0
  399. package/lib/typescript/src/lowMemoryCache.d.ts.map +1 -0
  400. package/lib/typescript/src/mediaHistory.d.ts +3 -0
  401. package/lib/typescript/src/mediaHistory.d.ts.map +1 -0
  402. package/lib/typescript/src/mediaStorageService.d.ts +155 -0
  403. package/lib/typescript/src/mediaStorageService.d.ts.map +1 -0
  404. package/lib/typescript/src/memory.d.ts +21 -0
  405. package/lib/typescript/src/memory.d.ts.map +1 -0
  406. package/lib/typescript/src/nativeActions.d.ts +174 -0
  407. package/lib/typescript/src/nativeActions.d.ts.map +1 -0
  408. package/lib/typescript/src/nativeComponentSupport.d.ts +30 -0
  409. package/lib/typescript/src/nativeComponentSupport.d.ts.map +1 -0
  410. package/lib/typescript/src/networkPerformance.d.ts +12 -0
  411. package/lib/typescript/src/networkPerformance.d.ts.map +1 -0
  412. package/lib/typescript/src/performance.d.ts +32 -0
  413. package/lib/typescript/src/performance.d.ts.map +1 -0
  414. package/lib/typescript/src/performanceMonitor.d.ts +45 -0
  415. package/lib/typescript/src/performanceMonitor.d.ts.map +1 -0
  416. package/lib/typescript/src/permissions.d.ts +132 -0
  417. package/lib/typescript/src/permissions.d.ts.map +1 -0
  418. package/lib/typescript/src/rendering.d.ts +9 -0
  419. package/lib/typescript/src/rendering.d.ts.map +1 -0
  420. package/lib/typescript/src/security.d.ts +6 -0
  421. package/lib/typescript/src/security.d.ts.map +1 -0
  422. package/lib/typescript/src/state.d.ts +102 -0
  423. package/lib/typescript/src/state.d.ts.map +1 -0
  424. package/lib/typescript/src/storage.d.ts +117 -0
  425. package/lib/typescript/src/storage.d.ts.map +1 -0
  426. package/lib/typescript/src/theme.d.ts +15 -0
  427. package/lib/typescript/src/theme.d.ts.map +1 -0
  428. package/lib/typescript/src/types.d.ts +802 -0
  429. package/lib/typescript/src/types.d.ts.map +1 -0
  430. package/lib/typescript/src/utils.d.ts +50 -0
  431. package/lib/typescript/src/utils.d.ts.map +1 -0
  432. package/lib/typescript/src/validation.d.ts +52 -0
  433. package/lib/typescript/src/validation.d.ts.map +1 -0
  434. package/package.json +204 -0
  435. package/react-native.config.js +17 -0
  436. package/src/AudioPlayerContext.tsx +220 -0
  437. package/src/CameraPreview.tsx +352 -0
  438. package/src/NativeAnimatedImageView.tsx +71 -0
  439. package/src/NativeAudioPlayerView.tsx +39 -0
  440. package/src/NativeBlurView.tsx +40 -0
  441. package/src/NativeCustomCamera.ts +305 -0
  442. package/src/NativeCustomCamera.web.ts +192 -0
  443. package/src/NativeCustomVideoView.ts +30 -0
  444. package/src/NativeDocumentPreviewView.tsx +196 -0
  445. package/src/NativeMediaThumbnailView.tsx +167 -0
  446. package/src/NativeSvgIcon.tsx +46 -0
  447. package/src/ResponsivePreviewContainer.tsx +227 -0
  448. package/src/accessibility.ts +80 -0
  449. package/src/config.ts +406 -0
  450. package/src/cpuOptimization.ts +365 -0
  451. package/src/db/DatabaseManager.ts +212 -0
  452. package/src/db/MediaMapper.ts +377 -0
  453. package/src/db/MediaRepository.ts +313 -0
  454. package/src/db/index.ts +73 -0
  455. package/src/db/migrations.ts +222 -0
  456. package/src/db/react-native-sqlcipher.d.ts +76 -0
  457. package/src/db/secureKey.ts +100 -0
  458. package/src/db/types.ts +123 -0
  459. package/src/db/useMediaDatabase.ts +191 -0
  460. package/src/defaultIcons.tsx +2390 -0
  461. package/src/deviceCapabilities.ts +438 -0
  462. package/src/errors.ts +350 -0
  463. package/src/iconConfig.tsx +962 -0
  464. package/src/icons.tsx +788 -0
  465. package/src/index.tsx +763 -0
  466. package/src/jest-globals.d.ts +9 -0
  467. package/src/library/MediaLibrary.tsx +141 -0
  468. package/src/library/MediaLibraryScreen.tsx +3003 -0
  469. package/src/library/components/AudioPreview.tsx +73 -0
  470. package/src/library/components/DocumentPreview.tsx +361 -0
  471. package/src/library/components/ExpandableFab.tsx +342 -0
  472. package/src/library/components/FileTiles.tsx +252 -0
  473. package/src/library/components/ImagePreview.tsx +72 -0
  474. package/src/library/components/MediaMetadataHeader.tsx +208 -0
  475. package/src/library/components/RecordAudioScreen.tsx +845 -0
  476. package/src/library/components/VideoPreview.tsx +478 -0
  477. package/src/library/components/ViewerCounter.tsx +71 -0
  478. package/src/library/compressionEstimate.ts +662 -0
  479. package/src/library/fileMetadata.ts +212 -0
  480. package/src/library/index.ts +66 -0
  481. package/src/library/libraryIconRegistry.tsx +86 -0
  482. package/src/library/libraryIcons.tsx +928 -0
  483. package/src/library/localizedFormat.ts +207 -0
  484. package/src/library/palette.ts +281 -0
  485. package/src/library/responsive.ts +49 -0
  486. package/src/locales.ts +381 -0
  487. package/src/localization.ts +1947 -0
  488. package/src/logger.ts +20 -0
  489. package/src/lowMemoryCache.ts +218 -0
  490. package/src/mediaHistory.ts +42 -0
  491. package/src/mediaStorageService.ts +546 -0
  492. package/src/memory.ts +102 -0
  493. package/src/nativeActions.ts +422 -0
  494. package/src/nativeComponentSupport.ts +60 -0
  495. package/src/networkPerformance.ts +30 -0
  496. package/src/performance.ts +137 -0
  497. package/src/performanceMonitor.ts +219 -0
  498. package/src/permissions.ts +403 -0
  499. package/src/rendering.ts +47 -0
  500. package/src/security.ts +19 -0
  501. package/src/state.ts +333 -0
  502. package/src/storage.ts +453 -0
  503. package/src/theme.tsx +467 -0
  504. package/src/types.ts +946 -0
  505. package/src/utils.ts +177 -0
  506. package/src/validation.ts +372 -0
package/README.md ADDED
@@ -0,0 +1,833 @@
1
+ # react-native-ensys-camera-x
2
+
3
+ A full-screen native Android camera for React Native. One call opens a WhatsApp-style camera —
4
+ photo/video capture, gallery multi-select, and an editor (crop, rotate, filters, stickers, emoji,
5
+ text, drawing, trim) — and gives you back the media the user picked.
6
+
7
+ **A complete media library screen is included.** `<CameraMediaLibrary />` is a single element that
8
+ renders a whole media app: the gallery grid with category tabs, a swipeable pager, the Plus/Cross
9
+ button, a full-screen viewer with a video scrubber, in-app document and audio previews, an audio
10
+ recorder, an encrypted store that survives restarts, and upload progress notifications.
11
+
12
+ **Every icon is customizable** from a single configuration object, and any icon you don't replace
13
+ keeps the one the plugin ships.
14
+
15
+ See [ICON_CUSTOMIZATION.md](ICON_CUSTOMIZATION.md) for React component, image, Android
16
+ resource, tint, and inline SVG examples and surface limitations.
17
+
18
+ **Every string is translatable.** Pass your app's active language and the plugin follows it — right
19
+ down to the native camera, with right-to-left languages handled automatically.
20
+
21
+ > **Android only.** The iOS APIs exist as typed stubs that reject with an unsupported-platform
22
+ > error, so cross-platform code still compiles.
23
+
24
+ ---
25
+
26
+ ## Requirements
27
+
28
+ | | |
29
+ | --- | --- |
30
+ | React Native | 0.85 (New Architecture, which is the default) |
31
+ | Node | 20 or newer |
32
+ | JDK | 17 |
33
+ | Android | minSdk 24 |
34
+
35
+ ---
36
+
37
+ ## Step 1 — Create a React Native project
38
+
39
+ Skip this if you already have an app.
40
+
41
+ ```sh
42
+ npx @react-native-community/cli@latest init MyApp --version 0.85.0
43
+ cd MyApp
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Step 2 — Install the plugin
49
+
50
+ ```sh
51
+ npm install react-native-ensys-camera-x react-native-sqlcipher
52
+ ```
53
+
54
+ That's the whole setup. Autolinking wires up the native code, and camera / microphone / gallery
55
+ permissions are declared and requested by the plugin itself — **you do not need to edit any Android
56
+ file.**
57
+
58
+ `react-native-sqlcipher` is the encrypted store behind the media library screen you add in Step 3.
59
+ If you only ever call `openCameraPicker()` yourself, leave it out — the camera doesn't use it.
60
+
61
+ ---
62
+
63
+ ## Step 3 — Add this one file
64
+
65
+ Open the file your project already has at:
66
+
67
+ ```
68
+ MyApp/App.tsx
69
+ ```
70
+
71
+ Delete everything in it and paste this in. This single file is your whole integration: the plugin
72
+ configuration, your icon customizations, and the complete media library screen.
73
+
74
+ ```tsx
75
+ /**
76
+ * App.tsx — react-native-ensys-camera-x
77
+ *
78
+ * Everything you need is in this one file:
79
+ * 1. CUSTOM_ICONS — replace any default icon with your own
80
+ * 2. MY_LANGUAGES — translate the plugin into your app's languages
81
+ * 3. configureCameraPlugin — plugin settings
82
+ * 4. App — the complete media library screen
83
+ */
84
+ import {
85
+ CameraMediaLibrary,
86
+ configureCameraPlugin,
87
+ type CameraAsset,
88
+ type CameraIconsConfig,
89
+ type CameraTranslationBundles,
90
+ } from 'react-native-ensys-camera-x';
91
+
92
+ // ══════════════════════════════════════════════════════════════════════════
93
+ // 1. CUSTOM ICONS ← replace any default icon here
94
+ //
95
+ // Every key is optional. Leave a key out and the plugin's own icon is used.
96
+ // See the "Icon keys" table in the README for the full list of keys.
97
+ //
98
+ // Five ways to customize an icon:
99
+ // myKey: require('./assets/my-icon.png') → your image (React Native UI)
100
+ // myKey: MyIconComponent → your React component
101
+ // myKey: { tintColor: '#25D366' } → recolour the built-in icon
102
+ // myKey: { resourceName: 'my_drawable' } → your Android drawable
103
+ // (native camera screen)
104
+ // myKey: { svg: '<svg …>…</svg>' } → inline SVG markup (both surfaces)
105
+ // ══════════════════════════════════════════════════════════════════════════
106
+ const CUSTOM_ICONS: CameraIconsConfig = {
107
+ // ---- Uncomment and edit any of these, or add your own ----
108
+ // send: { tintColor: '#25D366' },
109
+ // flashOn: require('./assets/flash-on.png'),
110
+ // crop: { resourceName: 'my_crop_icon' },
111
+ };
112
+
113
+ // ══════════════════════════════════════════════════════════════════════════
114
+ // 2. LANGUAGES ← optional; delete this block to stay in English
115
+ //
116
+ // One entry per language your app supports, keyed by language code
117
+ // ('es', 'fr', 'pt-BR', 'zh-Hans', …). Every string is optional — anything
118
+ // you don't translate stays English. Right-to-left languages (Arabic,
119
+ // Persian, Hebrew, Urdu …) flip the layout automatically.
120
+ //
121
+ // See the "Languages" section in the README for the full list of text keys.
122
+ // ══════════════════════════════════════════════════════════════════════════
123
+ const MY_LANGUAGES: CameraTranslationBundles = {
124
+ es: { done: 'Listo', cancel: 'Cancelar', photoMode: 'Foto', videoMode: 'Video' },
125
+ ar: { done: 'تم', cancel: 'إلغاء', photoMode: 'صورة', videoMode: 'فيديو' },
126
+ };
127
+
128
+ // ══════════════════════════════════════════════════════════════════════════
129
+ // 3. PLUGIN CONFIGURATION
130
+ // ══════════════════════════════════════════════════════════════════════════
131
+ configureCameraPlugin({
132
+ customIcons: CUSTOM_ICONS,
133
+ theme: 'default', // 'default' | 'dark' | 'light' | 'minimal'
134
+
135
+ translations: MY_LANGUAGES,
136
+ language: 'en', // your app's active language.
137
+ // Switch it any time with setCameraLanguage('es') — the whole
138
+ // plugin updates immediately, no restart needed.
139
+ //
140
+ // Or hand `language` a provider instead of a code and the plugin
141
+ // follows your app's language on its own, forever after:
142
+ // language: { get: () => i18n.language,
143
+ // subscribe: (cb) => { i18n.on('languageChanged', cb);
144
+ // return () => i18n.off('languageChanged', cb) } }
145
+ // See "Follow your app's language automatically" in the README.
146
+ });
147
+
148
+ // ══════════════════════════════════════════════════════════════════════════
149
+ // 4. YOUR SCREEN
150
+ //
151
+ // One element renders the whole media app: the gallery grid with its category
152
+ // tabs, the Plus button (camera / gallery / documents / audio / recorder), the
153
+ // full-screen viewer, and the encrypted store that keeps your media between
154
+ // launches. Every prop is optional.
155
+ // ══════════════════════════════════════════════════════════════════════════
156
+ export default function App() {
157
+ return (
158
+ <CameraMediaLibrary
159
+ // Where media is POSTed when the user presses Send, which is what drives
160
+ // the upload notifications. Leave it out and nothing is uploaded —
161
+ // everything else behaves exactly the same.
162
+ // uploadUrl="https://api.example.com/upload"
163
+
164
+ // Which category tab opens first:
165
+ // 'all' | 'photos' | 'videos' | 'documents' | 'audio'
166
+ initialFilter="all"
167
+ // Called whenever the library changes, so your own screens can follow it.
168
+ onAssetsChange={(assets: CameraAsset[]) => {
169
+ console.log(`${assets.length} items in the library`);
170
+ }}
171
+ />
172
+ );
173
+ }
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Step 4 — Run the app
179
+
180
+ ```sh
181
+ npm run android
182
+ ```
183
+
184
+ Tap the **+** button, then **Camera**. Take a photo or video — or pick from the gallery, edit it and
185
+ press send — and it lands in the grid and stays there between launches. Tap a tile to open the
186
+ full-screen viewer.
187
+
188
+ ---
189
+
190
+ ## Media library screen
191
+
192
+ `<CameraMediaLibrary />` is the screen from Step 3 — a complete media app in one element:
193
+
194
+ - **Gallery grid** with five category tabs (All, Photos, Videos, Documents, Audio) and a swipeable
195
+ pager between them
196
+ - **Plus/Cross button** that opens the camera, the gallery editor, the document picker, the audio
197
+ picker, or the audio recorder
198
+ - **Full-screen viewer** you swipe through, with a video scrubber, a position counter, a details
199
+ sheet, and delete / share actions
200
+ - **In-app document and audio previews** (PDF, Word, Excel, PowerPoint, text, images …) plus a mini
201
+ audio player that keeps playing as you browse
202
+ - **Encrypted storage** — media is kept in a SQLCipher database, so the library survives app restarts
203
+ - **Upload progress** in the system notification bar, once you set `uploadUrl`
204
+
205
+ **Every readout follows the host language.** The dates, times, file sizes, durations, resolutions
206
+ and the `3 / 12` position counter — in the grid rows, the full-screen viewer and the details sheet —
207
+ are formatted for the active language automatically: localized month names, a 12- or 24-hour clock,
208
+ the locale's decimal separator, and its own numerals (Arabic and Persian show their digits). There
209
+ is nothing to configure. The size-unit labels (`B`, `KB`, `MB`, `GB`) are themselves translation
210
+ keys, so those localize too when you provide them.
211
+
212
+ | Prop | Meaning |
213
+ | --- | --- |
214
+ | `uploadUrl` | Where media is POSTed when the user presses Send. Omit it and nothing is uploaded — everything else is identical |
215
+ | `initialFilter` | Category tab selected on first mount: `'all'` (default), `'photos'`, `'videos'`, `'documents'`, `'audio'` |
216
+ | `onAssetsChange` | Called with the full asset list whenever the library changes (capture, pick, delete) |
217
+ | `style` | Extra styles for the screen's root view |
218
+ | `theme` | Same values as `configureCameraPlugin`'s `theme` |
219
+ | `icons` | Icon overrides applied to this screen |
220
+ | `locale`, `bundles` | Language and translations, if you prefer props over `configureCameraPlugin` |
221
+
222
+ Configure language and icons through **either** `configureCameraPlugin` **or** these props — a
223
+ `<CameraMediaLibrary />` with no props inherits whatever you configured, and localization props
224
+ passed here take over instead of merging.
225
+
226
+ This screen needs the `react-native-sqlcipher` package from Step 2, which is its encrypted store.
227
+ The native camera doesn't: it bundles its own copy of SQLCipher, so `openCameraPicker()` works
228
+ without it.
229
+
230
+ ### Using the pieces on their own
231
+
232
+ Building your own screen instead? Every part is exported:
233
+
234
+ ```tsx
235
+ import {
236
+ MediaLibraryScreen, // the same screen, without the providers wrapped around it
237
+ RecordAudioScreen, // the audio recorder
238
+ ImagePreview, // the viewer's slides, one per media kind
239
+ VideoPreview,
240
+ DocumentPreview,
241
+ AudioPreview,
242
+ MediaMetadataHeader, // the name / size / date header
243
+ ExpandableFab, // the Plus/Cross button
244
+ ViewerCounter, // the "3 / 12" position counter
245
+ DocumentTile, // the document and audio cards
246
+ AudioTile,
247
+ libraryPalette, // the shell's colours
248
+ wp, hp, ms, fs, // and its screen-scaling helpers
249
+ } from 'react-native-ensys-camera-x';
250
+ ```
251
+
252
+ ---
253
+
254
+ ## How to use it
255
+
256
+ Prefer to build your own UI? `openCameraPicker()` is the whole API you need:
257
+
258
+ ```tsx
259
+ const result = await openCameraPicker({ mediaTypes: 'all', selectionLimit: 0 });
260
+
261
+ if (!result.cancelled) {
262
+ result.assets.forEach((asset) => {
263
+ console.log(asset.uri); // file:// path to the media
264
+ console.log(asset.type); // 'photo' | 'video' | 'document' | 'audio'
265
+ console.log(asset.fileName); // e.g. 'IMG_20260822_101500.jpg'
266
+ console.log(asset.size); // bytes
267
+ });
268
+ }
269
+ ```
270
+
271
+ | Option | Meaning |
272
+ | --- | --- |
273
+ | `mediaTypes` | `'all'` (default), `'photo'` or `'video'` |
274
+ | `selectionLimit` | Max items the user can pick. `0` = unlimited |
275
+ | `initialCamera` | `'back'` (default) or `'front'` |
276
+ | `enableVideo` | Set `false` for a photo-only camera |
277
+ | `enableFilter` | Set `false` to hide the filter tool in the editor |
278
+
279
+ ---
280
+
281
+ ## Customizing icons
282
+
283
+ All icon customization happens in the **`CUSTOM_ICONS`** block of your `App.tsx`. Nothing else to
284
+ edit, no icon library to install.
285
+
286
+ ### Replace a single icon
287
+
288
+ ```tsx
289
+ const CUSTOM_ICONS: CameraIconsConfig = {
290
+ send: require('./assets/my-send.png'),
291
+ };
292
+ ```
293
+
294
+ ### Replace multiple icons
295
+
296
+ ```tsx
297
+ const CUSTOM_ICONS: CameraIconsConfig = {
298
+ send: require('./assets/my-send.png'),
299
+ close: require('./assets/my-close.png'),
300
+ flashOn: require('./assets/flash-on.png'),
301
+ flashOff: require('./assets/flash-off.png'),
302
+ delete: { tintColor: '#EF4444' },
303
+ crop: { resourceName: 'my_crop_icon' },
304
+ };
305
+ ```
306
+
307
+ Every key you leave out keeps the plugin's default icon, so you can replace one icon or all of them.
308
+
309
+ ### The five ways to set an icon
310
+
311
+ | You write | What happens | Works on |
312
+ | --- | --- | --- |
313
+ | `require('./icon.png')` | Your image is drawn instead | React Native UI |
314
+ | `MyIconComponent` | Your React component is drawn instead | React Native UI |
315
+ | `{ tintColor: '#25D366' }` | The built-in icon is recoloured | Everywhere |
316
+ | `{ resourceName: 'my_icon' }` | Your Android drawable is drawn instead | Native camera screen |
317
+ | `{ svg: '<svg …>…</svg>' }` | Your inline SVG markup is drawn instead | Everywhere |
318
+ | `{ size: 28 }` | The icon is drawn at this size in dp | React Native UI |
319
+
320
+ You can combine them for one key:
321
+
322
+ ```tsx
323
+ close: { component: MyClose, resourceName: 'my_close', tintColor: '#FFFFFF' },
324
+ ```
325
+
326
+ ### Replace an icon with inline SVG
327
+
328
+ `svg` is the one artwork option that reaches **both** surfaces from a single string — no
329
+ `require()`, no drawable file, no `react-native-svg`. The plugin ships its own tiny SVG renderer
330
+ (React Native draws the markup through a bundled native view; the native camera/editor screen draws
331
+ it directly), so the same markup shows up everywhere the icon is used:
332
+
333
+ ```tsx
334
+ const CUSTOM_ICONS: CameraIconsConfig = {
335
+ send: {
336
+ svg: `<svg viewBox="0 0 24 24"><path d="M2 21l21-9L2 3v7l15 2-15 2z" fill="currentColor"/></svg>`,
337
+ },
338
+ // Give it a fixed colour, or leave it to follow the icon's own tint:
339
+ close: { svg: '<svg viewBox="0 0 24 24"><path d="M6 6l12 12M18 6L6 18"/></svg>', tintColor: '#FFFFFF' },
340
+ };
341
+ ```
342
+
343
+ **Supported subset.** The bundled renderer understands a practical, self-contained slice of SVG:
344
+ the `<svg>` root plus `path`, `rect`, `circle`, `ellipse`, `line`, `polyline` and `polygon`, with
345
+ `fill`, `stroke`, `stroke-width`, `opacity` and `transform` (`translate` / `scale` / `rotate`).
346
+ It does **not** run scripts, load external images/fonts, or fetch anything — keep the markup inline
347
+ and under 256 KB.
348
+
349
+ **Colour.** Use `fill="currentColor"` (or `stroke="currentColor"`) for parts that should follow the
350
+ icon's tint: `tintColor` — or, on React Native, the surrounding `color` — fills in for
351
+ `currentColor`, while any explicit colour in the markup is left untouched. With no tint, an SVG
352
+ keeps its own colours instead of being flattened to one tone.
353
+
354
+ **Safe fallback.** If the markup is empty, malformed, or uses something the renderer can't draw —
355
+ or on a platform without the native half (iOS / web) — the icon silently falls back to the
356
+ plugin's built-in default rather than showing a blank box.
357
+
358
+ > **Two surfaces, one key.** The plugin draws icons in two places: your React Native screens, and
359
+ > the native Android camera Activity. A native Android screen can't render a React component or a
360
+ > JS `require()`, so to change its artwork with an image you drop a file into
361
+ > `android/app/src/main/res/drawable/` and name it with `resourceName`. `tintColor` and `svg` need
362
+ > no extra files and reach **both** surfaces. The **Where** column in the table below tells you
363
+ > which surfaces a key reaches.
364
+
365
+ ### Changing icons at runtime
366
+
367
+ Instead of (or after) `configureCameraPlugin`, you can swap icons at any time:
368
+
369
+ ```tsx
370
+ import { setCameraIcons, resetCameraIcons } from 'react-native-ensys-camera-x';
371
+
372
+ setCameraIcons({ send: require('./assets/my-send.png') }); // merges with what's set
373
+ resetCameraIcons(); // back to all defaults
374
+ ```
375
+
376
+ ---
377
+
378
+ ## Icon keys
379
+
380
+ Every key below goes in `CUSTOM_ICONS`. **Where** tells you which surfaces the key affects:
381
+ **App** = the React Native screens (the media library screen, plus any screen of your own that uses
382
+ `RenderIcon`), **Camera** = the native camera/editor screen, **Both** = both.
383
+
384
+ ### Common controls
385
+
386
+ | Key | Used for | Where |
387
+ | --- | --- | --- |
388
+ | `close` | Close / dismiss a screen, sheet or overlay | Both |
389
+ | `back` | Back arrow in headers | Both |
390
+ | `done` | Confirm / apply the current step (checkmark) | Both |
391
+ | `cancel` | Cancel an action without applying it | App |
392
+ | `check` | Generic checkmark on list and option rows | App |
393
+ | `selectionCheck` | Checkmark badge on a selected gallery thumbnail | Camera |
394
+
395
+ ### Camera screen
396
+
397
+ | Key | Used for | Where |
398
+ | --- | --- | --- |
399
+ | `camera` | Generic camera icon (buttons that open the camera) | App |
400
+ | `photo` | Still photo / image media | App |
401
+ | `video` | Video clip media | App |
402
+ | `photoMode` | The "Photo" mode tab | Both |
403
+ | `videoMode` | The "Video" mode tab | Both |
404
+ | `flipCamera` | Switch between front and back camera | Both |
405
+ | `flashOn` | Flash forced on | Both |
406
+ | `flashOff` | Flash off | Both |
407
+ | `flashAuto` | Flash in automatic mode | Both |
408
+ | `gallery` | Gallery / recent media (bottom-left thumbnail) | Both |
409
+ | `record` | Start recording (record dot) | App |
410
+ | `mic` | Microphone — audio recording entry points | App |
411
+ | `lock` | Locked state — hands-free recording engaged | Both |
412
+ | `lockOpen` | The slide-to-lock rail shown while holding to record | Both |
413
+
414
+ ### Editor tools
415
+
416
+ | Key | Used for | Where |
417
+ | --- | --- | --- |
418
+ | `crop` | Crop tool | Both |
419
+ | `rotate` | Rotate the image 90° | Both |
420
+ | `aspectRatio` | Aspect-ratio picker inside the crop tool | Camera |
421
+ | `filter` | Colour filter strip | Both |
422
+ | `sticker` | Add-sticker tool | Both |
423
+ | `emoji` | Add-emoji tool | Both |
424
+ | `gif` | Add-GIF tool | Camera |
425
+ | `text` | Add-text tool | Both |
426
+ | `textBackground` | Cycle the text background style while typing | Camera |
427
+ | `textAlignLeft` | Text aligned left | Camera |
428
+ | `textAlignCenter` | Text aligned centre | Camera |
429
+ | `textAlignRight` | Text aligned right | Camera |
430
+ | `draw` | Freehand drawing tool | App |
431
+ | `marker` | Marker / pen tool | Camera |
432
+ | `brushThin` | Thin brush width | Camera |
433
+ | `brushMedium` | Medium brush width | Camera |
434
+ | `brushThick` | Thick brush width | Camera |
435
+ | `clearDrawing` | Erase every drawing stroke | Camera |
436
+ | `undo` | Undo the last edit | Both |
437
+ | `redo` | Redo the last undone edit | Both |
438
+ | `overlayClose` | The X that deletes a selected sticker / emoji / GIF / text | Camera |
439
+ | `overlayResize` | The corner handle that resizes a selected overlay | Camera |
440
+
441
+ ### Media actions & playback
442
+
443
+ | Key | Used for | Where |
444
+ | --- | --- | --- |
445
+ | `play` | Play video or audio | Both |
446
+ | `pause` | Pause playback or recording | Both |
447
+ | `stop` | Stop playback or recording | App |
448
+ | `volumeOn` | Sound on — video audio is kept | Both |
449
+ | `volumeOff` | Sound off — video is muted | Both |
450
+ | `mute` | Muted indicator on a media tile | App |
451
+ | `trim` | Trim a video clip | Both |
452
+ | `cover` | Pick a video's cover frame | Both |
453
+ | `compress` | Compress an image or video | App |
454
+ | `export` | Export in another file format | App |
455
+ | `send` | Send / confirm the selected media | Both |
456
+ | `download` | Save media to the device | Both |
457
+ | `share` | Share media with another app | Both |
458
+ | `delete` | Delete / remove media | Both |
459
+ | `trash` | Dustbin when dragging an overlay away, and bulk-delete bars | App |
460
+ | `more` | Generic overflow / "more" affordance | App |
461
+ | `moreOptions` | The ⋮ overflow button in the preview header | Camera |
462
+ | `upload` | Upload media to a server | App |
463
+ | `uploadStatus` | Status-bar icon of the upload notification (monochrome vector only) | Camera |
464
+
465
+ ### Documents & audio
466
+
467
+ | Key | Used for | Where |
468
+ | --- | --- | --- |
469
+ | `document` | Document file (PDF, DOCX, …) | Both |
470
+ | `audio` | Audio file | Both |
471
+ | `browseAudio` | Browse the device for an audio file | App |
472
+ | `imageVideo` | Combined image-or-video picker entry point | App |
473
+
474
+ ### Indicators
475
+
476
+ | Key | Used for | Where |
477
+ | --- | --- | --- |
478
+ | `chevronUp` | Upward chevron — swipe-up hints, expanding panels | Both |
479
+ | `chevronDown` | Downward chevron — collapsing the colour palette | Camera |
480
+ | `chevronRight` | Forward chevron on navigable rows | App |
481
+ | `warning` | Warning / error state | App |
482
+ | `plus` | Add / expand (the floating action button) | App |
483
+ | `minus` | Remove / collapse | App |
484
+
485
+ ---
486
+
487
+ ## Icons by screen
488
+
489
+ The tables above group icons by feature. This section groups the **same keys** by the screen they
490
+ actually appear on, so you can see at a glance which icons your users meet on the React Native side
491
+ and which live inside the native camera and editor.
492
+
493
+ Your **React Native screens** draw the keys under *React Native screens* **and** *Both screens*. The
494
+ **native camera / editor** draws the keys under *Native camera screen* **and** *Both screens*.
495
+
496
+ ### React Native screens
497
+
498
+ The media library grid, the full-screen viewer, the record-audio screen and the expandable "+" menu.
499
+
500
+ | Key | Used for |
501
+ | --- | --- |
502
+ | `camera` | Buttons that open the camera |
503
+ | `photo` | Still photo / image media |
504
+ | `video` | Video clip media |
505
+ | `record` | Start recording (record dot) |
506
+ | `mic` | Microphone — audio recording entry points |
507
+ | `draw` | Freehand drawing tool |
508
+ | `stop` | Stop playback or recording |
509
+ | `mute` | Muted indicator on a media tile |
510
+ | `compress` | Compress an image or video |
511
+ | `export` | Export in another file format |
512
+ | `trash` | Dustbin when dragging an overlay away, and bulk-delete bars |
513
+ | `more` | Generic overflow / "more" affordance |
514
+ | `upload` | Upload media to a server |
515
+ | `browseAudio` | Browse the device for an audio file |
516
+ | `imageVideo` | Combined image-or-video picker entry point |
517
+ | `chevronRight` | Forward chevron on navigable rows |
518
+ | `warning` | Warning / error state |
519
+ | `plus` | Add / expand affordance |
520
+ | `minus` | Remove / collapse |
521
+ | `plusClose` | Animated FAB plus-to-close morph |
522
+ | `circularSeek` | Video player -10s / +10s seek rings |
523
+ | `viewDetails` | View Details metadata button |
524
+ | `cancel` | Cancel an action without applying it |
525
+ | `check` | Generic checkmark on list and option rows |
526
+
527
+ ### Native camera screen
528
+
529
+ The native camera Activity and the native photo / video editor.
530
+
531
+ | Key | Used for |
532
+ | --- | --- |
533
+ | `selectionCheck` | Checkmark badge on a selected gallery thumbnail |
534
+ | `aspectRatio` | Aspect-ratio picker inside the crop tool |
535
+ | `gif` | Add-GIF tool |
536
+ | `textBackground` | Cycle the text background style while typing |
537
+ | `textAlignLeft` | Text aligned left |
538
+ | `textAlignCenter` | Text aligned centre |
539
+ | `textAlignRight` | Text aligned right |
540
+ | `marker` | Marker / pen tool |
541
+ | `brushThin` | Thin brush width |
542
+ | `brushMedium` | Medium brush width |
543
+ | `brushThick` | Thick brush width |
544
+ | `clearDrawing` | Erase every drawing stroke |
545
+ | `overlayClose` | The X that deletes a selected sticker / emoji / GIF / text |
546
+ | `overlayResize` | The corner handle that resizes a selected overlay |
547
+ | `moreOptions` | The ⋮ overflow button in the preview header |
548
+ | `uploadStatus` | Status-bar icon of the upload notification (monochrome vector only) |
549
+ | `chevronDown` | Downward chevron — collapsing the colour palette |
550
+
551
+ ### Both screens
552
+
553
+ These render on the React Native screens **and** inside the native camera / editor.
554
+
555
+ | Key | Used for |
556
+ | --- | --- |
557
+ | `close` | Close / dismiss a screen, sheet or overlay |
558
+ | `back` | Back arrow in headers |
559
+ | `done` | Confirm / apply the current step (checkmark) |
560
+ | `photoMode` | The "Photo" mode tab |
561
+ | `videoMode` | The "Video" mode tab |
562
+ | `flipCamera` | Switch between front and back camera |
563
+ | `flashOn` | Flash forced on |
564
+ | `flashOff` | Flash off |
565
+ | `flashAuto` | Flash in automatic mode |
566
+ | `gallery` | Gallery / recent media (bottom-left thumbnail) |
567
+ | `lock` | Locked state — hands-free recording engaged |
568
+ | `lockOpen` | The slide-to-lock rail shown while holding to record |
569
+ | `crop` | Crop tool |
570
+ | `rotate` | Rotate the image 90° |
571
+ | `filter` | Colour filter strip |
572
+ | `sticker` | Add-sticker tool |
573
+ | `emoji` | Add-emoji tool |
574
+ | `text` | Add-text tool |
575
+ | `undo` | Undo the last edit |
576
+ | `redo` | Redo the last undone edit |
577
+ | `play` | Play video or audio |
578
+ | `pause` | Pause playback or recording |
579
+ | `volumeOn` | Sound on — video audio is kept |
580
+ | `volumeOff` | Sound off — video is muted |
581
+ | `trim` | Trim a video clip |
582
+ | `cover` | Pick a video's cover frame |
583
+ | `send` | Send / confirm the selected media |
584
+ | `download` | Save media to the device |
585
+ | `share` | Share media with another app |
586
+ | `delete` | Delete / remove media |
587
+ | `chevronUp` | Upward chevron — swipe-up hints, expanding panels |
588
+ | `document` | Document file (PDF, DOCX, …) |
589
+ | `audio` | Audio file |
590
+
591
+ > The media-library "+" button's animated `+`↔`×` morph, the video player's ±10-second skip rings,
592
+ > and the "View details" `i` are customizable through `plusClose`, `circularSeek`, and
593
+ > `viewDetails`. Custom components receive the active theme-derived color and the interaction
594
+ > props they need (`progress`, `direction`, and the localized `label`).
595
+
596
+ ---
597
+
598
+ ## Languages
599
+
600
+ The plugin displays whatever language your app is in. It has no language selector of its own and
601
+ keeps no language state — you pass your app's active language code, and every screen (including the
602
+ native camera and editor) follows it. English is always the fallback, so you only translate what you
603
+ want to translate.
604
+
605
+ Set it up **once** with a language provider and you never have to tell the plugin about a language
606
+ change again — see [Follow your app's language automatically](#follow-your-apps-language-automatically).
607
+
608
+ ### Set the language
609
+
610
+ Both of these are shown in the `App.tsx` above:
611
+
612
+ ```tsx
613
+ configureCameraPlugin({
614
+ translations: MY_LANGUAGES, // one entry per language, keyed by code
615
+ language: 'en', // your app's active language
616
+ });
617
+ ```
618
+
619
+ To switch language later — from a settings screen, a language picker, anywhere:
620
+
621
+ ```tsx
622
+ import { setCameraLanguage } from 'react-native-ensys-camera-x';
623
+
624
+ setCameraLanguage('es'); // takes effect immediately, no restart
625
+ ```
626
+
627
+ If your app keeps its language in React state or context, wrap your screens instead and the plugin
628
+ follows the prop:
629
+
630
+ ```tsx
631
+ import { CameraLocalizationProvider } from 'react-native-ensys-camera-x';
632
+
633
+ <CameraLocalizationProvider locale={myAppLanguage} bundles={MY_LANGUAGES}>
634
+ <MyScreens />
635
+ </CameraLocalizationProvider>;
636
+ ```
637
+
638
+ Already using **i18next**, **i18n-js** or similar? Hand over your `t` function and skip the bundles
639
+ entirely:
640
+
641
+ ```tsx
642
+ <CameraLocalizationProvider locale={i18n.language} translate={(key) => t(`camera.${key}`)}>
643
+ ```
644
+
645
+ ### Follow your app's language automatically
646
+
647
+ Instead of calling `setCameraLanguage()` on every switch, hand `language` a small **provider** — an
648
+ object with `get()` and `subscribe()`. Configure it once at startup and from then on the whole plugin
649
+ follows your app on its own: React Native screens re-render, and the new translations, language code
650
+ and text direction are pushed to the native camera and editor live.
651
+
652
+ ```tsx
653
+ import { configureCameraPlugin } from 'react-native-ensys-camera-x';
654
+ import i18n from './i18n';
655
+
656
+ configureCameraPlugin({
657
+ translations: MY_LANGUAGES,
658
+ language: {
659
+ get: () => i18n.language,
660
+ subscribe: (onChange) => {
661
+ i18n.on('languageChanged', onChange);
662
+ return () => i18n.off('languageChanged', onChange); // returned so it can be released
663
+ },
664
+ },
665
+ });
666
+ ```
667
+
668
+ That is the entire integration. No `setCameraLanguage()` calls anywhere else in your app.
669
+
670
+ Any language source works — the provider is just two functions:
671
+
672
+ ```tsx
673
+ // Redux / Zustand / any store
674
+ language: {
675
+ get: () => store.getState().language,
676
+ subscribe: (onChange) => store.subscribe(onChange),
677
+ }
678
+
679
+ // Your own emitter
680
+ language: {
681
+ get: () => Settings.language,
682
+ subscribe: (onChange) => {
683
+ const sub = Settings.events.addListener('language', onChange);
684
+ return () => sub.remove();
685
+ },
686
+ }
687
+ ```
688
+
689
+ `subscribe` may return an unsubscribe function, an object with `remove()` or `unsubscribe()`, or
690
+ nothing at all. Your callback may be handed the new code (i18next passes it) or called bare — the
691
+ plugin re-reads `get()` when no code arrives.
692
+
693
+ You can also bind it on its own, at any time:
694
+
695
+ ```tsx
696
+ import {
697
+ setCameraLanguageProvider,
698
+ clearCameraLanguageProvider,
699
+ syncCameraLanguage,
700
+ } from 'react-native-ensys-camera-x';
701
+
702
+ setCameraLanguageProvider({ get: () => i18n.language, subscribe: … });
703
+
704
+ clearCameraLanguageProvider(); // back to manual switching
705
+ syncCameraLanguage(); // force a re-read, if your source can't notify
706
+ ```
707
+
708
+ Notes worth knowing:
709
+
710
+ - **Your app stays the single source of truth.** The plugin never reads the device locale and keeps
711
+ no language of its own — it mirrors whatever `get()` reports.
712
+ - **Binding is idempotent.** Passing the same provider object again re-reads it without adding a
713
+ second listener; passing a different one releases the previous subscription first. Safe to call
714
+ from a startup path that runs more than once.
715
+ - **`setCameraLanguage()` still works** as a manual fallback while a provider is bound. The next
716
+ change your provider reports wins, because your app owns the language.
717
+ - **Bundles and the English fallback are untouched.** Register `translations` once and the provider
718
+ just picks the right bundle; missing keys still fall back to `fallbackLanguage`, then to English.
719
+
720
+ ### Language codes
721
+
722
+ Any standard code works — `en`, `es`, `fr`, `de`, `it`, `pt`, `pt-BR`, `ru`, `pl`, `ro`, `da`, `sv`,
723
+ `uk`, `tr`, `vi`, `hi`, `bn`, `ja`, `ko`, `fa`, `ar`, `zh-Hans`, `zh-Hant`, … There is no list of
724
+ supported languages inside the plugin: it reads the code you give it, so adding a language to your
725
+ app never requires a plugin change.
726
+
727
+ Regional and script variants fall back sensibly, so one bundle can cover several codes:
728
+
729
+ | You provide | Covers |
730
+ | --- | --- |
731
+ | `pt` | `pt`, `pt-BR`, `pt-PT` |
732
+ | `zh-Hans` | `zh-Hans`, `zh-CN`, `zh-SG` |
733
+ | `zh-Hant` | `zh-Hant`, `zh-TW`, `zh-HK` |
734
+ | `fa` | `fa`, `fa-AF`, `prs` (Dari) |
735
+ | *(nothing)* | English |
736
+
737
+ ### Right-to-left languages
738
+
739
+ Arabic, Persian/Farsi, Hebrew, Urdu and other RTL languages are detected from the language code —
740
+ you don't maintain a list or pass a flag. Setting `language: 'ar'` mirrors the layout, flips text
741
+ alignment, and repositions toolbars and controls across both the React Native screens and the native
742
+ camera.
743
+
744
+ To force a direction anyway, pass `isRtl` and it wins:
745
+
746
+ ```tsx
747
+ <CameraLocalizationProvider locale="ku" bundles={MY_LANGUAGES} isRtl={false}>
748
+ ```
749
+
750
+ ### Translating your own screens
751
+
752
+ The same strings are available to your components:
753
+
754
+ ```tsx
755
+ import { useCameraLocalization } from 'react-native-ensys-camera-x';
756
+
757
+ const { t, locale, isRtl, textAlign } = useCameraLocalization();
758
+
759
+ <Text style={{ textAlign }}>{t('gallery')}</Text>;
760
+ ```
761
+
762
+ ### Full list of text keys
763
+
764
+ Every button, label, dialog, error message, editor and camera control, video control, empty state,
765
+ permission prompt and metadata format has a key. The complete list — over 400 keys, each with its
766
+ English default — is in **[MULTILINGUAL_INTEGRATION.md](./MULTILINGUAL_INTEGRATION.md)**, along with
767
+ ready-made integration patterns. You can also read the defaults at runtime:
768
+
769
+ ```tsx
770
+ import { defaultTranslations } from 'react-native-ensys-camera-x';
771
+
772
+ console.log(Object.keys(defaultTranslations)); // every available key
773
+ ```
774
+
775
+ A few keys carry placeholders (`{0}`, `{1}`) that are filled in at runtime — keep them in your
776
+ translation: `selectedCount: '{0} seleccionados'`.
777
+
778
+ ---
779
+
780
+ ## Other pickers (optional)
781
+
782
+ Same `{ cancelled, assets }` result as `openCameraPicker`:
783
+
784
+ ```tsx
785
+ import {
786
+ openDocumentPicker,
787
+ openAudioPicker,
788
+ openImageVideoPicker,
789
+ openGalleryEditor,
790
+ } from 'react-native-ensys-camera-x';
791
+
792
+ await openDocumentPicker(); // PDFs, Word, Excel, …
793
+ await openAudioPicker(); // audio files
794
+ await openImageVideoPicker(); // system photo/video picker
795
+ await openGalleryEditor(); // pick from the gallery, straight into the editor
796
+ ```
797
+
798
+ ---
799
+
800
+ ## Troubleshooting
801
+
802
+ | Problem | Fix |
803
+ | --- | --- |
804
+ | `openCameraPicker is not a function` | Stop Metro and rebuild: `npm run android`. Native modules need a rebuild, not a reload. |
805
+ | `'react-native-sqlcipher' is not available` | The media library screen needs it: `npm install react-native-sqlcipher`, then rebuild. |
806
+ | Build fails with *More than one file was found with OS independent path `lib/…/libcrypto.so`* | Two libraries ship the same native library. Add the `packagingOptions` block below to `android/app/build.gradle`. |
807
+ | A custom icon doesn't show on the camera screen | The native screen can't draw a `require()` or a React component. Use `resourceName` (a drawable in `android/app/src/main/res/drawable/`), or an inline `svg` — both reach the native screen. |
808
+ | Your PNG icon looks flat / single-coloured | Remove `tintColor` for that key — it recolours the whole image. |
809
+ | Your inline `svg` shows the default icon instead | The markup is empty, over 256 KB, or uses something outside the supported subset (gradients, `<text>`, `<image>`, filters, CSS, arc path commands). Simplify it to `path`/`rect`/`circle`/`ellipse`/`line`/`polyline`/`polygon`, or check it renders on the native screen — it falls back to the built-in icon on iOS / web. |
810
+ | The camera asks for permission again | Android grants "Only this time" permissions for one session. Choose "While using the app" to keep it. |
811
+ | A screen is still in English | That key isn't in the bundle for the active language. Check the code you passed matches a key in `translations`, and that the key names match the list in [MULTILINGUAL_INTEGRATION.md](./MULTILINGUAL_INTEGRATION.md). |
812
+ | Build fails on SDK version | Your app needs `minSdkVersion 24` or higher in `android/build.gradle`. |
813
+
814
+ The duplicate-native-library fix, inside the existing `android { … }` block of
815
+ `android/app/build.gradle`:
816
+
817
+ ```gradle
818
+ android {
819
+ // …
820
+
821
+ packagingOptions {
822
+ pickFirst "**/libc++_shared.so"
823
+ pickFirst "**/libcrypto.so"
824
+ pickFirst "**/libssl.so"
825
+ }
826
+ }
827
+ ```
828
+
829
+ ---
830
+
831
+ ## License
832
+
833
+ MIT © Asif Ali