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