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
@@ -0,0 +1,361 @@
1
+ package com.customcamera
2
+
3
+ import android.Manifest
4
+ import android.content.BroadcastReceiver
5
+ import android.content.Context
6
+ import android.content.Intent
7
+ import android.content.IntentFilter
8
+ import android.content.pm.PackageManager
9
+ import android.graphics.Color
10
+ import android.graphics.drawable.GradientDrawable
11
+ import android.os.Bundle
12
+ import android.util.Log
13
+ import android.util.TypedValue
14
+ import android.view.Gravity
15
+ import android.view.View
16
+ import android.view.ViewGroup
17
+ import android.widget.FrameLayout
18
+ import android.widget.ImageButton
19
+ import android.widget.TextView
20
+ import androidx.activity.ComponentActivity
21
+ import androidx.annotation.OptIn
22
+ import androidx.camera.core.Camera
23
+ import androidx.camera.core.CameraSelector
24
+ import androidx.camera.core.ExperimentalGetImage
25
+ import androidx.camera.core.ImageAnalysis
26
+ import androidx.camera.core.ImageProxy
27
+ import androidx.camera.core.Preview
28
+ import androidx.camera.lifecycle.ProcessCameraProvider
29
+ import androidx.camera.view.PreviewView
30
+ import androidx.core.content.ContextCompat
31
+ import androidx.core.view.WindowCompat
32
+ import androidx.localbroadcastmanager.content.LocalBroadcastManager
33
+ import com.google.mlkit.vision.barcode.BarcodeScannerOptions
34
+ import com.google.mlkit.vision.barcode.BarcodeScanning
35
+ import com.google.mlkit.vision.barcode.common.Barcode
36
+ import com.google.mlkit.vision.common.InputImage
37
+ import java.util.concurrent.ExecutorService
38
+ import java.util.concurrent.Executors
39
+
40
+ /**
41
+ * Full-screen barcode / QR scanner.
42
+ *
43
+ * Self-contained CameraX ([Preview] + [ImageAnalysis]) + ML Kit pipeline, intentionally kept
44
+ * separate from the 3274-line [CustomCameraActivity] so the capture screen is untouched. Returns
45
+ * the first decoded value via [EXTRA_RESULT_VALUE] (and its human-readable format via
46
+ * [EXTRA_RESULT_FORMAT]) using the standard Activity result contract; the owning
47
+ * [CustomCameraModule.scanQRCode] resolves its promise from onActivityResult.
48
+ */
49
+ class BarcodeScannerActivity : ComponentActivity() {
50
+
51
+ private lateinit var previewView: PreviewView
52
+ // Rendered as a MONOCHROME bolt glyph (⚡ + U+FE0E text-presentation selector) in a TextView —
53
+ // not a color emoji — so setTextColor(WHITE) tints it white like the rest of the UI. The on/off
54
+ // state is shown via alpha in toggleTorch().
55
+ private lateinit var torchButton: TextView
56
+ private lateinit var cameraExecutor: ExecutorService
57
+
58
+ private var camera: Camera? = null
59
+
60
+ /**
61
+ * Latches once the first barcode is delivered so a burst of successful frames can never call
62
+ * setResult()/finish() twice (which would leak a second result and, upstream, double-resolve
63
+ * the JS promise). Written and read only on the main thread (ML Kit success callbacks post
64
+ * there), but kept @Volatile as defensive documentation of the invariant.
65
+ */
66
+ @Volatile
67
+ private var resultDelivered = false
68
+ private var torchOn = false
69
+
70
+ private val scanner by lazy {
71
+ BarcodeScanning.getClient(
72
+ BarcodeScannerOptions.Builder()
73
+ .setBarcodeFormats(Barcode.FORMAT_ALL_FORMATS)
74
+ .build()
75
+ )
76
+ }
77
+
78
+ private val localizers = mutableListOf<() -> Unit>()
79
+
80
+ private fun TextView.bindText(key: String, default: String, vararg args: Any) {
81
+ val updater = { this.text = Localization.getString(key, default, *args) }
82
+ updater()
83
+ localizers.add(updater)
84
+ }
85
+
86
+ private fun View.bindContentDescription(key: String, default: String, vararg args: Any) {
87
+ val updater = { this.contentDescription = Localization.getString(key, default, *args) }
88
+ updater()
89
+ localizers.add(updater)
90
+ }
91
+
92
+ private val localizationReceiver = object : BroadcastReceiver() {
93
+ override fun onReceive(context: Context?, intent: Intent?) {
94
+ window.decorView.rootView.layoutDirection = if (Localization.isRtl) View.LAYOUT_DIRECTION_RTL else View.LAYOUT_DIRECTION_LTR
95
+ localizers.forEach { it.invoke() }
96
+ }
97
+ }
98
+
99
+ override fun onCreate(savedInstanceState: Bundle?) {
100
+ super.onCreate(savedInstanceState)
101
+
102
+ window.decorView.rootView.layoutDirection = if (Localization.isRtl) View.LAYOUT_DIRECTION_RTL else View.LAYOUT_DIRECTION_LTR
103
+ cameraExecutor = Executors.newSingleThreadExecutor()
104
+ setContentView(buildUi())
105
+
106
+ // Match the system bars to the scanner's own backdrop (dark by default, but host-overridable
107
+ // via components.barcodeScanner.background): transparent bars with a light/dark icon appearance
108
+ // picked from the resolved backdrop so the status/nav icons stay legible over it.
109
+ val scannerBackground = CameraTheme.get(this).componentColor("barcodeScanner", "background", Color.BLACK)
110
+ window.statusBarColor = Color.TRANSPARENT
111
+ window.navigationBarColor = Color.TRANSPARENT
112
+ val lightBars = !isColorDark(scannerBackground)
113
+ WindowCompat.getInsetsController(window, window.decorView).apply {
114
+ isAppearanceLightStatusBars = lightBars
115
+ isAppearanceLightNavigationBars = lightBars
116
+ }
117
+
118
+ LocalBroadcastManager.getInstance(this).registerReceiver(
119
+ localizationReceiver, IntentFilter(Localization.ACTION_LOCALIZATION_CHANGED)
120
+ )
121
+
122
+ if (hasCameraPermission()) {
123
+ startCamera()
124
+ } else {
125
+ requestPermissions(arrayOf(Manifest.permission.CAMERA), PERMISSION_REQUEST)
126
+ }
127
+ }
128
+
129
+ // ── UI ────────────────────────────────────────────────────────────────────
130
+
131
+ private fun buildUi(): View {
132
+ val theme = CameraTheme.get(this)
133
+ val root = FrameLayout(this).apply {
134
+ layoutParams = ViewGroup.LayoutParams(MATCH, MATCH)
135
+ setBackgroundColor(theme.componentColor("barcodeScanner", "background", Color.BLACK))
136
+ }
137
+
138
+ previewView = PreviewView(this).apply {
139
+ layoutParams = FrameLayout.LayoutParams(MATCH, MATCH)
140
+ }
141
+ root.addView(previewView)
142
+
143
+ // Minimal centered scan frame (transparent fill, rounded border).
144
+ val frameSize = dp(250)
145
+ val scanFrame = View(this).apply {
146
+ layoutParams = FrameLayout.LayoutParams(frameSize, frameSize, Gravity.CENTER)
147
+ background = GradientDrawable().apply {
148
+ setColor(Color.TRANSPARENT)
149
+ setStroke(dp(3), theme.componentColor("barcodeScanner", "frameBorder", Color.WHITE))
150
+ cornerRadius = dp(16).toFloat()
151
+ }
152
+ }
153
+ root.addView(scanFrame)
154
+
155
+ val hint = TextView(this).apply {
156
+ layoutParams = FrameLayout.LayoutParams(WRAP, WRAP, Gravity.CENTER_HORIZONTAL).apply {
157
+ topMargin = dp(140)
158
+ }
159
+ bindText("pointCameraAtBarcode", "Point the camera at a QR code or barcode")
160
+ setTextColor(theme.componentColor("barcodeScanner", "hintText", Color.WHITE))
161
+ textSize = 14f
162
+ }
163
+ root.addView(hint)
164
+
165
+ val closeButton = ImageButton(this).apply {
166
+ layoutParams = FrameLayout.LayoutParams(dp(48), dp(48), Gravity.TOP or Gravity.START).apply {
167
+ topMargin = dp(40)
168
+ marginStart = dp(16)
169
+ }
170
+ setImageDrawable(theme.config.iconDrawable(this@BarcodeScannerActivity, "close", R.drawable.ic_close))
171
+ theme.config.iconTint("close")?.let { setColorFilter(it) }
172
+ background = circleBackground()
173
+ setPadding(dp(10), dp(10), dp(10), dp(10))
174
+ bindContentDescription("closeScanner", "Close scanner")
175
+ setOnClickListener { cancel() }
176
+ }
177
+ root.addView(closeButton)
178
+
179
+ torchButton = TextView(this).apply {
180
+ layoutParams = FrameLayout.LayoutParams(dp(48), dp(48), Gravity.TOP or Gravity.END).apply {
181
+ topMargin = dp(40)
182
+ marginEnd = dp(16)
183
+ }
184
+ text = "⚡︎"
185
+ gravity = Gravity.CENTER
186
+ includeFontPadding = false
187
+ setTextColor(theme.componentColor("barcodeScanner", "torchGlyph", Color.WHITE))
188
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, dp(22).toFloat())
189
+ // Dimmed until the torch is switched on (see toggleTorch).
190
+ alpha = 0.4f
191
+ background = circleBackground()
192
+ bindContentDescription("toggleFlashlight", "Toggle flashlight")
193
+ setOnClickListener { toggleTorch() }
194
+ }
195
+ root.addView(torchButton)
196
+
197
+ return root
198
+ }
199
+
200
+ private fun circleBackground(): GradientDrawable = GradientDrawable().apply {
201
+ shape = GradientDrawable.OVAL
202
+ setColor(
203
+ CameraTheme.get(this@BarcodeScannerActivity)
204
+ .componentColor("barcodeScanner", "buttonBackground", 0x66000000)
205
+ )
206
+ }
207
+
208
+ private fun toggleTorch() {
209
+ val control = camera?.cameraControl ?: return
210
+ if (camera?.cameraInfo?.hasFlashUnit() != true) return
211
+ torchOn = !torchOn
212
+ control.enableTorch(torchOn)
213
+ // Bright when on, dimmed when off — the 🔦 glyph itself is unchanged.
214
+ torchButton.alpha = if (torchOn) 1f else 0.4f
215
+ }
216
+
217
+ // ── Camera + analysis ───────────────────────────────────────────────────────
218
+
219
+ private fun startCamera() {
220
+ val providerFuture = ProcessCameraProvider.getInstance(this)
221
+ providerFuture.addListener(
222
+ {
223
+ // Not lifecycle-scoped: can fire after the user backed out. Binding a destroyed owner
224
+ // throws, so bail if we're already tearing down.
225
+ if (isFinishing || isDestroyed) return@addListener
226
+ try {
227
+ bindCamera(providerFuture.get())
228
+ } catch (e: Exception) {
229
+ Log.e(TAG, "Failed to start barcode scanner camera", e)
230
+ cancel()
231
+ }
232
+ },
233
+ ContextCompat.getMainExecutor(this)
234
+ )
235
+ }
236
+
237
+ private fun bindCamera(provider: ProcessCameraProvider) {
238
+ val preview = Preview.Builder().build().also {
239
+ it.setSurfaceProvider(previewView.surfaceProvider)
240
+ }
241
+
242
+ val analysis = ImageAnalysis.Builder()
243
+ .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
244
+ .build()
245
+ .also { it.setAnalyzer(cameraExecutor) { proxy -> analyze(proxy) } }
246
+
247
+ // hasCamera() can throw CameraInfoUnavailableException, so probe it safely (mirrors
248
+ // CustomCameraActivity.hasCameraSafe) and prefer the back camera for scanning.
249
+ val hasBack = runCatching { provider.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA) }.getOrDefault(false)
250
+ val selector =
251
+ if (hasBack) CameraSelector.DEFAULT_BACK_CAMERA else CameraSelector.DEFAULT_FRONT_CAMERA
252
+
253
+ provider.unbindAll()
254
+ camera = provider.bindToLifecycle(this, selector, preview, analysis)
255
+ }
256
+
257
+ @OptIn(ExperimentalGetImage::class)
258
+ private fun analyze(imageProxy: ImageProxy) {
259
+ if (resultDelivered) {
260
+ imageProxy.close()
261
+ return
262
+ }
263
+ val mediaImage = imageProxy.image
264
+ if (mediaImage == null) {
265
+ imageProxy.close()
266
+ return
267
+ }
268
+
269
+ val input = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
270
+ scanner.process(input)
271
+ .addOnSuccessListener { barcodes ->
272
+ val hit = barcodes.firstOrNull { !it.rawValue.isNullOrEmpty() }
273
+ if (hit != null && !resultDelivered) {
274
+ resultDelivered = true
275
+ deliverResult(hit.rawValue!!, formatName(hit.format))
276
+ }
277
+ }
278
+ .addOnFailureListener { e -> Log.w(TAG, "Barcode analysis failed", e) }
279
+ // MUST always close the proxy, or STRATEGY_KEEP_ONLY_LATEST stops delivering frames
280
+ // and scanning silently freezes.
281
+ .addOnCompleteListener { imageProxy.close() }
282
+ }
283
+
284
+ private fun deliverResult(value: String, format: String) {
285
+ runOnUiThread {
286
+ setResult(
287
+ RESULT_OK,
288
+ Intent()
289
+ .putExtra(EXTRA_RESULT_VALUE, value)
290
+ .putExtra(EXTRA_RESULT_FORMAT, format)
291
+ )
292
+ finish()
293
+ }
294
+ }
295
+
296
+ private fun cancel() {
297
+ setResult(RESULT_CANCELED)
298
+ finish()
299
+ }
300
+
301
+ // ── Permissions ─────────────────────────────────────────────────────────────
302
+
303
+ private fun hasCameraPermission(): Boolean =
304
+ ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
305
+ PackageManager.PERMISSION_GRANTED
306
+
307
+ override fun onRequestPermissionsResult(
308
+ requestCode: Int,
309
+ permissions: Array<String>,
310
+ grantResults: IntArray
311
+ ) {
312
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
313
+ if (requestCode != PERMISSION_REQUEST) return
314
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
315
+ startCamera()
316
+ } else {
317
+ cancel()
318
+ }
319
+ }
320
+
321
+ override fun onDestroy() {
322
+ super.onDestroy()
323
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(localizationReceiver)
324
+ if (::cameraExecutor.isInitialized) cameraExecutor.shutdown()
325
+ scanner.close()
326
+ }
327
+
328
+ // ── Helpers ───────────────────────────────────────────────────────────────
329
+
330
+ private fun dp(value: Int): Int = (value * resources.displayMetrics.density).toInt()
331
+
332
+ private fun formatName(format: Int): String = when (format) {
333
+ Barcode.FORMAT_QR_CODE -> "QR_CODE"
334
+ Barcode.FORMAT_AZTEC -> "AZTEC"
335
+ Barcode.FORMAT_DATA_MATRIX -> "DATA_MATRIX"
336
+ Barcode.FORMAT_PDF417 -> "PDF417"
337
+ Barcode.FORMAT_EAN_13 -> "EAN_13"
338
+ Barcode.FORMAT_EAN_8 -> "EAN_8"
339
+ Barcode.FORMAT_UPC_A -> "UPC_A"
340
+ Barcode.FORMAT_UPC_E -> "UPC_E"
341
+ Barcode.FORMAT_CODE_128 -> "CODE_128"
342
+ Barcode.FORMAT_CODE_39 -> "CODE_39"
343
+ Barcode.FORMAT_CODE_93 -> "CODE_93"
344
+ Barcode.FORMAT_CODABAR -> "CODABAR"
345
+ Barcode.FORMAT_ITF -> "ITF"
346
+ else -> "UNKNOWN"
347
+ }
348
+
349
+ companion object {
350
+ private const val TAG = "BarcodeScanner"
351
+ private const val PERMISSION_REQUEST = 9301
352
+ private val MATCH = ViewGroup.LayoutParams.MATCH_PARENT
353
+ private val WRAP = ViewGroup.LayoutParams.WRAP_CONTENT
354
+
355
+ const val EXTRA_RESULT_VALUE = "com.customcamera.extra.SCAN_VALUE"
356
+ const val EXTRA_RESULT_FORMAT = "com.customcamera.extra.SCAN_FORMAT"
357
+
358
+ fun createIntent(context: Context): Intent =
359
+ Intent(context, BarcodeScannerActivity::class.java)
360
+ }
361
+ }
@@ -0,0 +1,199 @@
1
+ package com.customcamera
2
+
3
+ import android.graphics.Bitmap
4
+ import android.graphics.Canvas
5
+ import android.view.View
6
+ import android.widget.FrameLayout
7
+ import android.widget.ImageView
8
+ import com.facebook.react.uimanager.SimpleViewManager
9
+ import com.facebook.react.uimanager.ThemedReactContext
10
+ import com.facebook.react.uimanager.annotations.ReactProp
11
+ import kotlin.math.max
12
+
13
+ /**
14
+ * ViewManager for a native, dependency-free "frosted glass" backdrop used behind the
15
+ * expandable FAB menu.
16
+ *
17
+ * How it works (the "snapshot + downscale blur" strategy):
18
+ * 1. When [BlurBackgroundView.setActive] flips true, it takes a ONE-OFF snapshot of the
19
+ * Activity's content view (the media library sitting behind the menu) by drawing it into
20
+ * a heavily down-scaled [Bitmap]. Down-scaling is itself most of the blur and makes the
21
+ * subsequent work tiny.
22
+ * 2. A fast, pure-Kotlin separable box blur (no RenderScript, no RenderEffect, no library)
23
+ * softens the small bitmap. Because the bitmap is a fraction of screen size, this is cheap
24
+ * enough to stay smooth on low-end devices, and it works on every supported API level
25
+ * (min SDK 24) — unlike RenderEffect, which is API 31+.
26
+ * 3. The blurred bitmap is shown in a full-bleed [ImageView] and stretched back up. The
27
+ * surrounding React view fades it in/out, so the existing menu animation is preserved.
28
+ *
29
+ * Only the BACKGROUND is captured/blurred: the view hides ITSELF for the draw, and the menu
30
+ * items are still transparent at the instant the menu begins to open, so neither the blur
31
+ * layer nor the menu rows ever appear inside the blurred snapshot. The snapshot is static
32
+ * while the menu is open (the library underneath is not interactive then), so a single capture
33
+ * is both correct and efficient — no per-frame re-blurring.
34
+ */
35
+ class BlurBackgroundViewManager : SimpleViewManager<BlurBackgroundView>() {
36
+ override fun getName() = "CustomBlurBackground"
37
+
38
+ override fun createViewInstance(reactContext: ThemedReactContext): BlurBackgroundView =
39
+ BlurBackgroundView(reactContext)
40
+
41
+ @ReactProp(name = "active", defaultBoolean = false)
42
+ fun setActive(view: BlurBackgroundView, active: Boolean) {
43
+ view.setActive(active)
44
+ }
45
+
46
+ @ReactProp(name = "blurRadius", defaultInt = 4)
47
+ fun setBlurRadius(view: BlurBackgroundView, radius: Int) {
48
+ view.blurRadius = radius.coerceIn(1, 25)
49
+ }
50
+
51
+ @ReactProp(name = "downsampleFactor", defaultInt = 6)
52
+ fun setDownsampleFactor(view: BlurBackgroundView, factor: Int) {
53
+ view.downsampleFactor = factor.coerceIn(1, 16)
54
+ }
55
+ }
56
+
57
+ class BlurBackgroundView(private val reactContext: ThemedReactContext) : FrameLayout(reactContext) {
58
+ private val imageView = ImageView(reactContext).apply {
59
+ scaleType = ImageView.ScaleType.FIT_XY
60
+ }
61
+
62
+ /** Down-sample divisor for the snapshot — higher = softer + cheaper. */
63
+ var downsampleFactor = 6
64
+ /** Box-blur radius applied to the down-sampled snapshot. */
65
+ var blurRadius = 4
66
+
67
+ private var active = false
68
+
69
+ init {
70
+ addView(
71
+ imageView,
72
+ LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
73
+ )
74
+ }
75
+
76
+ fun setActive(next: Boolean) {
77
+ if (next == active) return
78
+ active = next
79
+ if (active) {
80
+ // Defer to the next frame so the view is measured/laid out and the background
81
+ // content behind it is fully drawn before we snapshot it.
82
+ post { if (active) captureAndBlur() }
83
+ } else {
84
+ imageView.setImageBitmap(null)
85
+ }
86
+ }
87
+
88
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
89
+ super.onSizeChanged(w, h, oldw, oldh)
90
+ // Keep the frosted backdrop correct after a rotation / resize while it is showing.
91
+ if (active && w > 0 && h > 0) post { if (active) captureAndBlur() }
92
+ }
93
+
94
+ private fun captureAndBlur() {
95
+ val source: View =
96
+ reactContext.currentActivity?.findViewById(android.R.id.content) ?: rootView ?: return
97
+ val srcW = source.width
98
+ val srcH = source.height
99
+ if (srcW <= 0 || srcH <= 0) return
100
+
101
+ val factor = max(1, downsampleFactor)
102
+ val bmpW = max(1, srcW / factor)
103
+ val bmpH = max(1, srcH / factor)
104
+
105
+ val bitmap =
106
+ try {
107
+ Bitmap.createBitmap(bmpW, bmpH, Bitmap.Config.ARGB_8888)
108
+ } catch (e: OutOfMemoryError) {
109
+ return
110
+ }
111
+ val canvas = Canvas(bitmap)
112
+ val scale = 1f / factor
113
+ canvas.scale(scale, scale)
114
+
115
+ // Exclude our own (currently transparent) blur layer from the snapshot so we never
116
+ // capture a previous frame of the blur, then restore visibility immediately after.
117
+ val prevVisibility = visibility
118
+ visibility = View.INVISIBLE
119
+ try {
120
+ source.draw(canvas)
121
+ } catch (e: Exception) {
122
+ visibility = prevVisibility
123
+ return
124
+ }
125
+ visibility = prevVisibility
126
+
127
+ boxBlur(bitmap, blurRadius)
128
+ imageView.setImageBitmap(bitmap)
129
+ }
130
+
131
+ /**
132
+ * In-place separable box blur (two axes, run twice for a smoother, Gaussian-like falloff).
133
+ * Operates on the raw ARGB pixel array of a small, down-sampled bitmap, so it is O(pixels)
134
+ * and stays fast on low-end hardware. Alpha is preserved; only RGB channels are averaged.
135
+ */
136
+ private fun boxBlur(bitmap: Bitmap, radius: Int) {
137
+ if (radius < 1) return
138
+ val w = bitmap.width
139
+ val h = bitmap.height
140
+ if (w <= 0 || h <= 0) return
141
+
142
+ val pixels = IntArray(w * h)
143
+ bitmap.getPixels(pixels, 0, w, 0, 0, w, h)
144
+
145
+ // Two iterations approximate a Gaussian blur well enough for a frosted backdrop.
146
+ repeat(2) {
147
+ blurAxis(pixels, w, h, radius, horizontal = true)
148
+ blurAxis(pixels, w, h, radius, horizontal = false)
149
+ }
150
+
151
+ bitmap.setPixels(pixels, 0, w, 0, 0, w, h)
152
+ }
153
+
154
+ private fun blurAxis(pixels: IntArray, w: Int, h: Int, radius: Int, horizontal: Boolean) {
155
+ val lineCount = if (horizontal) h else w
156
+ val lineLength = if (horizontal) w else h
157
+ if (lineLength <= 1) return
158
+ val window = radius * 2 + 1
159
+ val scratch = IntArray(lineLength)
160
+
161
+ for (line in 0 until lineCount) {
162
+ // Prime the sliding window over the first `radius+1` samples (clamped at the edge).
163
+ var sumR = 0
164
+ var sumG = 0
165
+ var sumB = 0
166
+ for (i in -radius..radius) {
167
+ val idx = indexOf(line, i.coerceIn(0, lineLength - 1), w, horizontal)
168
+ val c = pixels[idx]
169
+ sumR += (c ushr 16) and 0xFF
170
+ sumG += (c ushr 8) and 0xFF
171
+ sumB += c and 0xFF
172
+ }
173
+
174
+ for (pos in 0 until lineLength) {
175
+ scratch[pos] = (0xFF shl 24) or
176
+ ((sumR / window) shl 16) or
177
+ ((sumG / window) shl 8) or
178
+ (sumB / window)
179
+
180
+ // Slide the window forward: drop the trailing sample, add the leading one.
181
+ val trailing = (pos - radius).coerceIn(0, lineLength - 1)
182
+ val leading = (pos + radius + 1).coerceIn(0, lineLength - 1)
183
+ val cOut = pixels[indexOf(line, trailing, w, horizontal)]
184
+ val cIn = pixels[indexOf(line, leading, w, horizontal)]
185
+ sumR += ((cIn ushr 16) and 0xFF) - ((cOut ushr 16) and 0xFF)
186
+ sumG += ((cIn ushr 8) and 0xFF) - ((cOut ushr 8) and 0xFF)
187
+ sumB += (cIn and 0xFF) - (cOut and 0xFF)
188
+ }
189
+
190
+ // Write the blurred line back into the shared buffer.
191
+ for (pos in 0 until lineLength) {
192
+ pixels[indexOf(line, pos, w, horizontal)] = scratch[pos]
193
+ }
194
+ }
195
+ }
196
+
197
+ private fun indexOf(line: Int, pos: Int, w: Int, horizontal: Boolean): Int =
198
+ if (horizontal) line * w + pos else pos * w + line
199
+ }