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,73 @@
1
+ /**
2
+ * Encrypted media database — public API.
3
+ *
4
+ * A modular SQLCipher persistence layer for the camera plugin:
5
+ * - `DatabaseManager` centralized encrypted connection + primitives
6
+ * - `migrations` schema versioning (PRAGMA user_version)
7
+ * - `MediaRepository` typed CRUD/service layer
8
+ * - `MediaMapper` CameraAsset ⇆ MediaRecord translation
9
+ * - `useMediaDatabase` React hook bridging UI and the store
10
+ * - `secureKey` Keystore-backed encryption-key provisioning
11
+ *
12
+ * Consumers should generally use `useMediaDatabase` (UI) or `getMediaRepository`
13
+ * (imperative), and call `initializeMediaDatabase()` once at startup.
14
+ */
15
+
16
+ // Models & types
17
+ export type {
18
+ MediaRecord,
19
+ MediaRecordInput,
20
+ MediaType,
21
+ MediaSource,
22
+ MediaFilter,
23
+ MediaCounts,
24
+ MediaQueryOptions,
25
+ } from './types';
26
+ export { MEDIA_TABLE, MediaColumns } from './types';
27
+
28
+ // Centralized manager
29
+ export {
30
+ DatabaseManager,
31
+ getDatabaseManager,
32
+ initializeMediaDatabase,
33
+ type BatchStatement,
34
+ } from './DatabaseManager';
35
+
36
+ // Schema versioning & migrations
37
+ export {
38
+ MIGRATIONS,
39
+ LATEST_SCHEMA_VERSION,
40
+ runMigrations,
41
+ type Migration,
42
+ type MigrationExecutor,
43
+ } from './migrations';
44
+
45
+ // Repository / service layer
46
+ export { MediaRepository, getMediaRepository } from './MediaRepository';
47
+
48
+ // Mapping helpers
49
+ export {
50
+ assetToRecordInput,
51
+ recordToAsset,
52
+ rowToRecord,
53
+ assetTypeToMediaType,
54
+ mediaTypeToAssetType,
55
+ normalizeSource,
56
+ extensionForMimeType,
57
+ // Documents-path & source resolution (persistence contract)
58
+ resolveDocumentsPath,
59
+ isPublishedToDocuments,
60
+ detectSource,
61
+ } from './MediaMapper';
62
+
63
+ // Encryption key provisioning
64
+ export {
65
+ getDatabaseKey,
66
+ isHardwareBackedKeyAvailable,
67
+ } from './secureKey';
68
+
69
+ // React hook
70
+ export {
71
+ useMediaDatabase,
72
+ type UseMediaDatabaseResult,
73
+ } from './useMediaDatabase';
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Schema versioning & migrations for the encrypted media database.
3
+ *
4
+ * Versioning uses SQLite's built-in `PRAGMA user_version`. On every open,
5
+ * `runMigrations` reads the current version and applies — inside a single
6
+ * transaction — every migration whose target version is greater than it, in
7
+ * ascending order. Adding a new schema change is a matter of appending one more
8
+ * entry to `MIGRATIONS`; never edit or reorder existing entries.
9
+ */
10
+ import { MEDIA_TABLE, MediaColumns } from './types';
11
+
12
+ /** A single forward migration step. */
13
+ export interface Migration {
14
+ /** Target `user_version` this migration upgrades the database to. */
15
+ version: number;
16
+ /** Human-readable description (documentation only). */
17
+ description: string;
18
+ /** Ordered SQL statements executed to reach `version`. */
19
+ statements: string[];
20
+ }
21
+
22
+ /**
23
+ * Ordered list of migrations. `LATEST_SCHEMA_VERSION` is derived from the last
24
+ * entry, so bumping the schema only requires appending a new `Migration`.
25
+ */
26
+ export const MIGRATIONS: Migration[] = [
27
+ {
28
+ version: 1,
29
+ description: 'Initial media table with type/source indexes',
30
+ statements: [
31
+ `CREATE TABLE IF NOT EXISTS ${MEDIA_TABLE} (
32
+ ${MediaColumns.id} TEXT PRIMARY KEY NOT NULL,
33
+ ${MediaColumns.mediaType} TEXT NOT NULL CHECK (${MediaColumns.mediaType} IN ('image','video')),
34
+ ${MediaColumns.source} TEXT NOT NULL CHECK (${MediaColumns.source} IN ('camera','gallery')),
35
+ ${MediaColumns.filePath} TEXT NOT NULL,
36
+ ${MediaColumns.fileName} TEXT NOT NULL,
37
+ ${MediaColumns.fileSize} INTEGER,
38
+ ${MediaColumns.width} INTEGER,
39
+ ${MediaColumns.height} INTEGER,
40
+ ${MediaColumns.duration} INTEGER,
41
+ ${MediaColumns.mimeType} TEXT,
42
+ ${MediaColumns.createdAt} INTEGER NOT NULL,
43
+ ${MediaColumns.updatedAt} INTEGER NOT NULL
44
+ );`,
45
+ `CREATE INDEX IF NOT EXISTS idx_media_type
46
+ ON ${MEDIA_TABLE} (${MediaColumns.mediaType});`,
47
+ `CREATE INDEX IF NOT EXISTS idx_media_created_at
48
+ ON ${MEDIA_TABLE} (${MediaColumns.createdAt} DESC);`,
49
+ // Non-unique: speeds up delete-by-path without rejecting a re-selected
50
+ // file that arrives under a new id (dedup is keyed on the primary id).
51
+ `CREATE INDEX IF NOT EXISTS idx_media_file_path
52
+ ON ${MEDIA_TABLE} (${MediaColumns.filePath});`,
53
+ ],
54
+ },
55
+ {
56
+ version: 2,
57
+ description:
58
+ 'Composite (media_type, created_at DESC) index for the filtered+ordered list query',
59
+ statements: [
60
+ // The Photos/Videos filters run `WHERE media_type = ? ORDER BY created_at DESC`
61
+ // (see MediaRepository.getAll). The single-column idx_media_type filters but then
62
+ // forces a sort of the matching rows on every query; the single-column
63
+ // idx_media_created_at orders but can't also filter. A composite index lets SQLite
64
+ // satisfy BOTH the equality filter and the ordering from one index — no separate
65
+ // sort step — which keeps the filtered list fast as the library grows into the
66
+ // thousands. Purely additive (CREATE INDEX IF NOT EXISTS): no data change, and the
67
+ // unfiltered "All" query keeps using idx_media_created_at.
68
+ `CREATE INDEX IF NOT EXISTS idx_media_type_created_at
69
+ ON ${MEDIA_TABLE} (${MediaColumns.mediaType}, ${MediaColumns.createdAt} DESC);`,
70
+ ],
71
+ },
72
+ {
73
+ version: 3,
74
+ description:
75
+ 'Widen media_type to include document + audio, and reclassify legacy rows by MIME/extension',
76
+ // SQLite cannot ALTER a CHECK constraint in place, so the table is rebuilt.
77
+ // The copy step reclassifies rows the old two-kind schema was forced to store
78
+ // as `image`: a picked PDF/track kept its real MIME (e.g. application/pdf,
79
+ // audio/mpeg) even though media_type was clamped to 'image', so we recover the
80
+ // correct kind here from mime_type (then the file extension as a fallback).
81
+ statements: [
82
+ // 1. Park the current table out of the way (its indexes move with it).
83
+ `ALTER TABLE ${MEDIA_TABLE} RENAME TO ${MEDIA_TABLE}_legacy_v2;`,
84
+ // 2. Recreate the table with the widened media_type CHECK constraint.
85
+ `CREATE TABLE ${MEDIA_TABLE} (
86
+ ${MediaColumns.id} TEXT PRIMARY KEY NOT NULL,
87
+ ${MediaColumns.mediaType} TEXT NOT NULL CHECK (${MediaColumns.mediaType} IN ('image','video','document','audio')),
88
+ ${MediaColumns.source} TEXT NOT NULL CHECK (${MediaColumns.source} IN ('camera','gallery')),
89
+ ${MediaColumns.filePath} TEXT NOT NULL,
90
+ ${MediaColumns.fileName} TEXT NOT NULL,
91
+ ${MediaColumns.fileSize} INTEGER,
92
+ ${MediaColumns.width} INTEGER,
93
+ ${MediaColumns.height} INTEGER,
94
+ ${MediaColumns.duration} INTEGER,
95
+ ${MediaColumns.mimeType} TEXT,
96
+ ${MediaColumns.createdAt} INTEGER NOT NULL,
97
+ ${MediaColumns.updatedAt} INTEGER NOT NULL
98
+ );`,
99
+ // 3. Copy rows over, reclassifying media_type from mime_type / file extension.
100
+ `INSERT INTO ${MEDIA_TABLE} (
101
+ ${MediaColumns.id}, ${MediaColumns.mediaType}, ${MediaColumns.source},
102
+ ${MediaColumns.filePath}, ${MediaColumns.fileName}, ${MediaColumns.fileSize},
103
+ ${MediaColumns.width}, ${MediaColumns.height}, ${MediaColumns.duration},
104
+ ${MediaColumns.mimeType}, ${MediaColumns.createdAt}, ${MediaColumns.updatedAt}
105
+ )
106
+ SELECT
107
+ ${MediaColumns.id},
108
+ CASE
109
+ WHEN ${MediaColumns.mediaType} = 'video' THEN 'video'
110
+ WHEN ${MediaColumns.mimeType} LIKE 'video/%' THEN 'video'
111
+ WHEN ${MediaColumns.mimeType} LIKE 'audio/%' THEN 'audio'
112
+ WHEN ${MediaColumns.mimeType} LIKE 'image/%' THEN 'image'
113
+ WHEN ${MediaColumns.mimeType} = 'application/pdf'
114
+ OR ${MediaColumns.mimeType} LIKE 'application/vnd.%'
115
+ OR ${MediaColumns.mimeType} LIKE 'application/msword%'
116
+ OR ${MediaColumns.mimeType} LIKE 'application/rtf%'
117
+ OR ${MediaColumns.mimeType} = 'application/epub+zip'
118
+ OR ${MediaColumns.mimeType} LIKE 'text/%' THEN 'document'
119
+ WHEN lower(${MediaColumns.fileName}) LIKE '%.mp4'
120
+ OR lower(${MediaColumns.fileName}) LIKE '%.mov'
121
+ OR lower(${MediaColumns.fileName}) LIKE '%.mkv'
122
+ OR lower(${MediaColumns.fileName}) LIKE '%.webm'
123
+ OR lower(${MediaColumns.fileName}) LIKE '%.3gp'
124
+ OR lower(${MediaColumns.fileName}) LIKE '%.m4v' THEN 'video'
125
+ WHEN lower(${MediaColumns.fileName}) LIKE '%.mp3'
126
+ OR lower(${MediaColumns.fileName}) LIKE '%.wav'
127
+ OR lower(${MediaColumns.fileName}) LIKE '%.aac'
128
+ OR lower(${MediaColumns.fileName}) LIKE '%.m4a'
129
+ OR lower(${MediaColumns.fileName}) LIKE '%.ogg'
130
+ OR lower(${MediaColumns.fileName}) LIKE '%.flac'
131
+ OR lower(${MediaColumns.fileName}) LIKE '%.opus'
132
+ OR lower(${MediaColumns.fileName}) LIKE '%.amr' THEN 'audio'
133
+ WHEN lower(${MediaColumns.fileName}) LIKE '%.pdf'
134
+ OR lower(${MediaColumns.fileName}) LIKE '%.doc'
135
+ OR lower(${MediaColumns.fileName}) LIKE '%.docx'
136
+ OR lower(${MediaColumns.fileName}) LIKE '%.xls'
137
+ OR lower(${MediaColumns.fileName}) LIKE '%.xlsx'
138
+ OR lower(${MediaColumns.fileName}) LIKE '%.ppt'
139
+ OR lower(${MediaColumns.fileName}) LIKE '%.pptx'
140
+ OR lower(${MediaColumns.fileName}) LIKE '%.txt'
141
+ OR lower(${MediaColumns.fileName}) LIKE '%.csv'
142
+ OR lower(${MediaColumns.fileName}) LIKE '%.rtf'
143
+ OR lower(${MediaColumns.fileName}) LIKE '%.odt'
144
+ OR lower(${MediaColumns.fileName}) LIKE '%.ods'
145
+ OR lower(${MediaColumns.fileName}) LIKE '%.odp'
146
+ OR lower(${MediaColumns.fileName}) LIKE '%.epub' THEN 'document'
147
+ ELSE 'image'
148
+ END,
149
+ ${MediaColumns.source}, ${MediaColumns.filePath}, ${MediaColumns.fileName},
150
+ ${MediaColumns.fileSize}, ${MediaColumns.width}, ${MediaColumns.height},
151
+ ${MediaColumns.duration}, ${MediaColumns.mimeType}, ${MediaColumns.createdAt},
152
+ ${MediaColumns.updatedAt}
153
+ FROM ${MEDIA_TABLE}_legacy_v2;`,
154
+ // 4. Drop the legacy table (this also drops its now-orphaned indexes,
155
+ // freeing the index names for recreation below).
156
+ `DROP TABLE ${MEDIA_TABLE}_legacy_v2;`,
157
+ // 5. Recreate every index on the rebuilt table.
158
+ `CREATE INDEX IF NOT EXISTS idx_media_type
159
+ ON ${MEDIA_TABLE} (${MediaColumns.mediaType});`,
160
+ `CREATE INDEX IF NOT EXISTS idx_media_created_at
161
+ ON ${MEDIA_TABLE} (${MediaColumns.createdAt} DESC);`,
162
+ `CREATE INDEX IF NOT EXISTS idx_media_file_path
163
+ ON ${MEDIA_TABLE} (${MediaColumns.filePath});`,
164
+ `CREATE INDEX IF NOT EXISTS idx_media_type_created_at
165
+ ON ${MEDIA_TABLE} (${MediaColumns.mediaType}, ${MediaColumns.createdAt} DESC);`,
166
+ ],
167
+ },
168
+ {
169
+ version: 4,
170
+ description:
171
+ 'Add size_is_display_estimate flag: true when file_size is a compressed video’s proportional display figure, not the exact bytes on disk',
172
+ // Purely additive. Existing rows get NULL (read back as false), so nothing
173
+ // that was stored before this column re-stats differently. Only compressed
174
+ // videos published from the editor set it to 1 (see CameraAsset.sizeIsDisplayEstimate).
175
+ statements: [
176
+ `ALTER TABLE ${MEDIA_TABLE} ADD COLUMN ${MediaColumns.sizeIsDisplayEstimate} INTEGER;`,
177
+ ],
178
+ },
179
+ ];
180
+
181
+ /** The schema version the app expects after all migrations are applied. */
182
+ export const LATEST_SCHEMA_VERSION =
183
+ MIGRATIONS.length > 0 ? MIGRATIONS[MIGRATIONS.length - 1]!.version : 0;
184
+
185
+ /** Minimal executor contract so migrations don't depend on the concrete manager. */
186
+ export interface MigrationExecutor {
187
+ /** Reads the current `PRAGMA user_version`. */
188
+ getVersion(): Promise<number>;
189
+ /** Runs the given statements atomically in a single transaction. */
190
+ runBatch(statements: string[]): Promise<void>;
191
+ }
192
+
193
+ /**
194
+ * Applies all pending migrations. Safe to call on every launch — a fully
195
+ * up-to-date database performs only a cheap version read and returns.
196
+ *
197
+ * @returns the schema version after migration.
198
+ */
199
+ export async function runMigrations(
200
+ executor: MigrationExecutor
201
+ ): Promise<number> {
202
+ const currentVersion = await executor.getVersion();
203
+
204
+ if (currentVersion >= LATEST_SCHEMA_VERSION) {
205
+ return currentVersion;
206
+ }
207
+
208
+ const pending = MIGRATIONS.filter((m) => m.version > currentVersion).sort(
209
+ (a, b) => a.version - b.version
210
+ );
211
+
212
+ for (const migration of pending) {
213
+ // Each migration is atomic: the DDL statements and the version bump land in
214
+ // one transaction, or the whole step rolls back and the next launch retries.
215
+ await executor.runBatch([
216
+ ...migration.statements,
217
+ `PRAGMA user_version = ${Math.floor(migration.version)};`,
218
+ ]);
219
+ }
220
+
221
+ return LATEST_SCHEMA_VERSION;
222
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Ambient type declaration for `react-native-sqlcipher`.
3
+ *
4
+ * `react-native-sqlcipher` is a SQLCipher-backed fork of
5
+ * `react-native-sqlite-storage` and ships without TypeScript types. This
6
+ * declaration types only the subset of the WebSQL-style API that the database
7
+ * layer in `src/db` actually consumes, so the project typechecks whether or not
8
+ * the native package has been installed yet.
9
+ *
10
+ * The runtime API is loaded lazily (see `DatabaseManager`), so a missing package
11
+ * is a graceful runtime fallback rather than a build error.
12
+ */
13
+ declare module 'react-native-sqlcipher' {
14
+ export interface ResultSetRowList {
15
+ length: number;
16
+ item(index: number): any;
17
+ raw(): any[];
18
+ }
19
+
20
+ export interface ResultSet {
21
+ insertId?: number;
22
+ rowsAffected: number;
23
+ rows: ResultSetRowList;
24
+ }
25
+
26
+ export interface Transaction {
27
+ executeSql(
28
+ sqlStatement: string,
29
+ args?: any[]
30
+ ): Promise<[Transaction, ResultSet]>;
31
+ }
32
+
33
+ export interface SQLiteDatabase {
34
+ transaction(scope: (tx: Transaction) => void): Promise<Transaction>;
35
+ readTransaction(scope: (tx: Transaction) => void): Promise<Transaction>;
36
+ executeSql(
37
+ sqlStatement: string,
38
+ args?: any[]
39
+ ): Promise<[ResultSet]>;
40
+ close(): Promise<void>;
41
+ attach?(...args: any[]): Promise<any>;
42
+ dbName?: string;
43
+ }
44
+
45
+ export interface OpenDatabaseParams {
46
+ /** Database file name, e.g. `media_secure.db`. */
47
+ name: string;
48
+ /** SQLCipher passphrase used to encrypt/decrypt the database. */
49
+ key?: string;
50
+ /** Storage location. `default` = app's internal Documents/Databases dir. */
51
+ location?: 'default' | 'Library' | 'Documents';
52
+ createFromLocation?: number | string;
53
+ }
54
+
55
+ export interface SQLiteStatic {
56
+ /** Enable promise-based API (must be called before openDatabase). */
57
+ enablePromise(enabled: boolean): void;
58
+ /** Enable/disable verbose native logging. */
59
+ DEBUG(enabled: boolean): void;
60
+ openDatabase(
61
+ params: OpenDatabaseParams
62
+ ): Promise<SQLiteDatabase>;
63
+ openDatabase(
64
+ params: OpenDatabaseParams,
65
+ success?: (db: SQLiteDatabase) => void,
66
+ error?: (err: any) => void
67
+ ): SQLiteDatabase;
68
+ deleteDatabase(params: {
69
+ name: string;
70
+ location?: string;
71
+ }): Promise<void>;
72
+ }
73
+
74
+ const SQLite: SQLiteStatic;
75
+ export default SQLite;
76
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Encryption-key provisioning for the SQLCipher database.
3
+ *
4
+ * Strategy (most secure first):
5
+ * 1. Native `SecureKeyModule` (Android) — generates a cryptographically random
6
+ * 256-bit key on first launch and persists it in `EncryptedSharedPreferences`,
7
+ * which is sealed by a master key held in the Android Keystore. The raw key
8
+ * material therefore never lives in the JS bundle or in plaintext on disk.
9
+ * 2. Fallback — a locally derived key used only when the native module is
10
+ * unavailable (web, iOS without the native helper, or an older build). This
11
+ * keeps the app functional but is NOT hardware-backed; see the warning below.
12
+ *
13
+ * The resolved key is cached in-memory for the process lifetime so the native
14
+ * bridge is hit at most once.
15
+ */
16
+ import { NativeModules, Platform } from 'react-native';
17
+
18
+ /** Shape of the optional native key module. */
19
+ interface SecureKeyNativeModule {
20
+ getOrCreateDatabaseKey(): Promise<string>;
21
+ }
22
+
23
+ const nativeKeyModule: SecureKeyNativeModule | undefined = (
24
+ NativeModules as Record<string, SecureKeyNativeModule | undefined>
25
+ ).SecureKeyModule;
26
+
27
+ let cachedKey: string | null = null;
28
+
29
+ /**
30
+ * Deterministic fallback key. Used ONLY when no native Keystore-backed module is
31
+ * present. It is intentionally derived (not a bare literal) but, because it is
32
+ * reconstructable from the bundle, it does not provide hardware-backed secrecy.
33
+ * On Android the native module supersedes this path.
34
+ */
35
+ function deriveFallbackKey(): string {
36
+ // A stable, app-scoped seed combined into a 64-hex-char (256-bit) string.
37
+ const seed = `rncc.media.${Platform.OS}.v1.9f3ac21e-secure-media-store`;
38
+ let h1 = 0x811c9dc5;
39
+ let h2 = 0xc2b2ae35;
40
+ for (let i = 0; i < seed.length; i++) {
41
+ const c = seed.charCodeAt(i);
42
+ h1 = Math.imul(h1 ^ c, 0x01000193) >>> 0;
43
+ h2 = Math.imul(h2 ^ c, 0x85ebca77) >>> 0;
44
+ }
45
+ // Expand the two 32-bit hashes into 64 hex chars deterministically.
46
+ let out = '';
47
+ let a = h1 >>> 0;
48
+ let b = h2 >>> 0;
49
+ for (let i = 0; i < 8; i++) {
50
+ a = (Math.imul(a, 0x9e3779b1) + 0x7f4a7c15) >>> 0;
51
+ b = (Math.imul(b, 0x85ebca6b) + 0xc2b2ae35) >>> 0;
52
+ out += a.toString(16).padStart(8, '0');
53
+ out += b.toString(16).padStart(8, '0');
54
+ }
55
+ return out.slice(0, 64);
56
+ }
57
+
58
+ /**
59
+ * Resolve the SQLCipher passphrase, preferring the hardware-backed native key.
60
+ * The result is memoized for the lifetime of the JS runtime.
61
+ */
62
+ export async function getDatabaseKey(): Promise<string> {
63
+ if (cachedKey) return cachedKey;
64
+
65
+ if (nativeKeyModule?.getOrCreateDatabaseKey) {
66
+ try {
67
+ const key = await nativeKeyModule.getOrCreateDatabaseKey();
68
+ if (key && key.length >= 16) {
69
+ cachedKey = key;
70
+ return cachedKey;
71
+ }
72
+ console.warn(
73
+ '[SecureKey] Native module returned an unusable key; using fallback.'
74
+ );
75
+ } catch (error) {
76
+ console.warn(
77
+ '[SecureKey] Native key retrieval failed; using fallback.',
78
+ error
79
+ );
80
+ }
81
+ } else if (Platform.OS === 'android') {
82
+ console.warn(
83
+ '[SecureKey] SecureKeyModule not linked. Rebuild the Android app to enable ' +
84
+ 'Keystore-backed encryption; using derived fallback key for now.'
85
+ );
86
+ }
87
+
88
+ cachedKey = deriveFallbackKey();
89
+ return cachedKey;
90
+ }
91
+
92
+ /** True when the hardware-backed native key module is available. */
93
+ export function isHardwareBackedKeyAvailable(): boolean {
94
+ return Boolean(nativeKeyModule?.getOrCreateDatabaseKey);
95
+ }
96
+
97
+ /** Test/hot-reload helper: clears the in-memory key cache. */
98
+ export function __resetDatabaseKeyCache(): void {
99
+ cachedKey = null;
100
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Strongly-typed media models for the encrypted SQLCipher database.
3
+ *
4
+ * These types describe the *persistence* shape of a media item — the exact
5
+ * columns stored in the `media` table — independently of the UI-facing
6
+ * `CameraAsset` type. Mapping between the two lives in `MediaMapper.ts`, keeping
7
+ * a clean separation between the database schema and the rest of the app.
8
+ */
9
+
10
+ /**
11
+ * Persisted media kind. Photos are normalized to `image`; documents and audio
12
+ * are first-class kinds so a picked PDF/track is never mis-stored as an image.
13
+ */
14
+ export type MediaType = 'image' | 'video' | 'document' | 'audio';
15
+
16
+ /** Where a media item originated. */
17
+ export type MediaSource = 'camera' | 'gallery';
18
+
19
+ /**
20
+ * A single row of the `media` table — the canonical, strongly-typed record.
21
+ *
22
+ * `null` is used (never `undefined`) for absent optional columns so the shape
23
+ * maps 1:1 onto SQL rows.
24
+ */
25
+ export interface MediaRecord {
26
+ /** Unique identifier (primary key). */
27
+ id: string;
28
+ /** `image` or `video`. */
29
+ mediaType: MediaType;
30
+ /** `camera` or `gallery`. */
31
+ source: MediaSource;
32
+ /** Absolute file path or content URI. */
33
+ filePath: string;
34
+ /** Display file name, e.g. `photo_1699999999999.jpg`. */
35
+ fileName: string;
36
+ /** File size in bytes, or null if unknown. */
37
+ fileSize: number | null;
38
+ /** Pixel width, or null if unknown. */
39
+ width: number | null;
40
+ /** Pixel height, or null if unknown. */
41
+ height: number | null;
42
+ /** Duration in milliseconds (videos only), or null. */
43
+ duration: number | null;
44
+ /** MIME type such as `image/jpeg` or `video/mp4`, or null. */
45
+ mimeType: string | null;
46
+ /** Creation timestamp (epoch ms). */
47
+ createdAt: number;
48
+ /** Last-updated timestamp (epoch ms). */
49
+ updatedAt: number;
50
+ /**
51
+ * True when {@link fileSize} is a DISPLAY convention (a compressed video's
52
+ * proportional figure) rather than the exact bytes on disk. Read back onto
53
+ * `CameraAsset.sizeIsDisplayEstimate` so the preview / Info panel keeps the
54
+ * quoted size instead of re-statting the file. Absent (legacy) rows read false.
55
+ */
56
+ sizeIsDisplayEstimate: boolean;
57
+ }
58
+
59
+ /**
60
+ * Fields required to insert a new media record. Timestamps are optional on
61
+ * input — the repository fills `createdAt`/`updatedAt` when omitted.
62
+ */
63
+ export interface MediaRecordInput {
64
+ id: string;
65
+ mediaType: MediaType;
66
+ source: MediaSource;
67
+ filePath: string;
68
+ fileName: string;
69
+ fileSize?: number | null;
70
+ width?: number | null;
71
+ height?: number | null;
72
+ duration?: number | null;
73
+ mimeType?: string | null;
74
+ createdAt?: number;
75
+ updatedAt?: number;
76
+ /** See {@link MediaRecord.sizeIsDisplayEstimate}. Stored as INTEGER 1/0. */
77
+ sizeIsDisplayEstimate?: boolean | null;
78
+ }
79
+
80
+ /** Filter used when querying the media list. */
81
+ export type MediaFilter = 'all' | 'image' | 'video' | 'document' | 'audio';
82
+
83
+ /**
84
+ * Aggregate counts computed directly from the database via `COUNT(*)`.
85
+ * Backs the filter-card counters (All / Photos / Videos / Documents / Audio).
86
+ */
87
+ export interface MediaCounts {
88
+ all: number;
89
+ image: number;
90
+ video: number;
91
+ document: number;
92
+ audio: number;
93
+ }
94
+
95
+ /** Options for ordered/paged queries against the media table. */
96
+ export interface MediaQueryOptions {
97
+ filter?: MediaFilter;
98
+ /** Column to order by. Defaults to `createdAt`. */
99
+ orderBy?: 'createdAt' | 'updatedAt' | 'fileName';
100
+ /** Sort direction. Defaults to `DESC` (newest first). */
101
+ direction?: 'ASC' | 'DESC';
102
+ limit?: number;
103
+ offset?: number;
104
+ }
105
+
106
+ /** Table + column name constants — single source of truth for SQL strings. */
107
+ export const MEDIA_TABLE = 'media';
108
+
109
+ export const MediaColumns = {
110
+ id: 'id',
111
+ mediaType: 'media_type',
112
+ source: 'source',
113
+ filePath: 'file_path',
114
+ fileName: 'file_name',
115
+ fileSize: 'file_size',
116
+ width: 'width',
117
+ height: 'height',
118
+ duration: 'duration',
119
+ mimeType: 'mime_type',
120
+ createdAt: 'created_at',
121
+ updatedAt: 'updated_at',
122
+ sizeIsDisplayEstimate: 'size_is_display_estimate',
123
+ } as const;