shakebug-react-native 2.4.9 → 2.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +0 -12
  2. package/VideoPlayer/PlayVideo.tsx +4 -46
  3. package/VideoPlayer/index.js +6 -43
  4. package/android/src/main/java/com/shakebug/BaseUtils.java +7 -19
  5. package/android/src/main/java/com/shakebug/DeviceUtil.java +34 -21
  6. package/android/src/main/java/com/shakebug/ShakebugPackage.java +3 -3
  7. package/android/src/main/java/com/shakebug/UnitConverter.java +8 -8
  8. package/android/src/main/java/com/shakebug/VideoPlayerModule.java +81 -0
  9. package/android/src/main/java/com/shakebug/VideoTrimModule.java +387 -0
  10. package/android/src/main/java/com/shakebug/VideoTrimUtil.java +133 -0
  11. package/android/src/main/java/com/shakebug/adapters/VideoTrimmerAdapter.java +53 -0
  12. package/android/src/main/java/com/shakebug/callback/SingleCallback.java +0 -6
  13. package/android/src/main/java/com/shakebug/thread/BackgroundExecutor.java +1 -93
  14. package/android/src/main/java/com/shakebug/thread/UiThreadExecutor.java +0 -37
  15. package/android/src/main/java/com/shakebug/utils/StorageUtil.java +135 -0
  16. package/android/src/main/java/com/shakebug/utils/VideoTrimmerUtil.java +70 -0
  17. package/android/src/main/java/com/shakebug/widgets/RangeSeekBarView.java +534 -0
  18. package/android/src/main/java/com/shakebug/widgets/SpacesItemDecoration2.java +1 -2
  19. package/android/src/main/java/com/shakebug/widgets/VideoPlayerView.java +317 -0
  20. package/android/src/main/java/com/shakebug/widgets/VideoTrimmerView.java +520 -0
  21. package/android/src/main/res/drawable/ic_volume_off.xml +10 -0
  22. package/android/src/main/res/drawable/ic_volume_on.xml +10 -0
  23. package/android/src/main/res/layout/{video_player_view.xml → shakebug_video_player_view.xml} +29 -9
  24. package/ios/TrimVideo/ShakebugSDKVideoTrim.swift +389 -0
  25. package/ios/TrimVideo/VideoTrim-Bridging-Header.h +10 -0
  26. package/ios/TrimVideo/VideoTrim.m +23 -0
  27. package/ios/TrimVideo/VideoTrimmer.swift +810 -0
  28. package/ios/TrimVideo/VideoTrimmerThumb.swift +119 -0
  29. package/ios/TrimVideo/VideoTrimmerViewController.swift +322 -0
  30. package/ios/VideoPlayer/VideoPlayerModule.m +23 -7
  31. package/package.json +1 -1
  32. package/src/Componanats/LoadingModal.js +59 -0
  33. package/src/Componanats/ShakeFunction.js +2 -10
  34. package/src/Screens/AddDetailsScreen.js +28 -31
  35. package/src/Screens/FirstScreen.js +15 -18
  36. package/src/Screens/Shakebug.js +1 -1
  37. package/src/Screens/TrimVideoScreen.js +37 -22
  38. package/src/index.tsx +4 -4
  39. package/trimVideo/src/index.tsx +12 -48
  40. package/shakebug-react-native-2.4.8.tgz +0 -0
  41. /package/android/src/main/res/layout/{video_thumb_item_layout.xml → shakebug_video_thumb_item_layout.xml} +0 -0
  42. /package/android/src/main/res/layout/{video_trimmer_view.xml → shakebug_video_trimmer_view.xml} +0 -0
@@ -12,6 +12,7 @@ import { ScrollView } from 'react-native';
12
12
  import KeyboardAvoidingWrapper from '../Componanats/KeyboardAvoidingWrapper';
13
13
  import { useGlobalState } from '../Componanats/GlobalStateContext';
14
14
  import CustomeAlert from '../Componanats/CustomAlert';
15
+ import LoadingModal from '../Componanats/LoadingModal';
15
16
  import NetInfo from '../../NetInfo/src';
16
17
  import DeviceInfo from '../../DeviceInfo';
17
18
 
@@ -92,10 +93,11 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
92
93
  try {
93
94
 
94
95
  const { create: createThumbnail } = CreateThumbnail;
96
+ const cleanVideoPath = path ? path.replace('file://', '') : '';
95
97
 
96
98
  const thumbnail = await createThumbnail({
97
- url: `file://${path}`,
98
- timeStamp: 10000,
99
+ url: `file://${cleanVideoPath}`,
100
+ timeStamp: 1000,
99
101
  })
100
102
 
101
103
  if (thumbnail) {
@@ -145,6 +147,7 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
145
147
  // For open Video picker
146
148
  const openVideoPicker = () => {
147
149
  global.IsBackground = "false"
150
+ setIsLoading(true)
148
151
 
149
152
  const options = {
150
153
  mediaType: 'video',
@@ -153,26 +156,26 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
153
156
  };
154
157
 
155
158
  launchImageLibrary(options, async (response) => {
156
- setIsLoading(true)
157
159
  if (response.didCancel) {
158
160
  setIsLoading(false)
159
- global.IsBackground = "fa"
161
+ global.IsBackground = "false"
160
162
  // console.log('User cancelled image picker');
161
- } else if (response.error) {
163
+ } else if (response.error || response.errorCode) {
162
164
  setIsLoading(false)
163
165
  global.IsBackground = "true"
164
166
  // console.log('Image picker error: ', response.error);
165
167
  } else {
166
- setIsLoading(false)
167
168
  global.IsBackground = "true"
168
169
  let videoUri = await response.uri || response.assets?.[0]?.uri;
169
- if (response.assets?.[0]?.type.slice(0, 5).trim() == "video") {
170
+ if (response.assets?.[0]?.type?.slice(0, 5).trim() == "video") {
170
171
  if (mediaType == "img")
171
172
  navigate("TrimVideoScreen", { video: `${videoUri}`, Type: "imgReplacedWithVideo", themeColor: ThemeColor, SDKScreenTitle: SDKScreenTitle, UpdateStatusBar: UpdateStatusBar, updateParent: updateParent })
172
173
  else
173
174
  navigate("TrimVideoScreen", { video: `${videoUri}`, Type: "videoReplacedWithVideo", themeColor: ThemeColor, SDKScreenTitle: SDKScreenTitle, UpdateStatusBar: UpdateStatusBar, updateParent: updateParent })
175
+ setIsLoading(false)
174
176
  }
175
177
  else {
178
+ setIsLoading(false)
176
179
  setAPIMessage("Invalid selection, Please choose a valid video file")
177
180
  setErrorInAPI(true)
178
181
  }
@@ -184,25 +187,24 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
184
187
  // For open image picker
185
188
  const openImagePicker = () => {
186
189
  global.IsBackground = "false"
190
+ setIsLoading(true)
187
191
  const options = {
188
192
  mediaType: 'photo',
189
193
  includeBase64: false,
190
194
  selectionLimit: 1
191
195
  };
192
196
  launchImageLibrary(options, async (response) => {
193
- setIsLoading(true)
194
197
  if (response.didCancel) {
195
198
  setIsLoading(false)
196
199
  global.IsBackground = "true"
197
200
  // console.log('User cancelled image picker');
198
- } else if (response.error) {
201
+ } else if (response.error || response.errorCode) {
199
202
  setIsLoading(false)
200
203
  global.IsBackground = "true"
201
204
  // console.log('Image picker error: ', response.error);
202
205
  } else {
203
-
204
206
  global.IsBackground = "true"
205
- if (response.assets?.[0]?.type.slice(0, 5).trim() == "image") {
207
+ if (response.assets?.[0]?.type?.slice(0, 5).trim() == "image") {
206
208
  let imageuri = await response.uri || response.assets?.[0]?.uri;
207
209
  setIsLoading(false)
208
210
  if (imageuri != "" || imageuri != undefined) {
@@ -217,6 +219,7 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
217
219
  }
218
220
  }
219
221
  else {
222
+ setIsLoading(false)
220
223
  setAPIMessage("Invalid selection, Please choose a valid image file")
221
224
  setErrorInAPI(true)
222
225
  }
@@ -285,13 +288,18 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
285
288
  }
286
289
 
287
290
  return (
288
- <SafeAreaView style={{ flex: 1, backgroundColor: ThemeColor, paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0 }}>
291
+ <View style={{ flex: 1, backgroundColor: '#fff' }}>
289
292
  <StatusBar backgroundColor={ThemeColor} hidden={false} barStyle="dark-content" />
290
- <View style={{
291
- flex: 1,
292
- backgroundColor: "#fff",
293
- paddingBottom: Platform.OS === 'android' ? 48 : 0 // Standard bottom navigation bar height
294
- }}>
293
+ <SafeAreaView style={{ flex: 0, backgroundColor: ThemeColor }} />
294
+ {Platform.OS === 'android' && StatusBar.currentHeight ? (
295
+ <View style={{ height: StatusBar.currentHeight, backgroundColor: ThemeColor }} />
296
+ ) : null}
297
+ <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>
298
+ <View style={{
299
+ flex: 1,
300
+ backgroundColor: "#fff",
301
+ paddingBottom: Platform.OS === 'android' ? 48 : 0 // Standard bottom navigation bar height
302
+ }}>
295
303
  <KeyboardAvoidingWrapper>
296
304
  <>
297
305
  <View style={{ height: '6%', padding: 5, paddingHorizontal: 15, backgroundColor: ThemeColor, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }}>
@@ -436,7 +444,7 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
436
444
  <CustomeAlert
437
445
  isVisible={isErrorInAPI || isBugReported}
438
446
  text={apiMessage}
439
- color={themeColor}
447
+ color={ThemeColor}
440
448
  OnPrees={() => {
441
449
  if (isBugReported) {
442
450
  global.isScreenShotDetected = false;
@@ -449,24 +457,13 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
449
457
  setIsLoading(false)
450
458
  }}
451
459
  />
452
-
453
-
454
- {isLoading &&
455
- <View
456
- style={{
457
- ...StyleSheet.absoluteFillObject,
458
- backgroundColor: 'rgba(0, 0, 0, 0.4)',
459
- }}
460
- />
461
- }
462
-
463
- {isLoading &&
464
- <ActivityIndicator size={'large'} color={themeColor} collapsable={true} style={{ position: 'absolute', top: 0, bottom: 0, left: 0, right: 0, elevation: 2 }} />}
465
460
  </>
466
461
  </KeyboardAvoidingWrapper>
467
462
  </View>
468
463
 
469
464
  </SafeAreaView>
465
+ <LoadingModal visible={isLoading} color={ThemeColor} />
466
+ </View>
470
467
  )
471
468
  }
472
469
 
@@ -11,6 +11,7 @@ import { ActivityIndicator } from 'react-native';
11
11
  import DeviceInfo from '../../DeviceInfo';
12
12
  import { useGlobalState } from '../Componanats/GlobalStateContext.js';
13
13
  import CustomeAlert from '../Componanats/CustomAlert.js';
14
+ import LoadingModal from '../Componanats/LoadingModal.js';
14
15
 
15
16
  console.disableYellowBox = true;
16
17
  console.ignoredYellowBox = ["Warning: Each", "Warning: Failed", "Possible"];
@@ -108,6 +109,7 @@ const FirstScreen = ({ img, themeColor, SDKScreenTitle }) => {
108
109
 
109
110
  // open Video picker to choose video
110
111
  const openVideoPicker = () => {
112
+ setIsLoading(true)
111
113
  const options = {
112
114
  mediaType: 'video',
113
115
  includeBase64: false,
@@ -115,19 +117,19 @@ const FirstScreen = ({ img, themeColor, SDKScreenTitle }) => {
115
117
  };
116
118
 
117
119
  launchImageLibrary(options, async (response) => {
118
- setIsLoading(true)
119
120
  if (response.didCancel) {
120
121
  setIsLoading(false)
121
- } else if (response.error) {
122
+ } else if (response.error || response.errorCode) {
122
123
  setIsLoading(false)
123
124
  // console.log('Image picker error: ', response.error);
124
125
  } else {
125
126
  let vedioUri = await response.uri || response.assets?.[0]?.uri;
126
- if (response.assets?.[0]?.type.slice(0, 5).trim() == "video") {
127
+ if (response.assets?.[0]?.type?.slice(0, 5).trim() == "video") {
127
128
  setIsLoading(false)
128
129
  navigate("TrimVideoScreen", { video: `${vedioUri}`, Type: "video", themeColor: `${ThemeColor}`, SDKScreenTitle: `${SDKScreenTitle}`, UpdateStatusBar: UpdateStatusBar, updateParent: updateImage })
129
130
  }
130
131
  else {
132
+ setIsLoading(false)
131
133
  setIsAlertText("Invalid selection, Please choose a valid video file")
132
134
  setIsAlert(true)
133
135
  }
@@ -310,9 +312,13 @@ const FirstScreen = ({ img, themeColor, SDKScreenTitle }) => {
310
312
  // backgroundColor: "#181818"
311
313
 
312
314
  return (
313
- <SafeAreaView style={{ flex: 1, backgroundColor: ThemeColor, paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0 }}>
314
- <StatusBar backgroundColor={ThemeColor} barStyle="dark-content" />
315
-
315
+ <View style={{ flex: 1, backgroundColor: '#fff' }}>
316
+ <StatusBar backgroundColor={ThemeColor} barStyle="dark-content" />
317
+ <SafeAreaView style={{ flex: 0, backgroundColor: ThemeColor }} />
318
+ {Platform.OS === 'android' && StatusBar.currentHeight ? (
319
+ <View style={{ height: StatusBar.currentHeight, backgroundColor: ThemeColor }} />
320
+ ) : null}
321
+ <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>
316
322
  <View style={{
317
323
  flex: 1,
318
324
  backgroundColor: "#e4fdfd",
@@ -547,28 +553,19 @@ const FirstScreen = ({ img, themeColor, SDKScreenTitle }) => {
547
553
  </KeyboardAvoidingView>
548
554
  </View>) : null}
549
555
 
550
- {isLoading &&
551
- <View
552
- style={{
553
- ...StyleSheet.absoluteFillObject,
554
- backgroundColor: 'rgba(0, 0, 0, 0.4)',
555
- }}
556
- />
557
- }
558
-
559
556
  <CustomeAlert
560
557
  isVisible={isAlert}
561
558
  text={isAlertText}
562
- color={themeColor}
559
+ color={ThemeColor}
563
560
  OnPrees={() => {
564
561
  setIsAlert(false)
565
562
  setIsAlertText("")
566
563
  }}
567
564
  />
568
565
 
569
- {isLoading && <ActivityIndicator size={'large'} color={themeColor} collapsable={true} style={{ position: 'absolute', top: 0, bottom: 0, left: 0, right: 0, elevation: 2 }} />}
570
-
571
566
  </SafeAreaView>
567
+ <LoadingModal visible={isLoading} color={ThemeColor} />
568
+ </View>
572
569
  )
573
570
  }
574
571
 
@@ -63,7 +63,7 @@ global.isScreeenShotTaken = false;
63
63
  global.restrictedViews = [];
64
64
  global.currentScreen = ""
65
65
  global.isShakebugSDKOpen = false;
66
- global.sdk_version = "2.4.9";
66
+ global.sdk_version = "2.4.10";
67
67
  global.app_lunch_count = 0;
68
68
  global.POPUP_LAUNCH_THRESHOLD = 3;
69
69
  global.POPUP_COOLDOWN_DAYS = 2;
@@ -1,26 +1,27 @@
1
- import { NativeEventEmitter, NativeModules, Platform, SafeAreaView, StatusBar } from 'react-native'
1
+ import { DeviceEventEmitter, NativeEventEmitter, NativeModules, Platform, SafeAreaView, StatusBar, View } from 'react-native'
2
2
  import React, { useEffect, useState } from 'react'
3
- import { showEditor } from 'react-native-video-trim';
3
+ import { showEditor } from '../../trimVideo/src/index';
4
4
  import { useNavigation } from '../Componanats/NavigationContext';
5
5
  import { Localization } from '../Componanats/localization';
6
+ import LoadingModal from '../Componanats/LoadingModal';
6
7
 
7
8
  console.ignoredYellowBox = ["Warning: Each", "Warning: Failed"];
8
9
 
9
-
10
-
11
10
  const TrimVideoScreen = ({ video, themeColor, SDKScreenTitle, Type, UpdateStatusBar, updateParent }) => {
12
11
 
13
12
  const { goToScreenAtIndex, navigate, goBack } = useNavigation();
13
+ const [loading, setLoading] = useState(true);
14
14
 
15
+ const ThemeColor = themeColor ? themeColor : "#1dd3e3";
15
16
 
16
17
  // For display video trimmer
17
18
  useEffect(() => {
18
19
  StatusBar.setHidden(true)
19
20
 
20
21
  const uri = video; // your path
21
- const trimmedUri = uri.replace('file://', '');
22
+ const cleanUri = uri.replace('file://', '');
22
23
 
23
- showEditor(Platform.OS == 'android' ? trimmedUri : video, {
24
+ showEditor(cleanUri, {
24
25
  saveButtonText: Localization[global.ShakebugLanguage].Choose,
25
26
  cancelButtonText: Localization[global.ShakebugLanguage].Cancel,
26
27
  trimmingText: Localization[global.ShakebugLanguage].TrimmingText,
@@ -38,50 +39,64 @@ const TrimVideoScreen = ({ video, themeColor, SDKScreenTitle, Type, UpdateStatus
38
39
  saveDialogConfirmText: Localization[global.ShakebugLanguage].Yes
39
40
  });
40
41
 
41
- const eventEmitter = new NativeEventEmitter(NativeModules.VideoTrim);
42
- const subscription = eventEmitter.addListener('VideoTrim', (event) => {
42
+ const handleVideoTrimEvent = (event) => {
43
43
  switch (event.name) {
44
44
  case 'onShow': {
45
+ setLoading(false);
45
46
  break;
46
47
  }
47
48
  case 'onHide': {
48
49
  break;
49
50
  }
50
51
  case 'onStartTrimming': {
52
+ // The native side displays "Trimming video..." dialog, so we don't need a React Native loader here
51
53
  break;
52
54
  }
53
55
  case 'onFinishTrimming': {
54
- global.IsBackground = 'true'
55
- UpdateStatusBar()
56
+ global.IsBackground = 'true';
57
+ UpdateStatusBar();
56
58
  navigate("AddDetailsScreen", { media: `${event.outputPath}`, mediaType: 'video', themeColor: themeColor, SDKScreenTitle: SDKScreenTitle, updateParent: updateParent });
57
59
  return;
58
60
  }
59
61
  case 'onCancel': {
60
- UpdateStatusBar()
62
+ UpdateStatusBar();
61
63
  if (Type == "video") {
62
- goToScreenAtIndex(1)
63
- }
64
- else if (Type == "imgReplacedWithVideo") {
65
- goBack()
66
- }
67
- else if (Type == "videoReplacedWithVideo") {
68
- goToScreenAtIndex(3)
64
+ goToScreenAtIndex(1);
65
+ } else if (Type == "imgReplacedWithVideo") {
66
+ goBack();
67
+ } else if (Type == "videoReplacedWithVideo") {
68
+ goToScreenAtIndex(3);
69
69
  }
70
70
  return;
71
- break;
72
71
  }
73
72
  case 'onError': {
73
+ setLoading(false);
74
74
  break;
75
75
  }
76
76
  }
77
- });
77
+ };
78
+
79
+ let subscription;
80
+ if (Platform.OS === 'android') {
81
+ subscription = DeviceEventEmitter.addListener('VideoTrim', handleVideoTrimEvent);
82
+ } else {
83
+ const videoTrimModule = NativeModules.ShakebugSDKVideoTrim || NativeModules.VideoTrim;
84
+ const eventEmitter = new NativeEventEmitter(videoTrimModule);
85
+ subscription = eventEmitter.addListener('VideoTrim', handleVideoTrimEvent);
86
+ }
78
87
 
79
88
  return () => {
80
- subscription.remove();
89
+ if (subscription && subscription.remove) {
90
+ subscription.remove();
91
+ }
81
92
  };
82
93
  }, [])
83
94
 
84
- return;
95
+ return (
96
+ <View style={{ flex: 1, backgroundColor: '#000', justifyContent: 'center', alignItems: 'center' }}>
97
+ <LoadingModal visible={loading} color={ThemeColor} />
98
+ </View>
99
+ );
85
100
  }
86
101
 
87
102
  export default TrimVideoScreen;
package/src/index.tsx CHANGED
@@ -22,10 +22,10 @@ export interface ShakebugViewProps {
22
22
  changeSDKScreenTitle?: string[];
23
23
  allowToReportBugByShakingMobile?: boolean;
24
24
  allowToReportBugByScreenCapture?: boolean;
25
- allowCrashReport: boolean;
26
- makeLogEnabled: boolean;
27
- ShakebugLanguage: 'ENGLISH' | 'HINDI' | 'GUJARATI' | 'ARABIC' | 'CHINESE' | 'DUTCH' | 'FRENCH' | 'GERMAN' | 'GREEK' | 'INDONESIAN' | 'ITALIAN' | 'JAPANESE' | 'KOREAN' | 'RUSSIAN' | 'SPANISH' | 'TURKISH' | 'UKRAINIAN' | 'MARATHI' | 'TAMIL' | 'TELUGU';
28
- setShakebugSDKEndPointURL: string[];
25
+ allowCrashReport?: boolean;
26
+ makeLogEnabled?: boolean;
27
+ ShakebugLanguage?: 'ENGLISH' | 'HINDI' | 'GUJARATI' | 'ARABIC' | 'CHINESE' | 'DUTCH' | 'FRENCH' | 'GERMAN' | 'GREEK' | 'INDONESIAN' | 'ITALIAN' | 'JAPANESE' | 'KOREAN' | 'RUSSIAN' | 'SPANISH' | 'TURKISH' | 'UKRAINIAN' | 'MARATHI' | 'TAMIL' | 'TELUGU';
28
+ setShakebugSDKEndPointURL?: string[];
29
29
  }
30
30
 
31
31
 
@@ -1,13 +1,13 @@
1
1
  import { NativeModules, PermissionsAndroid, Platform } from 'react-native';
2
2
 
3
3
  const LINKING_ERROR =
4
- `The package 'react-native-video-trim' doesn't seem to be linked. Make sure: \n\n` +
4
+ `The native module 'ShakebugSDKVideoTrim' is not linked. Make sure: \n\n` +
5
5
  Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
6
6
  '- You rebuilt the app after installing the package\n' +
7
7
  '- You are not using Expo Go\n';
8
8
 
9
- const VideoTrim = NativeModules.ShakebugSDKVideoTrim
10
- ? NativeModules.ShakebugSDKVideoTrim
9
+ const VideoTrim = NativeModules.ShakebugSDKVideoTrim || NativeModules.VideoTrim
10
+ ? (NativeModules.ShakebugSDKVideoTrim || NativeModules.VideoTrim)
11
11
  : new Proxy(
12
12
  {},
13
13
  {
@@ -21,6 +21,7 @@ export interface EditorConfig {
21
21
  saveToPhoto?: boolean;
22
22
  removeAfterSavedToPhoto?: boolean;
23
23
  maxDuration?: number;
24
+ minDuration?: number;
24
25
  cancelButtonText?: string;
25
26
  saveButtonText?: string;
26
27
  enableCancelDialog?: boolean;
@@ -34,15 +35,9 @@ export interface EditorConfig {
34
35
  saveDialogCancelText?: string;
35
36
  saveDialogConfirmText?: string;
36
37
  trimmingText?: string;
38
+ fullScreenModalIOS?: boolean;
37
39
  }
38
40
 
39
- /**
40
- * Delete a file
41
- *
42
- * @param {string} videoPath: absolute non-empty file path to edit
43
- * @param {EditorConfig} config: editor configuration
44
- * @returns {void} A **Promise** which resolves `void`
45
- */
46
41
  export async function showEditor(
47
42
  filePath: string,
48
43
  config: EditorConfig = {}
@@ -54,19 +49,17 @@ export async function showEditor(
54
49
  const { saveToPhoto = true } = config;
55
50
  const outputPath = await VideoTrim.showEditor(filePath, config);
56
51
 
57
- if (Platform.OS === 'android') {
52
+ if (Platform.OS === 'android' && outputPath) {
58
53
  if (saveToPhoto) {
59
54
  try {
60
55
  if (Platform.Version >= 33) {
61
- // since android 13 it's not needed to request permission for write storage: https://github.com/facebook/react-native/issues/36714#issuecomment-1491338276
62
56
  await VideoTrim.saveVideo(outputPath);
63
-
64
57
  if (config.removeAfterSavedToPhoto) {
65
58
  deleteFile(outputPath);
66
59
  }
67
60
  } else {
68
61
  const granted = await PermissionsAndroid.request(
69
- PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE!,
62
+ PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
70
63
  {
71
64
  title: 'Video Trimmer Photos Access Required',
72
65
  message: 'Grant access to your Photos to write output Video',
@@ -77,65 +70,36 @@ export async function showEditor(
77
70
  );
78
71
  if (granted === PermissionsAndroid.RESULTS.GRANTED) {
79
72
  await VideoTrim.saveVideo(outputPath);
80
-
81
73
  if (config.removeAfterSavedToPhoto) {
82
74
  deleteFile(outputPath);
83
75
  }
84
- } else {
85
- throw new Error('Photos Library permission denied');
86
76
  }
87
77
  }
88
78
  } catch (err) {
89
- throw err;
79
+ console.warn(err);
90
80
  } finally {
91
81
  VideoTrim.hideDialog();
92
82
  }
93
- } else {
94
- VideoTrim.hideDialog();
95
83
  }
96
84
  }
97
85
  }
98
86
 
99
- /**
100
- * Delete a file
101
- *
102
- * @param {string} filePath: absolute non-empty file path to check if editable
103
- * @returns {Promise} A **Promise** which resolves `true` if editable
104
- */
105
87
  export function isValidVideo(filePath: string): Promise<boolean> {
106
- if (!filePath?.trim().length) {
107
- throw new Error('File path cannot be empty!');
108
- }
109
88
  return VideoTrim.isValidVideo(filePath);
110
89
  }
111
90
 
112
- /**
113
- * Clean output files generated at all time
114
- *
115
- * @returns {Promise<string[]>} A **Promise** which resolves to array of files
116
- */
117
91
  export function listFiles(): Promise<string[]> {
118
92
  return VideoTrim.listFiles();
119
93
  }
120
94
 
121
- /**
122
- * Clean output files generated at all time
123
- *
124
- * @returns {Promise} A **Promise** which resolves to number of deleted files
125
- */
126
95
  export function cleanFiles(): Promise<number> {
127
96
  return VideoTrim.cleanFiles();
128
97
  }
129
98
 
130
- /**
131
- * Delete a file
132
- *
133
- * @param {string} filePath: absolute non-empty file path to delete
134
- * @returns {Promise} A **Promise** which resolves `true` if successful
135
- */
136
99
  export function deleteFile(filePath: string): Promise<boolean> {
137
- if (!filePath?.trim().length) {
138
- throw new Error('File path cannot be empty!');
139
- }
140
100
  return VideoTrim.deleteFile(filePath);
141
101
  }
102
+
103
+ export function closeEditor(): void {
104
+ return VideoTrim.hideDialog();
105
+ }
Binary file