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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
package com.customcamera
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.graphics.Color
|
|
6
|
+
import android.graphics.Paint
|
|
7
|
+
import android.graphics.Path
|
|
8
|
+
import android.view.MotionEvent
|
|
9
|
+
import android.view.View
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A fully native freehand drawing surface built ONLY on the platform Canvas /
|
|
13
|
+
* Path / Paint APIs already available in the Android SDK — no third-party
|
|
14
|
+
* drawing library or plugin is involved.
|
|
15
|
+
*
|
|
16
|
+
* Design goals:
|
|
17
|
+
* • Smooth, low-latency strokes: each in-progress stroke is drawn with a
|
|
18
|
+
* quadratic Bézier smoothing between successive touch points so the line
|
|
19
|
+
* follows the finger without visible segmentation.
|
|
20
|
+
* • Transform-agnostic: this view is added as a CHILD of the PhotoEditorView
|
|
21
|
+
* (a RelativeLayout) and sized to MATCH_PARENT, so it inherits the exact same
|
|
22
|
+
* position, scale (CENTER_CROP / FIT_CENTER), crop, rotation and any parent
|
|
23
|
+
* transform as the photo underneath. Strokes are stored in this view's own
|
|
24
|
+
* coordinate space, so they stay locked to the image through zoom / pan /
|
|
25
|
+
* crop / rotate — the parent renders both together.
|
|
26
|
+
* • Export-ready: because the strokes live in the view hierarchy, the editor's
|
|
27
|
+
* existing "render the whole PhotoEditorView to a Canvas" export path merges
|
|
28
|
+
* every stroke into the exported / uploaded / sent bitmap automatically.
|
|
29
|
+
*
|
|
30
|
+
* Undo / redo / clear operate on completed strokes. While [drawingEnabled] is
|
|
31
|
+
* false the view ignores touches (letting the underlying editor gestures work);
|
|
32
|
+
* previously drawn strokes are always rendered.
|
|
33
|
+
*/
|
|
34
|
+
class DrawingView(context: Context) : View(context) {
|
|
35
|
+
|
|
36
|
+
/** One completed freehand stroke: its path plus the paint that rendered it. */
|
|
37
|
+
internal class Stroke(val path: Path, val paint: Paint)
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Opaque, immutable capture of the committed + undone stroke stacks. Used to
|
|
41
|
+
* revert an entire drawing session in one shot (e.g. the brush-tool Cross)
|
|
42
|
+
* back to exactly the state that existed when the session started, without
|
|
43
|
+
* touching anything else in the editor. Committed strokes are immutable once
|
|
44
|
+
* finished, so holding shallow copies of the two lists is sufficient.
|
|
45
|
+
*/
|
|
46
|
+
class Snapshot internal constructor(
|
|
47
|
+
internal val strokes: List<Stroke>,
|
|
48
|
+
internal val undoneStrokes: List<Stroke>
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
private val strokes = ArrayList<Stroke>()
|
|
52
|
+
private val undoneStrokes = ArrayList<Stroke>()
|
|
53
|
+
|
|
54
|
+
// The stroke currently being drawn (between ACTION_DOWN and ACTION_UP).
|
|
55
|
+
private var activePath: Path? = null
|
|
56
|
+
private var activePaint: Paint? = null
|
|
57
|
+
private var lastX = 0f
|
|
58
|
+
private var lastY = 0f
|
|
59
|
+
private var hasMoved = false
|
|
60
|
+
|
|
61
|
+
/** Touch slop below which a move is treated as noise (keeps dots crisp). */
|
|
62
|
+
private val touchTolerance = 2f
|
|
63
|
+
|
|
64
|
+
var brushColor: Int = Color.RED
|
|
65
|
+
/** Stroke width in pixels. */
|
|
66
|
+
var brushSize: Float = 12f
|
|
67
|
+
|
|
68
|
+
/** When false, the view is display-only and passes touches through. */
|
|
69
|
+
var drawingEnabled: Boolean = false
|
|
70
|
+
|
|
71
|
+
/** Invoked whenever the set of committed strokes changes (draw/undo/redo/clear). */
|
|
72
|
+
var onStrokesChanged: (() -> Unit)? = null
|
|
73
|
+
|
|
74
|
+
init {
|
|
75
|
+
// Transparent so the photo (and any filter / stickers / text) shows through.
|
|
76
|
+
setBackgroundColor(Color.TRANSPARENT)
|
|
77
|
+
// Software layer keeps anti-aliased Path rendering identical between the live
|
|
78
|
+
// preview and the offscreen export canvas used by the editor.
|
|
79
|
+
setLayerType(LAYER_TYPE_SOFTWARE, null)
|
|
80
|
+
isClickable = true
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private fun newPaint(): Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
84
|
+
color = brushColor
|
|
85
|
+
style = Paint.Style.STROKE
|
|
86
|
+
strokeJoin = Paint.Join.ROUND
|
|
87
|
+
strokeCap = Paint.Cap.ROUND
|
|
88
|
+
strokeWidth = brushSize
|
|
89
|
+
isDither = true
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fun hasStrokes(): Boolean = strokes.isNotEmpty()
|
|
93
|
+
|
|
94
|
+
fun canUndo(): Boolean = strokes.isNotEmpty()
|
|
95
|
+
|
|
96
|
+
fun canRedo(): Boolean = undoneStrokes.isNotEmpty()
|
|
97
|
+
|
|
98
|
+
fun undo() {
|
|
99
|
+
if (strokes.isEmpty()) return
|
|
100
|
+
undoneStrokes.add(strokes.removeAt(strokes.size - 1))
|
|
101
|
+
invalidate()
|
|
102
|
+
onStrokesChanged?.invoke()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
fun redo() {
|
|
106
|
+
if (undoneStrokes.isEmpty()) return
|
|
107
|
+
strokes.add(undoneStrokes.removeAt(undoneStrokes.size - 1))
|
|
108
|
+
invalidate()
|
|
109
|
+
onStrokesChanged?.invoke()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fun clear() {
|
|
113
|
+
if (strokes.isEmpty() && undoneStrokes.isEmpty() && activePath == null) return
|
|
114
|
+
strokes.clear()
|
|
115
|
+
undoneStrokes.clear()
|
|
116
|
+
activePath = null
|
|
117
|
+
activePaint = null
|
|
118
|
+
invalidate()
|
|
119
|
+
onStrokesChanged?.invoke()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Captures the current committed + undone stroke stacks so they can later be
|
|
124
|
+
* put back verbatim with [restore]. Take this when a drawing session begins to
|
|
125
|
+
* support a cancel action that reverts only that session's strokes.
|
|
126
|
+
*/
|
|
127
|
+
fun snapshot(): Snapshot = Snapshot(ArrayList(strokes), ArrayList(undoneStrokes))
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Restores a previously captured [snapshot], replacing the current strokes with
|
|
131
|
+
* exactly those it holds and dropping any in-progress stroke. Fires
|
|
132
|
+
* [onStrokesChanged] so dependent state (edit flags, thumbnails, undo/redo
|
|
133
|
+
* button enablement) refreshes to match.
|
|
134
|
+
*/
|
|
135
|
+
fun restore(snapshot: Snapshot) {
|
|
136
|
+
strokes.clear()
|
|
137
|
+
strokes.addAll(snapshot.strokes)
|
|
138
|
+
undoneStrokes.clear()
|
|
139
|
+
undoneStrokes.addAll(snapshot.undoneStrokes)
|
|
140
|
+
activePath = null
|
|
141
|
+
activePaint = null
|
|
142
|
+
invalidate()
|
|
143
|
+
onStrokesChanged?.invoke()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
override fun onDraw(canvas: Canvas) {
|
|
147
|
+
super.onDraw(canvas)
|
|
148
|
+
for (stroke in strokes) {
|
|
149
|
+
canvas.drawPath(stroke.path, stroke.paint)
|
|
150
|
+
}
|
|
151
|
+
val ap = activePath
|
|
152
|
+
val apaint = activePaint
|
|
153
|
+
if (ap != null && apaint != null) {
|
|
154
|
+
canvas.drawPath(ap, apaint)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
override fun onTouchEvent(event: MotionEvent): Boolean {
|
|
159
|
+
if (!drawingEnabled) return false
|
|
160
|
+
|
|
161
|
+
val x = event.x
|
|
162
|
+
val y = event.y
|
|
163
|
+
|
|
164
|
+
when (event.actionMasked) {
|
|
165
|
+
MotionEvent.ACTION_DOWN -> {
|
|
166
|
+
// Starting a new stroke invalidates the redo history, matching the
|
|
167
|
+
// conventional undo/redo contract.
|
|
168
|
+
undoneStrokes.clear()
|
|
169
|
+
val path = Path().apply { moveTo(x, y) }
|
|
170
|
+
activePath = path
|
|
171
|
+
activePaint = newPaint()
|
|
172
|
+
lastX = x
|
|
173
|
+
lastY = y
|
|
174
|
+
hasMoved = false
|
|
175
|
+
invalidate()
|
|
176
|
+
return true
|
|
177
|
+
}
|
|
178
|
+
MotionEvent.ACTION_MOVE -> {
|
|
179
|
+
val path = activePath ?: return true
|
|
180
|
+
val dx = Math.abs(x - lastX)
|
|
181
|
+
val dy = Math.abs(y - lastY)
|
|
182
|
+
if (dx >= touchTolerance || dy >= touchTolerance) {
|
|
183
|
+
// Quadratic smoothing: control point at the previous sample, endpoint
|
|
184
|
+
// at the midpoint, so the curve stays continuous and low-latency.
|
|
185
|
+
path.quadTo(lastX, lastY, (x + lastX) / 2f, (y + lastY) / 2f)
|
|
186
|
+
lastX = x
|
|
187
|
+
lastY = y
|
|
188
|
+
hasMoved = true
|
|
189
|
+
invalidate()
|
|
190
|
+
}
|
|
191
|
+
return true
|
|
192
|
+
}
|
|
193
|
+
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
|
194
|
+
val path = activePath
|
|
195
|
+
val paint = activePaint
|
|
196
|
+
if (path != null && paint != null) {
|
|
197
|
+
if (!hasMoved) {
|
|
198
|
+
// A tap with no movement: draw a dot so single taps still mark.
|
|
199
|
+
path.lineTo(x, y)
|
|
200
|
+
} else {
|
|
201
|
+
path.lineTo(lastX, lastY)
|
|
202
|
+
}
|
|
203
|
+
strokes.add(Stroke(path, paint))
|
|
204
|
+
onStrokesChanged?.invoke()
|
|
205
|
+
}
|
|
206
|
+
activePath = null
|
|
207
|
+
activePaint = null
|
|
208
|
+
invalidate()
|
|
209
|
+
return true
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return false
|
|
213
|
+
}
|
|
214
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
package com.customcamera
|
|
2
|
+
|
|
3
|
+
import android.graphics.Paint
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Full categorized emoji set for the preview editor's emoji picker.
|
|
7
|
+
*
|
|
8
|
+
* Categories follow the standard Unicode/CLDR grouping used by modern keyboards and
|
|
9
|
+
* messaging apps (Smileys, People, Animals & Nature, Food & Drink, Activities,
|
|
10
|
+
* Travel & Places, Objects, Symbols, Flags).
|
|
11
|
+
*
|
|
12
|
+
* Device compatibility: the raw lists include emoji up to recent Unicode versions, but
|
|
13
|
+
* the system emoji font on older devices (minSdk 24 / Android 7) lacks many of them and
|
|
14
|
+
* would render tofu boxes. [supportedCategories] therefore filters every glyph through
|
|
15
|
+
* [Paint.hasGlyph] (API 23+) once per process and caches the result, so each device shows
|
|
16
|
+
* exactly the set it can actually render — no tofu, no per-open recompute cost.
|
|
17
|
+
*/
|
|
18
|
+
internal object EmojiPickerData {
|
|
19
|
+
|
|
20
|
+
data class Category(val icon: String, val label: String, val emojis: List<String>)
|
|
21
|
+
|
|
22
|
+
val categories: List<Category> = listOf(
|
|
23
|
+
Category(
|
|
24
|
+
icon = "😀", // 😀
|
|
25
|
+
label = "Smileys",
|
|
26
|
+
emojis = listOf(
|
|
27
|
+
"😀", "😃", "😄", "😁", "😆", "😅", "🤣", "😂", "🙂", "🙃",
|
|
28
|
+
"😉", "😊", "😇", "🥰", "😍", "🤩", "😘", "😗", "😚", "😙",
|
|
29
|
+
"😋", "😛", "😜", "🤪", "😝", "🤑", "🤗", "🤭", "🤫", "🤔",
|
|
30
|
+
"🤐", "🤨", "😐", "😑", "😶", "😏", "😒", "🙄", "😬", "🤥",
|
|
31
|
+
"😌", "😔", "😪", "🤤", "😴", "😷", "🤒", "🤕", "🤢", "🤮",
|
|
32
|
+
"🤧", "🥵", "🥶", "🥴", "😵", "🤯", "🤠", "🥳", "😎", "🤓",
|
|
33
|
+
"🧐", "😕", "😟", "🙁", "☹️", "😮", "😯", "😲", "😳", "🥺",
|
|
34
|
+
"😦", "😧", "😨", "😰", "😥", "😢", "😭", "😱", "😖", "😣",
|
|
35
|
+
"😞", "😓", "😩", "😫", "🥱", "😤", "😡", "😠", "🤬", "😈",
|
|
36
|
+
"👿", "💀", "☠️", "💩", "🤡", "👹", "👺", "👻", "👽", "👾",
|
|
37
|
+
"🤖", "😺", "😸", "😹", "😻", "😼", "😽", "🙀", "😿", "😾",
|
|
38
|
+
"💋", "💌", "💘", "💝", "💖", "💗", "💓", "💞", "💕", "💟",
|
|
39
|
+
"❣️", "💔", "❤️", "🧡", "💛", "💚", "💙", "💜", "🤎", "🖤",
|
|
40
|
+
"🤍", "💯", "💢", "💥", "💫", "💦", "💨", "💣", "💬", "💭", "💤"
|
|
41
|
+
)
|
|
42
|
+
),
|
|
43
|
+
Category(
|
|
44
|
+
icon = "👋", // 👋
|
|
45
|
+
label = "People",
|
|
46
|
+
emojis = listOf(
|
|
47
|
+
"👋", "🤚", "🖐️", "✋", "🖖", "👌", "🤏", "✌️", "🤞", "🤟",
|
|
48
|
+
"🤘", "🤙", "👈", "👉", "👆", "👇", "☝️", "👍", "👎", "✊",
|
|
49
|
+
"👊", "🤛", "🤜", "👏", "🙌", "👐", "🤲", "🤝", "🙏", "✍️",
|
|
50
|
+
"💅", "🤳", "💪", "🦾", "🦵", "🦶", "👂", "👃", "🧠", "🦷",
|
|
51
|
+
"🦴", "👀", "👁️", "👅", "👄", "👶", "🧒", "👦", "👧", "🧑",
|
|
52
|
+
"👱", "👨", "🧔", "👩", "🧓", "👴", "👵", "🙍", "🙎", "🙅",
|
|
53
|
+
"🙆", "💁", "🙋", "🧏", "🙇", "🤦", "🤷", "👮", "🕵️", "💂",
|
|
54
|
+
"👷", "🤴", "👸", "👳", "👲", "🧕", "🤵", "👰", "🤰", "🤱",
|
|
55
|
+
"👼", "🎅", "🤶", "🦸", "🦹", "🧙", "🧚", "🧛", "🧜", "🧝",
|
|
56
|
+
"🧞", "🧟", "💆", "💇", "🚶", "🧍", "🧎", "🏃", "💃", "🕺",
|
|
57
|
+
"👯", "🧖", "🧗", "👫", "👬", "👭", "💏", "💑", "👪"
|
|
58
|
+
)
|
|
59
|
+
),
|
|
60
|
+
Category(
|
|
61
|
+
icon = "🐻", // 🐻
|
|
62
|
+
label = "Animals & Nature",
|
|
63
|
+
emojis = listOf(
|
|
64
|
+
"🐵", "🐒", "🦍", "🦧", "🐶", "🐕", "🦮", "🐩", "🐺", "🦊",
|
|
65
|
+
"🦝", "🐱", "🐈", "🦁", "🐯", "🐅", "🐆", "🐴", "🐎", "🦄",
|
|
66
|
+
"🦓", "🦌", "🐮", "🐂", "🐃", "🐄", "🐷", "🐖", "🐗", "🐽",
|
|
67
|
+
"🐏", "🐑", "🐐", "🐪", "🐫", "🦙", "🦒", "🐘", "🦏", "🦛",
|
|
68
|
+
"🐭", "🐁", "🐀", "🐹", "🐰", "🐇", "🐿️", "🦔", "🦇", "🐻",
|
|
69
|
+
"🐨", "🐼", "🦥", "🦦", "🦨", "🦘", "🦡", "🐾", "🦃", "🐔",
|
|
70
|
+
"🐓", "🐣", "🐤", "🐥", "🐦", "🐧", "🕊️", "🦅", "🦆", "🦢",
|
|
71
|
+
"🦉", "🦩", "🦚", "🦜", "🐸", "🐊", "🐢", "🦎", "🐍", "🐲",
|
|
72
|
+
"🐉", "🦕", "🦖", "🐳", "🐋", "🐬", "🐟", "🐠", "🐡", "🦈",
|
|
73
|
+
"🐙", "🐚", "🐌", "🦋", "🐛", "🐜", "🐝", "🐞", "🦗", "🕷️",
|
|
74
|
+
"🕸️", "🦂", "🦟", "💐", "🌸", "💮", "🏵️", "🌹", "🥀", "🌺",
|
|
75
|
+
"🌻", "🌼", "🌷", "🌱", "🌲", "🌳", "🌴", "🌵", "🌾", "🌿",
|
|
76
|
+
"☘️", "🍀", "🍁", "🍂", "🍃", "🌍", "🌎", "🌏", "🌕", "🌖",
|
|
77
|
+
"🌗", "🌘", "🌑", "🌒", "🌓", "🌔", "🌙", "🌚", "🌛", "🌜",
|
|
78
|
+
"☀️", "🌝", "🌞", "⭐", "🌟", "🌠", "☁️", "⛅", "🌈", "☂️",
|
|
79
|
+
"☔", "⚡", "❄️", "☃️", "⛄", "🔥", "💧", "🌊"
|
|
80
|
+
)
|
|
81
|
+
),
|
|
82
|
+
Category(
|
|
83
|
+
icon = "🍔", // 🍔
|
|
84
|
+
label = "Food & Drink",
|
|
85
|
+
emojis = listOf(
|
|
86
|
+
"🍇", "🍈", "🍉", "🍊", "🍋", "🍌", "🍍", "🥭", "🍎", "🍏",
|
|
87
|
+
"🍐", "🍑", "🍒", "🍓", "🥝", "🍅", "🥥", "🥑", "🍆", "🥔",
|
|
88
|
+
"🥕", "🌽", "🌶️", "🥒", "🥬", "🥦", "🧄", "🧅", "🍄", "🥜",
|
|
89
|
+
"🌰", "🍞", "🥐", "🥖", "🥨", "🥯", "🥞", "🧇", "🧀", "🍖",
|
|
90
|
+
"🍗", "🥩", "🥓", "🍔", "🍟", "🍕", "🌭", "🥪", "🌮", "🌯",
|
|
91
|
+
"🥙", "🧆", "🥚", "🍳", "🥘", "🍲", "🥣", "🥗", "🍿", "🧈",
|
|
92
|
+
"🧂", "🥫", "🍱", "🍘", "🍙", "🍚", "🍛", "🍜", "🍝", "🍠",
|
|
93
|
+
"🍢", "🍣", "🍤", "🍥", "🥮", "🍡", "🥟", "🥠", "🥡", "🦀",
|
|
94
|
+
"🦞", "🦐", "🦑", "🦪", "🍦", "🍧", "🍨", "🍩", "🍪", "🎂",
|
|
95
|
+
"🍰", "🧁", "🥧", "🍫", "🍬", "🍭", "🍮", "🍯", "🍼", "🥛",
|
|
96
|
+
"☕", "🍵", "🍶", "🍾", "🍷", "🍸", "🍹", "🍺", "🍻", "🥂",
|
|
97
|
+
"🥃", "🥤", "🧃", "🧉", "🧊", "🥢", "🍽️", "🍴", "🥄"
|
|
98
|
+
)
|
|
99
|
+
),
|
|
100
|
+
Category(
|
|
101
|
+
icon = "⚽", // ⚽
|
|
102
|
+
label = "Activities",
|
|
103
|
+
emojis = listOf(
|
|
104
|
+
"⚽", "🏀", "🏈", "⚾", "🥎", "🎾", "🏐", "🏉", "🥏", "🎱",
|
|
105
|
+
"🏓", "🏸", "🏒", "🏑", "🥍", "🏏", "🥅", "⛳", "🏹", "🎣",
|
|
106
|
+
"🤿", "🥊", "🥋", "🎽", "🛹", "🛷", "⛸️", "🥌", "🎿", "⛷️",
|
|
107
|
+
"🏂", "🏋️", "🤼", "🤸", "⛹️", "🤺", "🤾", "🏌️", "🏇", "🧘",
|
|
108
|
+
"🏄", "🏊", "🤽", "🚣", "🧗", "🚵", "🚴", "🏆", "🥇", "🥈",
|
|
109
|
+
"🥉", "🏅", "🎖️", "🎗️", "🎫", "🎟️", "🎪", "🤹", "🎭", "🎨",
|
|
110
|
+
"🎬", "🎤", "🎧", "🎼", "🎹", "🥁", "🎷", "🎺", "🎸", "🪕",
|
|
111
|
+
"🎻", "🎲", "♟️", "🎯", "🎳", "🎮", "🎰", "🧩", "🎉", "🎊",
|
|
112
|
+
"🎈", "🎁", "🎀", "🎏", "🎐", "🧨", "✨", "🎃", "🎄", "🎋", "🎍"
|
|
113
|
+
)
|
|
114
|
+
),
|
|
115
|
+
Category(
|
|
116
|
+
icon = "🚗", // 🚗
|
|
117
|
+
label = "Travel & Places",
|
|
118
|
+
emojis = listOf(
|
|
119
|
+
"🚗", "🚕", "🚙", "🚌", "🚎", "🏎️", "🚓", "🚑", "🚒", "🚐",
|
|
120
|
+
"🚚", "🚛", "🚜", "🛴", "🚲", "🛵", "🏍️", "🛺", "🚨", "🚔",
|
|
121
|
+
"🚍", "🚘", "🚖", "🚡", "🚠", "🚟", "🚃", "🚋", "🚞", "🚝",
|
|
122
|
+
"🚄", "🚅", "🚈", "🚂", "🚆", "🚇", "🚊", "🚉", "✈️", "🛫",
|
|
123
|
+
"🛬", "🛩️", "💺", "🛰️", "🚀", "🛸", "🚁", "🛶", "⛵", "🚤",
|
|
124
|
+
"🛥️", "🛳️", "⛴️", "🚢", "⚓", "⛽", "🚧", "🚦", "🚥", "🚏",
|
|
125
|
+
"🗺️", "🗿", "🗽", "🗼", "🏰", "🏯", "🏟️", "🎡", "🎢", "🎠",
|
|
126
|
+
"⛲", "⛱️", "🏖️", "🏝️", "🏜️", "🌋", "⛰️", "🏔️", "🗻", "🏕️",
|
|
127
|
+
"⛺", "🏠", "🏡", "🏘️", "🏚️", "🏗️", "🏭", "🏢", "🏬", "🏣",
|
|
128
|
+
"🏤", "🏥", "🏦", "🏨", "🏪", "🏫", "🏩", "💒", "🏛️", "⛪",
|
|
129
|
+
"🕌", "🕍", "🛕", "🕋", "⛩️", "🛤️", "🛣️", "🎑", "🏞️", "🌅",
|
|
130
|
+
"🌄", "🎇", "🎆", "🌇", "🌆", "🏙️", "🌃", "🌌", "🌉", "🌁"
|
|
131
|
+
)
|
|
132
|
+
),
|
|
133
|
+
Category(
|
|
134
|
+
icon = "💡", // 💡
|
|
135
|
+
label = "Objects",
|
|
136
|
+
emojis = listOf(
|
|
137
|
+
"⌚", "📱", "📲", "💻", "⌨️", "🖥️", "🖨️", "🖱️", "🕹️", "💽",
|
|
138
|
+
"💾", "💿", "📀", "📼", "📷", "📸", "📹", "🎥", "📽️", "🎞️",
|
|
139
|
+
"📞", "☎️", "📟", "📠", "📺", "📻", "🎙️", "🧭", "⏱️", "⏲️",
|
|
140
|
+
"⏰", "🕰️", "⌛", "⏳", "📡", "🔋", "🔌", "💡", "🔦", "🕯️",
|
|
141
|
+
"🧯", "💸", "💵", "💴", "💶", "💷", "💰", "💳", "💎", "⚖️",
|
|
142
|
+
"🧰", "🔧", "🔨", "⚒️", "🛠️", "⛏️", "🔩", "⚙️", "🧱", "⛓️",
|
|
143
|
+
"🧲", "🔫", "🪓", "🔪", "🗡️", "⚔️", "🛡️", "🏺", "🔮", "📿",
|
|
144
|
+
"🧿", "💈", "⚗️", "🔭", "🔬", "💊", "💉", "🩹", "🩺", "🌡️",
|
|
145
|
+
"🧬", "🦠", "🧫", "🧪", "🧹", "🧺", "🧻", "🚽", "🚿", "🛁",
|
|
146
|
+
"🧼", "🪒", "🧽", "🧴", "🛎️", "🔑", "🗝️", "🚪", "🪑", "🛋️",
|
|
147
|
+
"🛏️", "🧸", "🖼️", "🛍️", "🛒", "✉️", "📩", "📨", "📧", "📥",
|
|
148
|
+
"📤", "📦", "🏷️", "📪", "📫", "📬", "📮", "📜", "📃", "📄",
|
|
149
|
+
"📑", "🧾", "📊", "📈", "📉", "🗒️", "🗓️", "📆", "📅", "🗑️",
|
|
150
|
+
"📇", "🗃️", "🗳️", "🗄️", "📋", "📁", "📂", "🗂️", "🗞️", "📰",
|
|
151
|
+
"📓", "📔", "📒", "📕", "📗", "📘", "📙", "📚", "📖", "🔖",
|
|
152
|
+
"🧷", "🔗", "📎", "🖇️", "📐", "📏", "🧮", "📌", "📍", "✂️",
|
|
153
|
+
"🖊️", "🖋️", "✒️", "🖌️", "🖍️", "📝", "✏️", "🔍", "🔎", "🔏",
|
|
154
|
+
"🔐", "🔒", "🔓"
|
|
155
|
+
)
|
|
156
|
+
),
|
|
157
|
+
Category(
|
|
158
|
+
icon = "🔣", // 🔣
|
|
159
|
+
label = "Symbols",
|
|
160
|
+
emojis = listOf(
|
|
161
|
+
"♈", "♉", "♊", "♋", "♌", "♍", "♎", "♏", "♐", "♑",
|
|
162
|
+
"♒", "♓", "⛎", "🔀", "🔁", "🔂", "▶️", "⏩", "◀️", "⏪",
|
|
163
|
+
"🔼", "⏫", "🔽", "⏬", "⏸️", "⏹️", "⏺️", "⏏️", "🎦", "🔅",
|
|
164
|
+
"🔆", "📶", "📳", "📴", "♀️", "♂️", "✖️", "➕", "➖", "➗",
|
|
165
|
+
"‼️", "⁉️", "❓", "❔", "❕", "❗", "〰️", "💱", "💲", "⚕️",
|
|
166
|
+
"♻️", "⚜️", "🔱", "📛", "🔰", "⭕", "✅", "☑️", "✔️", "❌",
|
|
167
|
+
"❎", "➰", "➿", "〽️", "✳️", "✴️", "❇️", "©️", "®️", "™️",
|
|
168
|
+
"🔟", "🔠", "🔡", "🔢", "🔣", "🔤", "🅰️", "🆎", "🅱️", "🆑",
|
|
169
|
+
"🆒", "🆓", "ℹ️", "🆔", "Ⓜ️", "🆕", "🆖", "🅾️", "🆗", "🅿️",
|
|
170
|
+
"🆘", "🆙", "🆚", "🔴", "🟠", "🟡", "🟢", "🔵", "🟣", "🟤",
|
|
171
|
+
"⚫", "⚪", "🟥", "🟧", "🟨", "🟩", "🟦", "🟪", "🟫", "⬛",
|
|
172
|
+
"⬜", "🔶", "🔷", "🔸", "🔹", "🔺", "🔻", "💠", "🔘", "🔳",
|
|
173
|
+
"🔲", "♠️", "♥️", "♦️", "♣️", "🃏", "🀄", "🎴", "🕐", "🕑",
|
|
174
|
+
"🕒", "🕓", "🕔", "🕕", "🕖", "🕗", "🕘", "🕙", "🕚", "🕛"
|
|
175
|
+
)
|
|
176
|
+
),
|
|
177
|
+
Category(
|
|
178
|
+
icon = "🏁", // 🏁
|
|
179
|
+
label = "Flags",
|
|
180
|
+
emojis = listOf(
|
|
181
|
+
"🏁", "🚩", "🎌", "🏴", "🏳️", "🏳️🌈", "🏴☠️",
|
|
182
|
+
"🇵🇰", "🇺🇸", "🇬🇧", "🇨🇦", "🇦🇺", "🇳🇿", "🇩🇪", "🇫🇷", "🇮🇹",
|
|
183
|
+
"🇪🇸", "🇵🇹", "🇳🇱", "🇧🇪", "🇨🇭", "🇦🇹", "🇸🇪", "🇳🇴", "🇩🇰",
|
|
184
|
+
"🇫🇮", "🇮🇪", "🇵🇱", "🇨🇿", "🇬🇷", "🇷🇺", "🇺🇦", "🇹🇷", "🇮🇳",
|
|
185
|
+
"🇧🇩", "🇱🇰", "🇳🇵", "🇦🇫", "🇮🇷", "🇮🇶", "🇨🇳", "🇯🇵", "🇰🇷",
|
|
186
|
+
"🇹🇭", "🇻🇳", "🇵🇭", "🇮🇩", "🇲🇾", "🇸🇬", "🇦🇪", "🇸🇦", "🇶🇦",
|
|
187
|
+
"🇰🇼", "🇧🇭", "🇴🇲", "🇯🇴", "🇱🇧", "🇪🇬", "🇿🇦", "🇳🇬", "🇰🇪",
|
|
188
|
+
"🇪🇹", "🇲🇦", "🇩🇿", "🇹🇳", "🇧🇷", "🇦🇷", "🇨🇱", "🇨🇴", "🇵🇪",
|
|
189
|
+
"🇻🇪", "🇲🇽", "🇺🇾", "🇺🇳", "🇪🇺"
|
|
190
|
+
)
|
|
191
|
+
)
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
@Volatile
|
|
195
|
+
private var supportedCache: List<Category>? = null
|
|
196
|
+
|
|
197
|
+
fun invalidateCache() {
|
|
198
|
+
supportedCache = null
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Categories filtered to the emoji this device's font can actually render.
|
|
203
|
+
* Computed once per process (a single [Paint.hasGlyph] sweep) and cached.
|
|
204
|
+
*/
|
|
205
|
+
fun supportedCategories(): List<Category> {
|
|
206
|
+
supportedCache?.let { return it }
|
|
207
|
+
synchronized(this) {
|
|
208
|
+
supportedCache?.let { return it }
|
|
209
|
+
val paint = Paint()
|
|
210
|
+
val filtered = categories
|
|
211
|
+
.map { cat ->
|
|
212
|
+
val labelKey = "category" + cat.label.replace(" & ", "And")
|
|
213
|
+
val label = Localization.getString(labelKey, cat.label)
|
|
214
|
+
Category(cat.icon, label, cat.emojis.filter { paint.hasGlyph(it) })
|
|
215
|
+
}
|
|
216
|
+
.filter { it.emojis.isNotEmpty() }
|
|
217
|
+
val result = if (filtered.isEmpty()) {
|
|
218
|
+
categories.map { cat ->
|
|
219
|
+
val labelKey = "category" + cat.label.replace(" & ", "And")
|
|
220
|
+
val label = Localization.getString(labelKey, cat.label)
|
|
221
|
+
Category(cat.icon, label, cat.emojis)
|
|
222
|
+
}
|
|
223
|
+
} else filtered
|
|
224
|
+
supportedCache = result
|
|
225
|
+
return result
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
package com.customcamera
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Bitmap
|
|
5
|
+
import android.graphics.Canvas
|
|
6
|
+
import android.graphics.Color
|
|
7
|
+
import android.graphics.ColorMatrix
|
|
8
|
+
import android.graphics.ColorMatrixColorFilter
|
|
9
|
+
import android.graphics.Paint
|
|
10
|
+
import android.graphics.Rect
|
|
11
|
+
import android.graphics.drawable.GradientDrawable
|
|
12
|
+
import android.view.Gravity
|
|
13
|
+
import android.view.View
|
|
14
|
+
import android.view.ViewGroup
|
|
15
|
+
import android.widget.FrameLayout
|
|
16
|
+
import android.widget.ImageView
|
|
17
|
+
import android.widget.LinearLayout
|
|
18
|
+
import android.widget.TextView
|
|
19
|
+
import androidx.recyclerview.widget.RecyclerView
|
|
20
|
+
import ja.burhanrashid52.photoeditor.PhotoFilter
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Horizontal WhatsApp-style filter strip rendered inside the camera screen's EXISTING media strip
|
|
24
|
+
* (`RecyclerView`) while Filter Selection Mode is active. Each tile is the current camera frame
|
|
25
|
+
* rendered through one [ColorMatrix] with its name beneath it.
|
|
26
|
+
*
|
|
27
|
+
* The FIRST option — "Current/Original" (filter == null) — is selected by default and never applies
|
|
28
|
+
* a filter, so the live viewfinder keeps showing through. The [matrix]es come from the same
|
|
29
|
+
* `MediaPreviewEditor.availableFilterOptions()` source the editor's own picker uses, so a filter
|
|
30
|
+
* chosen here matches the preview and the exported pixels exactly.
|
|
31
|
+
*/
|
|
32
|
+
class FilterStripAdapter(
|
|
33
|
+
context: Context,
|
|
34
|
+
private val options: List<FilterItem>,
|
|
35
|
+
private var selectedFilter: PhotoFilter?,
|
|
36
|
+
private val onFilterSelected: (PhotoFilter?) -> Unit,
|
|
37
|
+
private val thumbSource: () -> Bitmap?
|
|
38
|
+
) : RecyclerView.Adapter<FilterStripAdapter.FilterViewHolder>() {
|
|
39
|
+
|
|
40
|
+
data class FilterItem(
|
|
41
|
+
val name: String,
|
|
42
|
+
val filter: PhotoFilter?,
|
|
43
|
+
val matrix: ColorMatrix
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
private val theme = CameraTheme.get(context)
|
|
47
|
+
private val tileSize: Int = context.dp(52)
|
|
48
|
+
private val labelColor: Int = Color.WHITE
|
|
49
|
+
// Selected tile ring = the host brand `primary` (was a hardcoded #4A56FF); the unselected ring
|
|
50
|
+
// stays a faint white hairline over the dark filter tiles, host-overridable via the theme.
|
|
51
|
+
private val selectedBorder: Int = theme.colors.primary
|
|
52
|
+
private val normalBorder: Int = theme.componentColor("editor", "filterInactiveBorder", 0x55FFFFFF)
|
|
53
|
+
|
|
54
|
+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FilterViewHolder =
|
|
55
|
+
FilterViewHolder(parent, tileSize, labelColor, selectedBorder, normalBorder)
|
|
56
|
+
|
|
57
|
+
override fun getItemCount(): Int = options.size
|
|
58
|
+
|
|
59
|
+
override fun onBindViewHolder(holder: FilterViewHolder, position: Int) {
|
|
60
|
+
val item = options.getOrNull(position) ?: return
|
|
61
|
+
holder.bind(item, selected = item.filter == selectedFilter, thumbSource)
|
|
62
|
+
holder.itemView.setOnClickListener { onFilterSelected(item.filter) }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Re-point the highlight at [filter] and redraw the strip. */
|
|
66
|
+
fun setSelected(filter: PhotoFilter?) {
|
|
67
|
+
val prev = selectedFilter
|
|
68
|
+
selectedFilter = filter
|
|
69
|
+
if (prev != filter) notifyDataSetChanged()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** One tappable tile: square preview + name label, with a selection ring. */
|
|
73
|
+
class FilterViewHolder(
|
|
74
|
+
parent: ViewGroup,
|
|
75
|
+
private val tileSize: Int,
|
|
76
|
+
private val labelColor: Int,
|
|
77
|
+
private val selectedBorder: Int,
|
|
78
|
+
private val normalBorder: Int
|
|
79
|
+
) : RecyclerView.ViewHolder(
|
|
80
|
+
LinearLayout(parent.context).apply {
|
|
81
|
+
orientation = LinearLayout.VERTICAL
|
|
82
|
+
gravity = Gravity.CENTER_HORIZONTAL
|
|
83
|
+
layoutParams = RecyclerView.LayoutParams(
|
|
84
|
+
parent.context.dp(76),
|
|
85
|
+
ViewGroup.LayoutParams.MATCH_PARENT
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
) {
|
|
89
|
+
private val container = FrameLayout(itemView.context).apply {
|
|
90
|
+
layoutParams = LinearLayout.LayoutParams(tileSize, tileSize)
|
|
91
|
+
}
|
|
92
|
+
private val image = ImageView(itemView.context).apply {
|
|
93
|
+
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
94
|
+
setLayerType(View.LAYER_TYPE_SOFTWARE, null)
|
|
95
|
+
}
|
|
96
|
+
private val label = TextView(itemView.context).apply {
|
|
97
|
+
gravity = Gravity.CENTER
|
|
98
|
+
setTextColor(labelColor)
|
|
99
|
+
textSize = 11f
|
|
100
|
+
maxLines = 1
|
|
101
|
+
includeFontPadding = true
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
init {
|
|
105
|
+
container.addView(
|
|
106
|
+
image,
|
|
107
|
+
FrameLayout.LayoutParams(
|
|
108
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
109
|
+
ViewGroup.LayoutParams.MATCH_PARENT
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
(itemView as LinearLayout).apply {
|
|
113
|
+
addView(container, LinearLayout.LayoutParams(tileSize, tileSize))
|
|
114
|
+
addView(
|
|
115
|
+
label,
|
|
116
|
+
LinearLayout.LayoutParams(
|
|
117
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
118
|
+
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
119
|
+
).apply { topMargin = itemView.context.dp(4) }
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private fun border(selected: Boolean): GradientDrawable =
|
|
125
|
+
GradientDrawable().apply {
|
|
126
|
+
setColor(Color.TRANSPARENT)
|
|
127
|
+
cornerRadius = itemView.context.dp(10).toFloat()
|
|
128
|
+
setStroke(
|
|
129
|
+
itemView.context.dp(if (selected) 3 else 1),
|
|
130
|
+
if (selected) selectedBorder else normalBorder
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
fun bind(item: FilterItem, selected: Boolean, thumbSource: () -> Bitmap?) {
|
|
135
|
+
container.background = border(selected)
|
|
136
|
+
label.text = item.name
|
|
137
|
+
container.clipToOutline = true
|
|
138
|
+
container.outlineProvider = android.view.ViewOutlineProvider.BACKGROUND
|
|
139
|
+
val src = thumbSource()
|
|
140
|
+
image.setImageBitmap(src?.let { renderFilteredTile(it, item.matrix) })
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Center-crop [src] to a square and push it through [matrix]. */
|
|
144
|
+
private fun renderFilteredTile(src: Bitmap, matrix: ColorMatrix): Bitmap {
|
|
145
|
+
val side = tileSize
|
|
146
|
+
val out = Bitmap.createBitmap(side, side, Bitmap.Config.ARGB_8888)
|
|
147
|
+
val canvas = Canvas(out)
|
|
148
|
+
val paint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG).apply {
|
|
149
|
+
colorFilter = ColorMatrixColorFilter(ColorMatrix(matrix))
|
|
150
|
+
}
|
|
151
|
+
val crop = minOf(src.width, src.height).coerceAtLeast(1)
|
|
152
|
+
val left = (src.width - crop) / 2
|
|
153
|
+
val top = (src.height - crop) / 2
|
|
154
|
+
canvas.drawBitmap(src, Rect(left, top, left + crop, top + crop), Rect(0, 0, side, side), paint)
|
|
155
|
+
return out
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|