shakebug-react-native 1.0.14
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/DeviceInfo/index.js.flow +177 -0
- package/DeviceInfo/index.ts +1034 -0
- package/DeviceInfo/internal/asyncHookWrappers.ts +59 -0
- package/DeviceInfo/internal/devicesWithDynamicIsland.ts +30 -0
- package/DeviceInfo/internal/devicesWithNotch.ts +374 -0
- package/DeviceInfo/internal/nativeInterface.ts +28 -0
- package/DeviceInfo/internal/privateTypes.ts +231 -0
- package/DeviceInfo/internal/supported-platform-info.ts +97 -0
- package/DeviceInfo/internal/types.ts +19 -0
- package/DeviceInfo/web/index.js +223 -0
- package/GetLocals/src/NativeRNLocalize.ts +18 -0
- package/GetLocals/src/constants.ts +269 -0
- package/GetLocals/src/index.ts +56 -0
- package/GetLocals/src/module.ts +51 -0
- package/GetLocals/src/module.web.ts +148 -0
- package/GetLocals/src/types.ts +31 -0
- package/GetLocation/LocationError.ts +20 -0
- package/GetLocation/index.ts +46 -0
- package/GetLocation/utils.ts +89 -0
- package/ImageOrVedioPicker/src/index.ts +28 -0
- package/ImageOrVedioPicker/src/platforms/NativeImagePicker.ts +10 -0
- package/ImageOrVedioPicker/src/platforms/native.ts +61 -0
- package/ImageOrVedioPicker/src/platforms/web.ts +159 -0
- package/ImageOrVedioPicker/src/types.ts +74 -0
- package/NetInfo/src/__tests__/eventListenerCallbacks.spec.ts +332 -0
- package/NetInfo/src/__tests__/fetch.spec.ts +479 -0
- package/NetInfo/src/index.ts +186 -0
- package/NetInfo/src/internal/__mocks__/nativeModule.ts +13 -0
- package/NetInfo/src/internal/defaultConfiguration.ts +17 -0
- package/NetInfo/src/internal/defaultConfiguration.web.ts +17 -0
- package/NetInfo/src/internal/internetReachability.ts +180 -0
- package/NetInfo/src/internal/nativeInterface.ts +43 -0
- package/NetInfo/src/internal/nativeInterface.web.ts +27 -0
- package/NetInfo/src/internal/nativeModule.ts +15 -0
- package/NetInfo/src/internal/nativeModule.web.ts +306 -0
- package/NetInfo/src/internal/privateTypes.ts +41 -0
- package/NetInfo/src/internal/state.ts +137 -0
- package/NetInfo/src/internal/types.ts +128 -0
- package/README.md +246 -0
- package/RecordScreen/src/index.tsx +75 -0
- package/ScreenShot/src/RNViewShot.js +3 -0
- package/ScreenShot/src/RNViewShot.web.js +42 -0
- package/ScreenShot/src/index.js +308 -0
- package/Sensor/src/index.js +14 -0
- package/Sensor/src/rnsensors.js +57 -0
- package/Sensor/src/sensors.js +97 -0
- package/VideoPlayer/PlayVideo.tsx +51 -0
- package/VideoPlayer/index.js +69 -0
- package/android/README.md +14 -0
- package/android/build/generated/source/buildConfig/debug/com/shakebug/BuildConfig.java +10 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml +42 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json +18 -0
- package/android/build/intermediates/aar_metadata/debug/aar-metadata.properties +6 -0
- package/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json +1 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/R.txt +47 -0
- package/android/build/intermediates/compiled_local_resources/debug/out/xml_imagepicker_provider_paths.xml.flat +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +12 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
- package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/BuildConfig.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/CustomMediaMetadataRetriever.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ImageMetadata.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ImagePickerProvider.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Metadata.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Options.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/RecordScreenModule$1.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/RecordScreenModule.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Shakebug.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ShakebugPackage.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Utility.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Utils.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/VideoMetadata.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$1.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$2.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$Formats.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$Results.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$ReusableByteArrayOutputStream.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/R-def.txt +49 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt +82 -0
- package/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml +42 -0
- package/android/build/intermediates/navigation_json/debug/navigation.json +1 -0
- package/android/build/intermediates/packaged_res/debug/values/values.xml +25 -0
- package/android/build/intermediates/packaged_res/debug/xml/imagepicker_provider_paths.xml +4 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/BuildConfig.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/CustomMediaMetadataRetriever.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ImageMetadata.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ImagePickerProvider.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Metadata.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Options.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/RecordScreenModule$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/RecordScreenModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Shakebug.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ShakebugPackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Utility.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Utils.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/VideoMetadata.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$2.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$Formats.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$Results.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$ReusableByteArrayOutputStream.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot.class +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt +48 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +97 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build.gradle +235 -0
- package/android/src/main/AndroidManifest.xml +40 -0
- package/android/src/main/java/com/shakebug/AmazonFireDeviceConnectivityPoller.java +170 -0
- package/android/src/main/java/com/shakebug/BaseUtils.java +33 -0
- package/android/src/main/java/com/shakebug/BroadcastReceiverConnectivityReceiver.java +131 -0
- package/android/src/main/java/com/shakebug/ConnectivityReceiver.java +318 -0
- package/android/src/main/java/com/shakebug/CrashLoggerModule.java +48 -0
- package/android/src/main/java/com/shakebug/DateUtil.java +64 -0
- package/android/src/main/java/com/shakebug/DeviceType.java +18 -0
- package/android/src/main/java/com/shakebug/DeviceUtil.java +46 -0
- package/android/src/main/java/com/shakebug/DrawingView.java +90 -0
- package/android/src/main/java/com/shakebug/DrawingViewManager.java +38 -0
- package/android/src/main/java/com/shakebug/GetLocation.java +147 -0
- package/android/src/main/java/com/shakebug/ImageMetadata.java +42 -0
- package/android/src/main/java/com/shakebug/ImagePickerProvider.java +8 -0
- package/android/src/main/java/com/shakebug/Metadata.java +46 -0
- package/android/src/main/java/com/shakebug/NetInfoModule.java +79 -0
- package/android/src/main/java/com/shakebug/NetInfoUtils.java +50 -0
- package/android/src/main/java/com/shakebug/NetworkCallbackConnectivityReceiver.java +209 -0
- package/android/src/main/java/com/shakebug/Options.java +42 -0
- package/android/src/main/java/com/shakebug/RNDeviceModule.java +1036 -0
- package/android/src/main/java/com/shakebug/RNInstallReferrerClient.java +124 -0
- package/android/src/main/java/com/shakebug/RNLocalizeModule.java +79 -0
- package/android/src/main/java/com/shakebug/RNLocalizeModuleImpl.java +258 -0
- package/android/src/main/java/com/shakebug/ReactNativeGetLocationModule.java +95 -0
- package/android/src/main/java/com/shakebug/RecordScreenModule.java +202 -0
- package/android/src/main/java/com/shakebug/ScreenshotDetectorModule.java +63 -0
- package/android/src/main/java/com/shakebug/SettingsUtil.java +44 -0
- package/android/src/main/java/com/shakebug/Shakebug.java +181 -0
- package/android/src/main/java/com/shakebug/ShakebugPackage.java +75 -0
- package/android/src/main/java/com/shakebug/ShakebugSDKImagePickerModule.java +56 -0
- package/android/src/main/java/com/shakebug/ShakebugSDKImagePickerModuleImpl.java +230 -0
- package/android/src/main/java/com/shakebug/ShakebugSDKScreenShotModule.java +196 -0
- package/android/src/main/java/com/shakebug/SharedPreferencesModule.java +39 -0
- package/android/src/main/java/com/shakebug/UnitConverter.java +48 -0
- package/android/src/main/java/com/shakebug/Utility.java +29 -0
- package/android/src/main/java/com/shakebug/Utils.java +593 -0
- package/android/src/main/java/com/shakebug/VideoMetadata.java +91 -0
- package/android/src/main/java/com/shakebug/VideoPlayerModule.java +199 -0
- package/android/src/main/java/com/shakebug/VideoThumbnailModule.java +215 -0
- package/android/src/main/java/com/shakebug/VideoTrimModule.java +372 -0
- package/android/src/main/java/com/shakebug/ViewShot.java +627 -0
- package/android/src/main/java/com/shakebug/adapters/VideoTrimmerAdapter.java +54 -0
- package/android/src/main/java/com/shakebug/callback/SingleCallback.java +11 -0
- package/android/src/main/java/com/shakebug/interfaces/IVideoTrimmerView.java +5 -0
- package/android/src/main/java/com/shakebug/interfaces/VideoPlayerListner.java +5 -0
- package/android/src/main/java/com/shakebug/interfaces/VideoTrimListener.java +10 -0
- package/android/src/main/java/com/shakebug/resolver/DeviceIdResolver.java +87 -0
- package/android/src/main/java/com/shakebug/resolver/DeviceTypeResolver.java +94 -0
- package/android/src/main/java/com/shakebug/thread/BackgroundExecutor.java +246 -0
- package/android/src/main/java/com/shakebug/thread/UiThreadExecutor.java +120 -0
- package/android/src/main/java/com/shakebug/types/CellularGeneration.java +60 -0
- package/android/src/main/java/com/shakebug/types/ConnectionType.java +26 -0
- package/android/src/main/java/com/shakebug/utils/StorageUtil.java +139 -0
- package/android/src/main/java/com/shakebug/utils/VideoTrimmerUtil.java +89 -0
- package/android/src/main/java/com/shakebug/widgets/RangeSeekBarView.java +534 -0
- package/android/src/main/java/com/shakebug/widgets/SpacesItemDecoration2.java +32 -0
- package/android/src/main/java/com/shakebug/widgets/VideoPlayerView.java +429 -0
- package/android/src/main/java/com/shakebug/widgets/VideoTrimmerView.java +477 -0
- package/android/src/main/java/com/shakebug/widgets/ZVideoView.java +48 -0
- package/android/src/main/res/drawable/custom_progress.xml +16 -0
- package/android/src/main/res/drawable/custom_thumb.xml +4 -0
- package/android/src/main/res/drawable/ic_close_button.xml +10 -0
- package/android/src/main/res/drawable/ic_video_pause_black.png +0 -0
- package/android/src/main/res/drawable/ic_video_play_black.png +0 -0
- package/android/src/main/res/drawable/ic_video_thumb_handle.png +0 -0
- package/android/src/main/res/drawable/icon_seek_bar.png +0 -0
- package/android/src/main/res/layout/video_player_view.xml +121 -0
- package/android/src/main/res/layout/video_thumb_item_layout.xml +16 -0
- package/android/src/main/res/layout/video_trimmer_view.xml +148 -0
- package/android/src/main/res/values/colors.xml +17 -0
- package/android/src/main/res/values/strings.xml +14 -0
- package/android/src/main/res/xml/imagepicker_provider_paths.xml +4 -0
- package/ios/CammeraPermission/RNCameraPermission.h +16 -0
- package/ios/CammeraPermission/RNCameraPermission.m +46 -0
- package/ios/DeviceInfo/DeviceUID.h +14 -0
- package/ios/DeviceInfo/DeviceUID.m +202 -0
- package/ios/DeviceInfo/EnvironmentUtil.h +41 -0
- package/ios/DeviceInfo/EnvironmentUtil.m +56 -0
- package/ios/DeviceInfo/RNDeviceInfo.h +22 -0
- package/ios/DeviceInfo/RNDeviceInfo.m +918 -0
- package/ios/GetLocals/ShakebugSDKRNLocalize.h +21 -0
- package/ios/GetLocals/ShakebugSDKRNLocalize.m +296 -0
- package/ios/GetLocation/SettingsUtil.h +16 -0
- package/ios/GetLocation/SettingsUtil.m +21 -0
- package/ios/GetLocation/ShakebugSDKLocationModule.h +17 -0
- package/ios/GetLocation/ShakebugSDKLocationModule.m +218 -0
- package/ios/ImageOrVideoPicker/ShakebugSDKImagePickerManager.h +40 -0
- package/ios/ImageOrVideoPicker/ShakebugSDKImagePickerManager.m +588 -0
- package/ios/ImageOrVideoPicker/ShakebugSDKImagePickerUtils.h +26 -0
- package/ios/ImageOrVideoPicker/ShakebugSDKImagePickerUtils.m +194 -0
- package/ios/MicrophonePermissionManager.h +14 -0
- package/ios/MicrophonePermissionManager.m +35 -0
- package/ios/NetInfo/RNCConnectionState.h +42 -0
- package/ios/NetInfo/RNCConnectionState.m +119 -0
- package/ios/NetInfo/RNCConnectionStateWatcher.h +31 -0
- package/ios/NetInfo/RNCConnectionStateWatcher.m +136 -0
- package/ios/NetInfo/RNCNetInfo.h +13 -0
- package/ios/NetInfo/RNCNetInfo.m +269 -0
- package/ios/RecordScreen/ShakebugSDKRecordScreen.h +31 -0
- package/ios/RecordScreen/ShakebugSDKRecordScreen.m +309 -0
- package/ios/ScreenShot/ShakebugSDKRNViewShot.h +6 -0
- package/ios/ScreenShot/ShakebugSDKRNViewShot.m +186 -0
- package/ios/ScreenshotDetector/ScreenShotDetector.h +12 -0
- package/ios/ScreenshotDetector/ScreenShotDetector.m +37 -0
- package/ios/Senors/RNSensorsAccelerometer.h +22 -0
- package/ios/Senors/RNSensorsAccelerometer.m +162 -0
- package/ios/Senors/RNSensorsBarometer.h +22 -0
- package/ios/Senors/RNSensorsBarometer.m +141 -0
- package/ios/Senors/RNSensorsGravity.h +22 -0
- package/ios/Senors/RNSensorsGravity.m +165 -0
- package/ios/Senors/RNSensorsGyroscope.h +22 -0
- package/ios/Senors/RNSensorsGyroscope.m +160 -0
- package/ios/Senors/RNSensorsMagnetometer.h +22 -0
- package/ios/Senors/RNSensorsMagnetometer.m +163 -0
- package/ios/Senors/RNSensorsOrientation.h +22 -0
- package/ios/Senors/RNSensorsOrientation.m +189 -0
- package/ios/Senors/RNSensorsUtils.h +7 -0
- package/ios/Senors/RNSensorsUtils.m +9 -0
- package/ios/Shakebug.h +7 -0
- package/ios/Shakebug.m +16 -0
- package/ios/Shakebug.xcodeproj/project.pbxproj +872 -0
- package/ios/Shakebug.xcodeproj/xcshareddata/xcschemes/Shakebug.xcscheme +66 -0
- package/ios/Shakebug.xcworkspace/contents.xcworkspacedata +10 -0
- package/ios/Shakebug.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/SketchCanvas/DrawingView.h +18 -0
- package/ios/SketchCanvas/DrawingView.m +96 -0
- package/ios/SketchCanvas/DrawingViewManager.h +12 -0
- package/ios/SketchCanvas/DrawingViewManager.m +35 -0
- package/ios/Storage/SharedPreferencesModule.h +13 -0
- package/ios/Storage/SharedPreferencesModule.m +35 -0
- package/ios/Thumbnaill/VideoThumbnailManager.h +12 -0
- package/ios/Thumbnaill/VideoThumbnailManager.m +73 -0
- package/ios/TrimVideo/ShakebugSDKVideoTrim.swift +372 -0
- package/ios/TrimVideo/VideoTrim-Bridging-Header.h +10 -0
- package/ios/TrimVideo/VideoTrim.m +23 -0
- package/ios/TrimVideo/VideoTrimmer.swift +810 -0
- package/ios/TrimVideo/VideoTrimmerThumb.swift +119 -0
- package/ios/TrimVideo/VideoTrimmerViewController.swift +301 -0
- package/ios/VideoPlayer/VideoPlayerModule.h +14 -0
- package/ios/VideoPlayer/VideoPlayerModule.m +29 -0
- package/ios/VideoPlayer/VideoPlayerViewController.h +18 -0
- package/ios/VideoPlayer/VideoPlayerViewController.m +29 -0
- package/package.json +45 -0
- package/shakebug-react-native.podspec +50 -0
- package/src/APIs/AddIssue.js +70 -0
- package/src/APIs/EndSession.js +32 -0
- package/src/APIs/Event.js +39 -0
- package/src/APIs/MatchKey.js +40 -0
- package/src/APIs/StartSession.js +84 -0
- package/src/Assets/images/OpenSketch.png +0 -0
- package/src/Assets/images/Push.png +0 -0
- package/src/Assets/images/RemoveTextView.png +0 -0
- package/src/Assets/images/black.png +0 -0
- package/src/Assets/images/blue.png +0 -0
- package/src/Assets/images/borderdBlack.png +0 -0
- package/src/Assets/images/borderdBlue.png +0 -0
- package/src/Assets/images/borderdGreen.png +0 -0
- package/src/Assets/images/borderdRed.png +0 -0
- package/src/Assets/images/borderdYellow.png +0 -0
- package/src/Assets/images/clear.png +0 -0
- package/src/Assets/images/close.png +0 -0
- package/src/Assets/images/green.png +0 -0
- package/src/Assets/images/next.png +0 -0
- package/src/Assets/images/play.png +0 -0
- package/src/Assets/images/red.png +0 -0
- package/src/Assets/images/shake.png +0 -0
- package/src/Assets/images/shakebugLogo.png +0 -0
- package/src/Assets/images/stopButton.png +0 -0
- package/src/Assets/images/text_icon.png +0 -0
- package/src/Assets/images/yellow.png +0 -0
- package/src/Componanats/CustomAlert.js +80 -0
- package/src/Componanats/ErrorHandler.js +80 -0
- package/src/Componanats/GlobalStateContext.js +22 -0
- package/src/Componanats/KeyboardAvoidingWrapper.js +43 -0
- package/src/Componanats/NavigationContext.js +42 -0
- package/src/Componanats/ShakeFunction.js +562 -0
- package/src/Componanats/localization.js +482 -0
- package/src/Screens/AddDetailsScreen.js +462 -0
- package/src/Screens/FirstScreen.js +629 -0
- package/src/Screens/Shakebug.js +487 -0
- package/src/Screens/StrockView.js +20 -0
- package/src/Screens/TrimVideoScreen.js +81 -0
- package/src/Screens/TutorialScreen.js +36 -0
- package/src/index.tsx +117 -0
- package/trimVideo/src/index.tsx +141 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
//
|
|
2
|
+
// VideoTrim.swift
|
|
3
|
+
// Shakebug
|
|
4
|
+
//
|
|
5
|
+
// Created by ideveloper2 on 26/04/24.
|
|
6
|
+
// Copyright © 2024 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import React
|
|
10
|
+
import Photos
|
|
11
|
+
import ffmpegkit
|
|
12
|
+
|
|
13
|
+
@objc(ShakebugSDKVideoTrim)
|
|
14
|
+
class ShakebugSDKVideoTrim: RCTEventEmitter {
|
|
15
|
+
private let FILE_PREFIX = "trimmedVideo"
|
|
16
|
+
private var hasListeners = false
|
|
17
|
+
private var isShowing = false
|
|
18
|
+
|
|
19
|
+
private var saveToPhoto = true
|
|
20
|
+
private var removeAfterSavedToPhoto = false
|
|
21
|
+
private var trimmingText = "Trimming video..."
|
|
22
|
+
|
|
23
|
+
@objc
|
|
24
|
+
static override func requiresMainQueueSetup() -> Bool {
|
|
25
|
+
return true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override func supportedEvents() -> [String]! {
|
|
29
|
+
return ["ShakebugSDKVideoTrim"]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
override func startObserving() {
|
|
33
|
+
hasListeners = true
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override func stopObserving() {
|
|
37
|
+
hasListeners = false
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@objc(isValidVideo:withResolver:withRejecter:)
|
|
41
|
+
func isValidVideo(uri: String, resolve: @escaping RCTPromiseResolveBlock,reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
42
|
+
if let destPath = copyFileToDocumentDir(uri: uri) {
|
|
43
|
+
resolve(UIVideoEditorController.canEditVideo(atPath: destPath.path))
|
|
44
|
+
let _ = deleteFile(url: destPath) // remove the file we just copied to document directory
|
|
45
|
+
} else {
|
|
46
|
+
resolve(false)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@objc(showEditor:withConfig:)
|
|
51
|
+
func showEditor(uri: String, config: NSDictionary){
|
|
52
|
+
if isShowing {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
saveToPhoto = config["saveToPhoto"] as? Bool ?? true
|
|
57
|
+
removeAfterSavedToPhoto = config["removeAfterSavedToPhoto"] as? Bool ?? false
|
|
58
|
+
|
|
59
|
+
let enableCancelDialog = config["enableCancelDialog"] as? Bool ?? true
|
|
60
|
+
let cancelDialogTitle = config["cancelDialogTitle"] as? String ?? "Warning!"
|
|
61
|
+
let cancelDialogMessage = config["cancelDialogMessage"] as? String ?? "Are you sure want to cancel?"
|
|
62
|
+
let cancelDialogCancelText = config["cancelDialogCancelText"] as? String ?? "Close"
|
|
63
|
+
let cancelDialogConfirmText = config["cancelDialogConfirmText"] as? String ?? "Proceed"
|
|
64
|
+
|
|
65
|
+
let enableSaveDialog = config["enableSaveDialog"] as? Bool ?? true
|
|
66
|
+
let saveDialogTitle = config["saveDialogTitle"] as? String ?? "Confirmation!"
|
|
67
|
+
let saveDialogMessage = config["saveDialogMessage"] as? String ?? "Are you sure want to save?"
|
|
68
|
+
let saveDialogCancelText = config["saveDialogCancelText"] as? String ?? "Close"
|
|
69
|
+
let saveDialogConfirmText = config["saveDialogConfirmText"] as? String ?? "Proceed"
|
|
70
|
+
trimmingText = config["trimmingText"] as? String ?? "Trimming video..."
|
|
71
|
+
let fullScreenModalIOS = config["fullScreenModalIOS"] as? Bool ?? false
|
|
72
|
+
|
|
73
|
+
if let destPath = copyFileToDocumentDir(uri: uri) {
|
|
74
|
+
if UIVideoEditorController.canEditVideo(atPath: destPath.path) {
|
|
75
|
+
DispatchQueue.main.async {
|
|
76
|
+
if #available(iOS 13.0, *) {
|
|
77
|
+
let vc = VideoTrimmerViewController()
|
|
78
|
+
vc.asset = AVURLAsset(url: destPath, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
|
|
79
|
+
|
|
80
|
+
if let maxDuration = config["maxDuration"] as? Int {
|
|
81
|
+
vc.maximumDuration = maxDuration
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if let minDuration = config["minDuration"] as? Int {
|
|
85
|
+
vc.minimumDuration = minDuration
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if let cancelBtnText = config["cancelButtonText"] as? String, !cancelBtnText.isEmpty {
|
|
89
|
+
vc.cancelBtnText = cancelBtnText
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if let saveButtonText = config["saveButtonText"] as? String, !saveButtonText.isEmpty {
|
|
93
|
+
vc.saveButtonText = saveButtonText
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
vc.cancelBtnClicked = {
|
|
97
|
+
if !enableCancelDialog {
|
|
98
|
+
let _ = self.deleteFile(url: destPath) // remove the file we just copied to document directory
|
|
99
|
+
self.emitEventToJS("onCancelTrimming", eventData: nil)
|
|
100
|
+
|
|
101
|
+
vc.dismiss(animated: true, completion: {
|
|
102
|
+
self.emitEventToJS("onHide", eventData: nil)
|
|
103
|
+
self.isShowing = false
|
|
104
|
+
})
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Create Alert
|
|
109
|
+
let dialogMessage = UIAlertController(title: cancelDialogTitle, message: cancelDialogMessage, preferredStyle: .alert)
|
|
110
|
+
|
|
111
|
+
// Create OK button with action handler
|
|
112
|
+
let ok = UIAlertAction(title: cancelDialogConfirmText, style: .destructive, handler: { (action) -> Void in
|
|
113
|
+
let _ = self.deleteFile(url: destPath) // remove the file we just copied to document directory
|
|
114
|
+
self.emitEventToJS("onCancelTrimming", eventData: nil)
|
|
115
|
+
|
|
116
|
+
vc.dismiss(animated: true, completion: {
|
|
117
|
+
self.emitEventToJS("onHide", eventData: nil)
|
|
118
|
+
self.isShowing = false
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
// Create Cancel button with action handlder
|
|
123
|
+
let cancel = UIAlertAction(title: cancelDialogCancelText, style: .cancel)
|
|
124
|
+
|
|
125
|
+
//Add OK and Cancel button to an Alert object
|
|
126
|
+
dialogMessage.addAction(ok)
|
|
127
|
+
dialogMessage.addAction(cancel)
|
|
128
|
+
|
|
129
|
+
// Present alert message to user
|
|
130
|
+
if let root = RCTPresentedViewController() {
|
|
131
|
+
root.present(dialogMessage, animated: true, completion: nil)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
vc.saveBtnClicked = {(selectedRange: CMTimeRange) in
|
|
136
|
+
if !enableSaveDialog {
|
|
137
|
+
self.trim(viewController: vc,inputFile: destPath, videoDuration: vc.asset.duration.seconds, startTime: selectedRange.start.seconds, endTime: selectedRange.end.seconds)
|
|
138
|
+
return
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Create Alert
|
|
142
|
+
let dialogMessage = UIAlertController(title: saveDialogTitle, message: saveDialogMessage, preferredStyle: .alert)
|
|
143
|
+
|
|
144
|
+
// Create OK button with action handler
|
|
145
|
+
let ok = UIAlertAction(title: saveDialogConfirmText, style: .default, handler: { (action) -> Void in
|
|
146
|
+
self.trim(viewController: vc,inputFile: destPath, videoDuration: vc.asset.duration.seconds, startTime: selectedRange.start.seconds, endTime: selectedRange.end.seconds)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
// Create Cancel button with action handlder
|
|
150
|
+
let cancel = UIAlertAction(title: saveDialogCancelText, style: .cancel)
|
|
151
|
+
|
|
152
|
+
//Add OK and Cancel button to an Alert object
|
|
153
|
+
dialogMessage.addAction(ok)
|
|
154
|
+
dialogMessage.addAction(cancel)
|
|
155
|
+
|
|
156
|
+
// Present alert message to user
|
|
157
|
+
if let root = RCTPresentedViewController() {
|
|
158
|
+
root.present(dialogMessage, animated: true, completion: nil)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
vc.isModalInPresentation = true // prevent modal closed by swipe down
|
|
163
|
+
|
|
164
|
+
if fullScreenModalIOS {
|
|
165
|
+
vc.modalPresentationStyle = .fullScreen
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if let root = RCTPresentedViewController() {
|
|
169
|
+
root.present(vc, animated: true, completion: {
|
|
170
|
+
self.emitEventToJS("onShow", eventData: nil)
|
|
171
|
+
self.isShowing = true
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
let eventPayload: [String: Any] = ["message": "File is not a valid video"]
|
|
178
|
+
self.emitEventToJS("onError", eventData: eventPayload)
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
let eventPayload: [String: Any] = ["message": "File is invalid"]
|
|
182
|
+
self.emitEventToJS("onError", eventData: eventPayload)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private func copyFileToDocumentDir(uri: String) -> URL? {
|
|
187
|
+
if let videoURL = URL(string: uri) {
|
|
188
|
+
// Save the video to the document directory
|
|
189
|
+
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
190
|
+
// Extract the file extension from the videoURL
|
|
191
|
+
let fileExtension = videoURL.pathExtension
|
|
192
|
+
|
|
193
|
+
// Define the filename with the correct file extension
|
|
194
|
+
let timestamp = Int(Date().timeIntervalSince1970)
|
|
195
|
+
let destinationURL = documentsDirectory.appendingPathComponent("\(FILE_PREFIX)_original_\(timestamp).\(fileExtension)")
|
|
196
|
+
|
|
197
|
+
do {
|
|
198
|
+
try FileManager.default.copyItem(at: videoURL, to: destinationURL)
|
|
199
|
+
} catch {
|
|
200
|
+
print("Error while copying file to document directory \(error)")
|
|
201
|
+
return nil
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return destinationURL
|
|
205
|
+
} else {
|
|
206
|
+
return nil
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private func emitEventToJS(_ eventName: String, eventData: [String: Any]?) {
|
|
211
|
+
if hasListeners {
|
|
212
|
+
var modifiedEventData = eventData ?? [:] // If eventData is nil, create an empty dictionary
|
|
213
|
+
modifiedEventData["name"] = eventName
|
|
214
|
+
sendEvent(withName: "ShakebugSDKVideoTrim", body: modifiedEventData)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
@objc(listFiles:withRejecter:)
|
|
219
|
+
func listFiles(resolve: @escaping RCTPromiseResolveBlock,reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
220
|
+
let files = listFiles()
|
|
221
|
+
resolve(files.map{ $0.absoluteString })
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@objc(cleanFiles:withRejecter:)
|
|
225
|
+
func cleanFiles(resolve: @escaping RCTPromiseResolveBlock,reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
226
|
+
let files = listFiles()
|
|
227
|
+
var successCount = 0
|
|
228
|
+
for file in files {
|
|
229
|
+
let state = deleteFile(url: file)
|
|
230
|
+
|
|
231
|
+
if state == 0 {
|
|
232
|
+
successCount += 1
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
resolve(successCount)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
@objc(deleteFile:withResolver:withRejecter:)
|
|
240
|
+
func deleteFile(uri: String, resolve: @escaping RCTPromiseResolveBlock,reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
241
|
+
let state = deleteFile(url: URL(string: uri)!)
|
|
242
|
+
resolve(state == 0)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private func listFiles() -> [URL] {
|
|
246
|
+
var files: [URL] = []
|
|
247
|
+
|
|
248
|
+
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
249
|
+
|
|
250
|
+
do {
|
|
251
|
+
let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsDirectory, includingPropertiesForKeys: nil)
|
|
252
|
+
|
|
253
|
+
for fileURL in directoryContents {
|
|
254
|
+
if fileURL.lastPathComponent.starts(with: FILE_PREFIX) {
|
|
255
|
+
files.append(fileURL)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
} catch {
|
|
259
|
+
print("[listFiles] Error when retrieving files: \(error)")
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return files
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
private func deleteFile(url: URL) -> Int {
|
|
266
|
+
do {
|
|
267
|
+
if FileManager.default.fileExists(atPath: url.path) {
|
|
268
|
+
try FileManager.default.removeItem(at: url)
|
|
269
|
+
|
|
270
|
+
return 0
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return 1
|
|
274
|
+
} catch {
|
|
275
|
+
print("[deleteFile] Error deleting files: \(error)")
|
|
276
|
+
|
|
277
|
+
return 2
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
@available(iOS 13.0, *)
|
|
282
|
+
private func trim(viewController: VideoTrimmerViewController, inputFile: URL, videoDuration: Double, startTime: Double, endTime: Double) {
|
|
283
|
+
let timestamp = Int(Date().timeIntervalSince1970)
|
|
284
|
+
let outputName = "\(FILE_PREFIX)_\(timestamp).mp4" // use mp4 to prevent any issue with ffmpeg about file extension
|
|
285
|
+
let outputFile = "\(inputFile.deletingLastPathComponent().absoluteURL)\(outputName)"
|
|
286
|
+
let cmd = "-ss \(startTime * 1000)ms -to \(endTime * 1000)ms -i \(inputFile) -c copy \(outputFile)";
|
|
287
|
+
|
|
288
|
+
self.emitEventToJS("onStartTrimming", eventData: nil)
|
|
289
|
+
|
|
290
|
+
// Create Alert
|
|
291
|
+
let dialogMessage = UIAlertController(title: trimmingText, message: nil, preferredStyle: .alert)
|
|
292
|
+
|
|
293
|
+
// Present alert message to user
|
|
294
|
+
let progressView = UIProgressView(frame: .zero)
|
|
295
|
+
progressView.tintColor = .systemBlue
|
|
296
|
+
if let root = RCTPresentedViewController() {
|
|
297
|
+
root.present(dialogMessage, animated: true, completion: {
|
|
298
|
+
dialogMessage.view.addSubview(progressView)
|
|
299
|
+
|
|
300
|
+
progressView.translatesAutoresizingMaskIntoConstraints = false
|
|
301
|
+
NSLayoutConstraint.activate([
|
|
302
|
+
progressView.leadingAnchor.constraint(equalTo: dialogMessage.view.leadingAnchor, constant: 8),
|
|
303
|
+
progressView.trailingAnchor.constraint(equalTo: dialogMessage.view.trailingAnchor, constant: -8),
|
|
304
|
+
progressView.bottomAnchor.constraint(equalTo: dialogMessage.view.bottomAnchor, constant: -8)
|
|
305
|
+
])
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
FFmpegKit.executeAsync(cmd, withCompleteCallback: { session in
|
|
310
|
+
let _ = self.deleteFile(url: inputFile) // remove the file we just copied to document directory
|
|
311
|
+
|
|
312
|
+
let state = session?.getState()
|
|
313
|
+
let returnCode = session?.getReturnCode()
|
|
314
|
+
|
|
315
|
+
if ReturnCode.isSuccess(returnCode) {
|
|
316
|
+
let eventPayload: [String: Any] = ["outputPath": outputFile]
|
|
317
|
+
self.emitEventToJS("onFinishTrimming", eventData: eventPayload)
|
|
318
|
+
|
|
319
|
+
if (self.saveToPhoto) {
|
|
320
|
+
PHPhotoLibrary.requestAuthorization { status in
|
|
321
|
+
guard status == .authorized else {
|
|
322
|
+
let eventPayload: [String: Any] = ["message": "Permission to access Photo Library is not granted"]
|
|
323
|
+
self.emitEventToJS("onError", eventData: eventPayload)
|
|
324
|
+
return
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
PHPhotoLibrary.shared().performChanges({
|
|
328
|
+
let request = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL(string: outputFile)!)
|
|
329
|
+
request?.creationDate = Date()
|
|
330
|
+
}) { success, error in
|
|
331
|
+
if success {
|
|
332
|
+
print("Edited video saved to Photo Library successfully.")
|
|
333
|
+
|
|
334
|
+
if self.removeAfterSavedToPhoto {
|
|
335
|
+
let _ = self.deleteFile(url: URL(string: outputFile)!)
|
|
336
|
+
}
|
|
337
|
+
} else {
|
|
338
|
+
let eventPayload: [String: Any] = ["message": "Failed to save edited video to Photo Library: \(error?.localizedDescription ?? "Unknown error")"]
|
|
339
|
+
self.emitEventToJS("onError", eventData: eventPayload)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
// CANCEL + FAILURE
|
|
346
|
+
let eventPayload: [String: Any] = ["message": "Command failed with state \(String(describing: FFmpegKitConfig.sessionState(toString: state ?? .failed))) and rc \(String(describing: returnCode)).\(String(describing: session?.getFailStackTrace()))"]
|
|
347
|
+
self.emitEventToJS("onError", eventData: eventPayload)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// some how in case we trim a very short video the view controller is still visible after first .dismiss call
|
|
351
|
+
// even the file is successfully saved
|
|
352
|
+
// that's why we need a small delay here to ensure vc will be dismissed
|
|
353
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
|
354
|
+
dialogMessage.dismiss(animated: false)
|
|
355
|
+
viewController.dismiss(animated: true, completion: {
|
|
356
|
+
self.emitEventToJS("onHide", eventData: nil)
|
|
357
|
+
self.isShowing = false
|
|
358
|
+
})
|
|
359
|
+
}
|
|
360
|
+
}, withLogCallback: { log in
|
|
361
|
+
|
|
362
|
+
}, withStatisticsCallback: { statistics in
|
|
363
|
+
let timeInMilliseconds = statistics?.getTime() ?? 0;
|
|
364
|
+
if timeInMilliseconds > 0 {
|
|
365
|
+
let completePercentage = timeInMilliseconds / (videoDuration * 1000); // from 0 -> 1
|
|
366
|
+
DispatchQueue.main.async {
|
|
367
|
+
progressView.setProgress(Float(completePercentage), animated: true)
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
}
|
|
372
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//
|
|
2
|
+
// VideoTrim.m
|
|
3
|
+
// Shakebug
|
|
4
|
+
//
|
|
5
|
+
// Created by ideveloper2 on 26/04/24.
|
|
6
|
+
// Copyright © 2024 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <React/RCTBridgeModule.h>
|
|
10
|
+
#import <React/RCTEventEmitter.h>
|
|
11
|
+
|
|
12
|
+
@interface RCT_EXTERN_MODULE(ShakebugSDKVideoTrim, RCTEventEmitter)
|
|
13
|
+
|
|
14
|
+
RCT_EXTERN_METHOD(showEditor:(NSString*)uri withConfig:(NSDictionary *)config)
|
|
15
|
+
RCT_EXTERN_METHOD(isValidVideo:(NSString*)uri withResolver:(RCTPromiseResolveBlock)resolve
|
|
16
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
17
|
+
RCT_EXTERN_METHOD(listFiles:(RCTPromiseResolveBlock)resolve
|
|
18
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
19
|
+
RCT_EXTERN_METHOD(cleanFiles:(RCTPromiseResolveBlock)resolve
|
|
20
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
21
|
+
RCT_EXTERN_METHOD(deleteFile:(NSString*)uri withResolver:(RCTPromiseResolveBlock)resolve
|
|
22
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
23
|
+
@end
|