react-native-video-trim 1.0.5 → 1.0.6

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/README.md CHANGED
@@ -147,6 +147,9 @@ Main method to show Video Editor UI.
147
147
 
148
148
  - `saveToPhoto` (optional, `default = true`): whether to save video to photo/gallery after editing
149
149
  - `maxDuration` (optional): maximum duration for the trimmed video
150
+ - `leftButtonText` (optional): text for left button in Editor dialog
151
+ - `rightButtonText` (optional): text for right button in Editor dialog
152
+ - `title` (optional, iOS only): title Editor dialog
150
153
 
151
154
  If `saveToPhoto = true`, you must ensure that you have request permission to write to photo/gallery
152
155
  - For Android: you need to have `<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />` in AndroidManifest.xml
@@ -45,7 +45,6 @@ public class VideoTrimModule extends ReactContextBaseJavaModule implements Video
45
45
  private AlertDialog mProgressDialog;
46
46
  private ProgressBar mProgressBar;
47
47
  private Boolean mSaveToPhoto = true;
48
- private int mMaxDuration = 0;
49
48
  private int listenerCount = 0;
50
49
 
51
50
  private Promise showEditorPromise;
@@ -71,9 +70,6 @@ public class VideoTrimModule extends ReactContextBaseJavaModule implements Video
71
70
  if (config.hasKey("saveToPhoto")) {
72
71
  this.mSaveToPhoto = config.getBoolean("saveToPhoto");
73
72
  }
74
- if (config.hasKey("maxDuration")) {
75
- this.mMaxDuration = config.getInt("maxDuration");
76
- }
77
73
 
78
74
  if (!_isValidVideo(videoPath)) {
79
75
  WritableMap map = Arguments.createMap();
@@ -92,7 +88,7 @@ public class VideoTrimModule extends ReactContextBaseJavaModule implements Video
92
88
  // here is NOT main thread, we need to create VideoTrimmerView on UI thread, so that later we can update it using same thread
93
89
 
94
90
  runOnUiThread(() -> {
95
- trimmerView = new VideoTrimmerView(getReactApplicationContext(), mMaxDuration, null);
91
+ trimmerView = new VideoTrimmerView(getReactApplicationContext(), config, null);
96
92
  trimmerView.setOnTrimVideoListener(this);
97
93
  trimmerView.initVideoByURI(Uri.parse(videoPath));
98
94
 
@@ -161,11 +157,7 @@ public class VideoTrimModule extends ReactContextBaseJavaModule implements Video
161
157
  WritableMap map = Arguments.createMap();
162
158
  map.putString("outputPath", in);
163
159
  sendEvent(getReactApplicationContext(), "onFinishTrimming", map);
164
- if (mSaveToPhoto) {
165
- showEditorPromise.resolve(in);
166
- } else {
167
- hideDialog();
168
- }
160
+ showEditorPromise.resolve(in);
169
161
  });
170
162
  }
171
163
 
@@ -22,6 +22,7 @@ import android.widget.FrameLayout;
22
22
  import android.widget.ImageView;
23
23
  import android.widget.LinearLayout;
24
24
  import android.widget.RelativeLayout;
25
+ import android.widget.TextView;
25
26
  import android.widget.Toast;
26
27
 
27
28
  import androidx.appcompat.app.AlertDialog;
@@ -29,6 +30,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
29
30
  import androidx.recyclerview.widget.RecyclerView;
30
31
 
31
32
  import com.facebook.react.bridge.ReactApplicationContext;
33
+ import com.facebook.react.bridge.ReadableMap;
32
34
  import com.videotrim.R;
33
35
  import com.videotrim.adapters.VideoTrimmerAdapter;
34
36
  import com.videotrim.interfaces.IVideoTrimmerView;
@@ -82,19 +84,18 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
82
84
 
83
85
 
84
86
  public VideoTrimmerView(ReactApplicationContext context, AttributeSet attrs) {
85
- this(context, attrs, 0);
87
+ this(context, attrs, 0, null);
86
88
  }
87
- public VideoTrimmerView(ReactApplicationContext context, int maxDuration, AttributeSet attrs) {
88
- this(context, attrs, 0);
89
- this.mMaxDuration = maxDuration;
89
+ public VideoTrimmerView(ReactApplicationContext context, ReadableMap config, AttributeSet attrs) {
90
+ this(context, attrs, 0, config);
90
91
  }
91
92
 
92
- public VideoTrimmerView(ReactApplicationContext context, AttributeSet attrs, int defStyleAttr) {
93
+ public VideoTrimmerView(ReactApplicationContext context, AttributeSet attrs, int defStyleAttr, ReadableMap config) {
93
94
  super(context, attrs, defStyleAttr);
94
- init(context);
95
+ init(context, config);
95
96
  }
96
97
 
97
- private void init(ReactApplicationContext context) {
98
+ private void init(ReactApplicationContext context, ReadableMap config) {
98
99
  this.mContext = context;
99
100
 
100
101
  // listen to onConfigurationChanged doesn't work for this, it runs too soon
@@ -112,6 +113,7 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
112
113
  mVideoThumbRecyclerView.setAdapter(mVideoThumbAdapter);
113
114
  mVideoThumbRecyclerView.addOnScrollListener(mOnScrollListener);
114
115
 
116
+ configure(config);
115
117
  setUpListeners();
116
118
  }
117
119
 
@@ -485,4 +487,20 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
485
487
 
486
488
  return screenWidth;
487
489
  }
490
+
491
+ private void configure(ReadableMap config) {
492
+ if (config.hasKey("maxDuration")) {
493
+ this.mMaxDuration = config.getInt("maxDuration");
494
+ }
495
+
496
+ if (config.hasKey("leftButtonText")) {
497
+ TextView tv = findViewById(R.id.cancelBtn);
498
+ tv.setText(config.getString("leftButtonText"));
499
+ }
500
+
501
+ if (config.hasKey("rightButtonText")) {
502
+ TextView tv = findViewById(R.id.saveBtn);
503
+ tv.setText(config.getString("rightButtonText"));
504
+ }
505
+ }
488
506
  }
@@ -65,6 +65,23 @@ class VideoTrim: RCTEventEmitter, UIVideoEditorControllerDelegate, UINavigationC
65
65
  root.present(editController, animated: true, completion: {
66
66
  self.emitEventToJS("onShow", eventData: nil)
67
67
  self.isShowing = true
68
+
69
+ if let topItem = editController.navigationBar.topItem{
70
+ if let title = config["title"] as? String, !title.isEmpty {
71
+ topItem.title = title
72
+ }
73
+
74
+ // when it comes to bar button customization
75
+ // we can't customize text of original buttons here, we can only set attrs like enabled/hidden
76
+ // to customize text we need to create new button
77
+ if let leftBtnText = config["leftButtonText"] as? String, !leftBtnText.isEmpty {
78
+ topItem.leftBarButtonItem = UIBarButtonItem(title: leftBtnText, style: topItem.leftBarButtonItem?.style ?? .plain, target: topItem.leftBarButtonItem?.target, action: topItem.leftBarButtonItem?.action)
79
+ }
80
+
81
+ if let rightBtnText = config["rightButtonText"] as? String, !rightBtnText.isEmpty {
82
+ topItem.rightBarButtonItem = UIBarButtonItem(title: rightBtnText, style: topItem.rightBarButtonItem?.style ?? .plain, target: topItem.rightBarButtonItem?.target, action: topItem.rightBarButtonItem?.action)
83
+ }
84
+ }
68
85
  })
69
86
  }
70
87
  }
@@ -18,30 +18,36 @@ const VideoTrim = _reactNative.NativeModules.VideoTrim ? _reactNative.NativeModu
18
18
  async function showEditor(videoPath) {
19
19
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
20
20
  const {
21
- maxDuration,
22
21
  saveToPhoto = true
23
22
  } = config;
24
- const outputPath = await VideoTrim.showEditor(videoPath, {
25
- saveToPhoto,
26
- maxDuration
27
- });
28
- if (_reactNative.Platform.OS === 'android' && saveToPhoto) {
29
- try {
30
- const granted = await _reactNative.PermissionsAndroid.request(_reactNative.PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, {
31
- title: 'Video Trimmer Photos Access Required',
32
- message: 'Grant access to your Photos to write output Video',
33
- buttonNeutral: 'Ask Me Later',
34
- buttonNegative: 'Cancel',
35
- buttonPositive: 'OK'
36
- });
37
- if (granted === _reactNative.PermissionsAndroid.RESULTS.GRANTED) {
38
- await VideoTrim.saveVideo(outputPath);
39
- } else {
23
+ const outputPath = await VideoTrim.showEditor(videoPath, config);
24
+ if (_reactNative.Platform.OS === 'android') {
25
+ if (saveToPhoto) {
26
+ try {
27
+ if (_reactNative.Platform.Version >= 33) {
28
+ // since android 13 it's not needed to request permission for write storage: https://github.com/facebook/react-native/issues/36714#issuecomment-1491338276
29
+ await VideoTrim.saveVideo(outputPath);
30
+ } else {
31
+ const granted = await _reactNative.PermissionsAndroid.request(_reactNative.PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, {
32
+ title: 'Video Trimmer Photos Access Required',
33
+ message: 'Grant access to your Photos to write output Video',
34
+ buttonNeutral: 'Ask Me Later',
35
+ buttonNegative: 'Cancel',
36
+ buttonPositive: 'OK'
37
+ });
38
+ if (granted === _reactNative.PermissionsAndroid.RESULTS.GRANTED) {
39
+ await VideoTrim.saveVideo(outputPath);
40
+ } else {
41
+ throw new Error('Photos Library permission denied');
42
+ }
43
+ }
44
+ } catch (err) {
45
+ throw err;
46
+ } finally {
40
47
  VideoTrim.hideDialog();
41
- throw new Error('Photos Library permission denied');
42
48
  }
43
- } catch (err) {
44
- throw err;
49
+ } else {
50
+ VideoTrim.hideDialog();
45
51
  }
46
52
  }
47
53
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","VideoTrim","NativeModules","Proxy","get","Error","showEditor","videoPath","config","arguments","length","undefined","maxDuration","saveToPhoto","outputPath","OS","granted","PermissionsAndroid","request","PERMISSIONS","WRITE_EXTERNAL_STORAGE","title","message","buttonNeutral","buttonNegative","buttonPositive","RESULTS","GRANTED","saveVideo","hideDialog","err","isValidVideo"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAMC,aAAa,GAChB,kFAAiF,GAClFC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,SAAS,GAAGC,0BAAa,CAACD,SAAS,GACrCC,0BAAa,CAACD,SAAS,GACvB,IAAIE,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACT,aAAa,CAAC;EAChC;AACF,CACF,CAAC;AAOE,eAAeU,UAAUA,CAC9BC,SAAiB,EAEF;EAAA,IADfC,MAAoB,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAEzB,MAAM;IAAEG,WAAW;IAAEC,WAAW,GAAG;EAAK,CAAC,GAAGL,MAAM;EAClD,MAAMM,UAAU,GAAG,MAAMb,SAAS,CAACK,UAAU,CAACC,SAAS,EAAE;IACvDM,WAAW;IACXD;EACF,CAAC,CAAC;EAEF,IAAIf,qBAAQ,CAACkB,EAAE,KAAK,SAAS,IAAIF,WAAW,EAAE;IAC5C,IAAI;MACF,MAAMG,OAAO,GAAG,MAAMC,+BAAkB,CAACC,OAAO,CAC9CD,+BAAkB,CAACE,WAAW,CAACC,sBAAsB,EACrD;QACEC,KAAK,EAAE,sCAAsC;QAC7CC,OAAO,EAAE,mDAAmD;QAC5DC,aAAa,EAAE,cAAc;QAC7BC,cAAc,EAAE,QAAQ;QACxBC,cAAc,EAAE;MAClB,CACF,CAAC;MACD,IAAIT,OAAO,KAAKC,+BAAkB,CAACS,OAAO,CAACC,OAAO,EAAE;QAClD,MAAM1B,SAAS,CAAC2B,SAAS,CAACd,UAAU,CAAC;MACvC,CAAC,MAAM;QACLb,SAAS,CAAC4B,UAAU,CAAC,CAAC;QACtB,MAAM,IAAIxB,KAAK,CAAC,kCAAkC,CAAC;MACrD;IACF,CAAC,CAAC,OAAOyB,GAAG,EAAE;MACZ,MAAMA,GAAG;IACX;EACF;AACF;AAEO,SAASC,YAAYA,CAACxB,SAAiB,EAAoB;EAChE,OAAON,SAAS,CAAC8B,YAAY,CAACxB,SAAS,CAAC;AAC1C"}
1
+ {"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","VideoTrim","NativeModules","Proxy","get","Error","showEditor","videoPath","config","arguments","length","undefined","saveToPhoto","outputPath","OS","Version","saveVideo","granted","PermissionsAndroid","request","PERMISSIONS","WRITE_EXTERNAL_STORAGE","title","message","buttonNeutral","buttonNegative","buttonPositive","RESULTS","GRANTED","err","hideDialog","isValidVideo"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAMC,aAAa,GAChB,kFAAiF,GAClFC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,SAAS,GAAGC,0BAAa,CAACD,SAAS,GACrCC,0BAAa,CAACD,SAAS,GACvB,IAAIE,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACT,aAAa,CAAC;EAChC;AACF,CACF,CAAC;AAUE,eAAeU,UAAUA,CAC9BC,SAAiB,EAEF;EAAA,IADfC,MAAoB,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAEzB,MAAM;IAAEG,WAAW,GAAG;EAAK,CAAC,GAAGJ,MAAM;EACrC,MAAMK,UAAU,GAAG,MAAMZ,SAAS,CAACK,UAAU,CAACC,SAAS,EAAEC,MAAM,CAAC;EAEhE,IAAIX,qBAAQ,CAACiB,EAAE,KAAK,SAAS,EAAE;IAC7B,IAAIF,WAAW,EAAE;MACf,IAAI;QACF,IAAIf,qBAAQ,CAACkB,OAAO,IAAI,EAAE,EAAE;UAC1B;UACA,MAAMd,SAAS,CAACe,SAAS,CAACH,UAAU,CAAC;QACvC,CAAC,MAAM;UACL,MAAMI,OAAO,GAAG,MAAMC,+BAAkB,CAACC,OAAO,CAC9CD,+BAAkB,CAACE,WAAW,CAACC,sBAAsB,EACrD;YACEC,KAAK,EAAE,sCAAsC;YAC7CC,OAAO,EAAE,mDAAmD;YAC5DC,aAAa,EAAE,cAAc;YAC7BC,cAAc,EAAE,QAAQ;YACxBC,cAAc,EAAE;UAClB,CACF,CAAC;UACD,IAAIT,OAAO,KAAKC,+BAAkB,CAACS,OAAO,CAACC,OAAO,EAAE;YAClD,MAAM3B,SAAS,CAACe,SAAS,CAACH,UAAU,CAAC;UACvC,CAAC,MAAM;YACL,MAAM,IAAIR,KAAK,CAAC,kCAAkC,CAAC;UACrD;QACF;MACF,CAAC,CAAC,OAAOwB,GAAG,EAAE;QACZ,MAAMA,GAAG;MACX,CAAC,SAAS;QACR5B,SAAS,CAAC6B,UAAU,CAAC,CAAC;MACxB;IACF,CAAC,MAAM;MACL7B,SAAS,CAAC6B,UAAU,CAAC,CAAC;IACxB;EACF;AACF;AAEO,SAASC,YAAYA,CAACxB,SAAiB,EAAoB;EAChE,OAAON,SAAS,CAAC8B,YAAY,CAACxB,SAAS,CAAC;AAC1C"}
@@ -11,30 +11,36 @@ const VideoTrim = NativeModules.VideoTrim ? NativeModules.VideoTrim : new Proxy(
11
11
  export async function showEditor(videoPath) {
12
12
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
13
13
  const {
14
- maxDuration,
15
14
  saveToPhoto = true
16
15
  } = config;
17
- const outputPath = await VideoTrim.showEditor(videoPath, {
18
- saveToPhoto,
19
- maxDuration
20
- });
21
- if (Platform.OS === 'android' && saveToPhoto) {
22
- try {
23
- const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, {
24
- title: 'Video Trimmer Photos Access Required',
25
- message: 'Grant access to your Photos to write output Video',
26
- buttonNeutral: 'Ask Me Later',
27
- buttonNegative: 'Cancel',
28
- buttonPositive: 'OK'
29
- });
30
- if (granted === PermissionsAndroid.RESULTS.GRANTED) {
31
- await VideoTrim.saveVideo(outputPath);
32
- } else {
16
+ const outputPath = await VideoTrim.showEditor(videoPath, config);
17
+ if (Platform.OS === 'android') {
18
+ if (saveToPhoto) {
19
+ try {
20
+ if (Platform.Version >= 33) {
21
+ // since android 13 it's not needed to request permission for write storage: https://github.com/facebook/react-native/issues/36714#issuecomment-1491338276
22
+ await VideoTrim.saveVideo(outputPath);
23
+ } else {
24
+ const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, {
25
+ title: 'Video Trimmer Photos Access Required',
26
+ message: 'Grant access to your Photos to write output Video',
27
+ buttonNeutral: 'Ask Me Later',
28
+ buttonNegative: 'Cancel',
29
+ buttonPositive: 'OK'
30
+ });
31
+ if (granted === PermissionsAndroid.RESULTS.GRANTED) {
32
+ await VideoTrim.saveVideo(outputPath);
33
+ } else {
34
+ throw new Error('Photos Library permission denied');
35
+ }
36
+ }
37
+ } catch (err) {
38
+ throw err;
39
+ } finally {
33
40
  VideoTrim.hideDialog();
34
- throw new Error('Photos Library permission denied');
35
41
  }
36
- } catch (err) {
37
- throw err;
42
+ } else {
43
+ VideoTrim.hideDialog();
38
44
  }
39
45
  }
40
46
  }
@@ -1 +1 @@
1
- {"version":3,"names":["NativeModules","PermissionsAndroid","Platform","LINKING_ERROR","select","ios","default","VideoTrim","Proxy","get","Error","showEditor","videoPath","config","arguments","length","undefined","maxDuration","saveToPhoto","outputPath","OS","granted","request","PERMISSIONS","WRITE_EXTERNAL_STORAGE","title","message","buttonNeutral","buttonNegative","buttonPositive","RESULTS","GRANTED","saveVideo","hideDialog","err","isValidVideo"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,aAAa,EAAEC,kBAAkB,EAAEC,QAAQ,QAAQ,cAAc;AAE1E,MAAMC,aAAa,GAChB,kFAAiF,GAClFD,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,SAAS,GAAGP,aAAa,CAACO,SAAS,GACrCP,aAAa,CAACO,SAAS,GACvB,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC;AAOL,OAAO,eAAeQ,UAAUA,CAC9BC,SAAiB,EAEF;EAAA,IADfC,MAAoB,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAEzB,MAAM;IAAEG,WAAW;IAAEC,WAAW,GAAG;EAAK,CAAC,GAAGL,MAAM;EAClD,MAAMM,UAAU,GAAG,MAAMZ,SAAS,CAACI,UAAU,CAACC,SAAS,EAAE;IACvDM,WAAW;IACXD;EACF,CAAC,CAAC;EAEF,IAAIf,QAAQ,CAACkB,EAAE,KAAK,SAAS,IAAIF,WAAW,EAAE;IAC5C,IAAI;MACF,MAAMG,OAAO,GAAG,MAAMpB,kBAAkB,CAACqB,OAAO,CAC9CrB,kBAAkB,CAACsB,WAAW,CAACC,sBAAsB,EACrD;QACEC,KAAK,EAAE,sCAAsC;QAC7CC,OAAO,EAAE,mDAAmD;QAC5DC,aAAa,EAAE,cAAc;QAC7BC,cAAc,EAAE,QAAQ;QACxBC,cAAc,EAAE;MAClB,CACF,CAAC;MACD,IAAIR,OAAO,KAAKpB,kBAAkB,CAAC6B,OAAO,CAACC,OAAO,EAAE;QAClD,MAAMxB,SAAS,CAACyB,SAAS,CAACb,UAAU,CAAC;MACvC,CAAC,MAAM;QACLZ,SAAS,CAAC0B,UAAU,CAAC,CAAC;QACtB,MAAM,IAAIvB,KAAK,CAAC,kCAAkC,CAAC;MACrD;IACF,CAAC,CAAC,OAAOwB,GAAG,EAAE;MACZ,MAAMA,GAAG;IACX;EACF;AACF;AAEA,OAAO,SAASC,YAAYA,CAACvB,SAAiB,EAAoB;EAChE,OAAOL,SAAS,CAAC4B,YAAY,CAACvB,SAAS,CAAC;AAC1C"}
1
+ {"version":3,"names":["NativeModules","PermissionsAndroid","Platform","LINKING_ERROR","select","ios","default","VideoTrim","Proxy","get","Error","showEditor","videoPath","config","arguments","length","undefined","saveToPhoto","outputPath","OS","Version","saveVideo","granted","request","PERMISSIONS","WRITE_EXTERNAL_STORAGE","title","message","buttonNeutral","buttonNegative","buttonPositive","RESULTS","GRANTED","err","hideDialog","isValidVideo"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,aAAa,EAAEC,kBAAkB,EAAEC,QAAQ,QAAQ,cAAc;AAE1E,MAAMC,aAAa,GAChB,kFAAiF,GAClFD,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,SAAS,GAAGP,aAAa,CAACO,SAAS,GACrCP,aAAa,CAACO,SAAS,GACvB,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC;AAUL,OAAO,eAAeQ,UAAUA,CAC9BC,SAAiB,EAEF;EAAA,IADfC,MAAoB,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAEzB,MAAM;IAAEG,WAAW,GAAG;EAAK,CAAC,GAAGJ,MAAM;EACrC,MAAMK,UAAU,GAAG,MAAMX,SAAS,CAACI,UAAU,CAACC,SAAS,EAAEC,MAAM,CAAC;EAEhE,IAAIX,QAAQ,CAACiB,EAAE,KAAK,SAAS,EAAE;IAC7B,IAAIF,WAAW,EAAE;MACf,IAAI;QACF,IAAIf,QAAQ,CAACkB,OAAO,IAAI,EAAE,EAAE;UAC1B;UACA,MAAMb,SAAS,CAACc,SAAS,CAACH,UAAU,CAAC;QACvC,CAAC,MAAM;UACL,MAAMI,OAAO,GAAG,MAAMrB,kBAAkB,CAACsB,OAAO,CAC9CtB,kBAAkB,CAACuB,WAAW,CAACC,sBAAsB,EACrD;YACEC,KAAK,EAAE,sCAAsC;YAC7CC,OAAO,EAAE,mDAAmD;YAC5DC,aAAa,EAAE,cAAc;YAC7BC,cAAc,EAAE,QAAQ;YACxBC,cAAc,EAAE;UAClB,CACF,CAAC;UACD,IAAIR,OAAO,KAAKrB,kBAAkB,CAAC8B,OAAO,CAACC,OAAO,EAAE;YAClD,MAAMzB,SAAS,CAACc,SAAS,CAACH,UAAU,CAAC;UACvC,CAAC,MAAM;YACL,MAAM,IAAIR,KAAK,CAAC,kCAAkC,CAAC;UACrD;QACF;MACF,CAAC,CAAC,OAAOuB,GAAG,EAAE;QACZ,MAAMA,GAAG;MACX,CAAC,SAAS;QACR1B,SAAS,CAAC2B,UAAU,CAAC,CAAC;MACxB;IACF,CAAC,MAAM;MACL3B,SAAS,CAAC2B,UAAU,CAAC,CAAC;IACxB;EACF;AACF;AAEA,OAAO,SAASC,YAAYA,CAACvB,SAAiB,EAAoB;EAChE,OAAOL,SAAS,CAAC4B,YAAY,CAACvB,SAAS,CAAC;AAC1C"}
@@ -1,6 +1,9 @@
1
1
  export interface EditorConfig {
2
2
  saveToPhoto?: boolean;
3
3
  maxDuration?: number;
4
+ title?: string;
5
+ leftButtonText?: string;
6
+ rightButtonText?: string;
4
7
  }
5
8
  export declare function showEditor(videoPath: string, config?: EditorConfig): Promise<void>;
6
9
  export declare function isValidVideo(videoPath: string): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAmBA,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,YAAiB,GACxB,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEhE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAmBA,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,YAAiB,GACxB,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEhE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-video-trim",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Video trimmer for your React Native app",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
package/src/index.tsx CHANGED
@@ -20,38 +20,48 @@ const VideoTrim = NativeModules.VideoTrim
20
20
  export interface EditorConfig {
21
21
  saveToPhoto?: boolean;
22
22
  maxDuration?: number;
23
+ title?: string;
24
+ leftButtonText?: string;
25
+ rightButtonText?: string;
23
26
  }
24
27
 
25
28
  export async function showEditor(
26
29
  videoPath: string,
27
30
  config: EditorConfig = {}
28
31
  ): Promise<void> {
29
- const { maxDuration, saveToPhoto = true } = config;
30
- const outputPath = await VideoTrim.showEditor(videoPath, {
31
- saveToPhoto,
32
- maxDuration,
33
- });
32
+ const { saveToPhoto = true } = config;
33
+ const outputPath = await VideoTrim.showEditor(videoPath, config);
34
34
 
35
- if (Platform.OS === 'android' && saveToPhoto) {
36
- try {
37
- const granted = await PermissionsAndroid.request(
38
- PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE!,
39
- {
40
- title: 'Video Trimmer Photos Access Required',
41
- message: 'Grant access to your Photos to write output Video',
42
- buttonNeutral: 'Ask Me Later',
43
- buttonNegative: 'Cancel',
44
- buttonPositive: 'OK',
35
+ if (Platform.OS === 'android') {
36
+ if (saveToPhoto) {
37
+ try {
38
+ if (Platform.Version >= 33) {
39
+ // since android 13 it's not needed to request permission for write storage: https://github.com/facebook/react-native/issues/36714#issuecomment-1491338276
40
+ await VideoTrim.saveVideo(outputPath);
41
+ } else {
42
+ const granted = await PermissionsAndroid.request(
43
+ PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE!,
44
+ {
45
+ title: 'Video Trimmer Photos Access Required',
46
+ message: 'Grant access to your Photos to write output Video',
47
+ buttonNeutral: 'Ask Me Later',
48
+ buttonNegative: 'Cancel',
49
+ buttonPositive: 'OK',
50
+ }
51
+ );
52
+ if (granted === PermissionsAndroid.RESULTS.GRANTED) {
53
+ await VideoTrim.saveVideo(outputPath);
54
+ } else {
55
+ throw new Error('Photos Library permission denied');
56
+ }
45
57
  }
46
- );
47
- if (granted === PermissionsAndroid.RESULTS.GRANTED) {
48
- await VideoTrim.saveVideo(outputPath);
49
- } else {
58
+ } catch (err) {
59
+ throw err;
60
+ } finally {
50
61
  VideoTrim.hideDialog();
51
- throw new Error('Photos Library permission denied');
52
62
  }
53
- } catch (err) {
54
- throw err;
63
+ } else {
64
+ VideoTrim.hideDialog();
55
65
  }
56
66
  }
57
67
  }