react-native-video-trim 7.0.1 → 7.1.0

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
@@ -12,6 +12,7 @@
12
12
  * [Behavior Options](#behavior-options)
13
13
  - [Platform Setup](#platform-setup)
14
14
  - [Advanced Features](#advanced-features)
15
+ * [Theming](#theming)
15
16
  * [Audio Trimming](#audio-trimming)
16
17
  * [Remote Files (HTTPS)](#remote-files-https)
17
18
  * [Video Transforms (Flip, Rotate, Crop)](#video-transforms-flip-rotate-crop)
@@ -24,8 +25,7 @@
24
25
  <div align="center">
25
26
  <h2>📱 Professional video trimmer for React Native apps</h2>
26
27
 
27
- <img src="images/android.gif" width="300" />
28
- <img src="images/ios.gif" width="300" />
28
+ <img src="images/ios.png" width="300" />
29
29
 
30
30
  <p>
31
31
  <strong>✅ iOS & Android</strong> •
@@ -48,6 +48,7 @@ A powerful, easy-to-use video and audio trimming library for React Native applic
48
48
  - **✅ File Validation** - Built-in validation for media files
49
49
  - **🗂️ File Management** - List, clean up, and delete specific files
50
50
  - **🔄 Universal Architecture** - Works with both New and Old React Native architectures
51
+ - **🎨 Dark & Light Theme** - Built-in dark and light theme support
51
52
 
52
53
  ### 🎛️ Core Capabilities
53
54
 
@@ -60,6 +61,7 @@ A powerful, easy-to-use video and audio trimming library for React Native applic
60
61
  | **Save Options** | Photos, Documents, Share sheet integration |
61
62
  | **File Management** | Complete file lifecycle management |
62
63
  | **Customization** | Extensive UI and behavior customization |
64
+ | **Theming** | Dark and light theme with automatic color adaptation |
63
65
 
64
66
  <div align="center">
65
67
  <img src="images/document_picker.png" width="250" />
@@ -282,14 +284,15 @@ All configuration options are optional. Here are the most commonly used ones:
282
284
 
283
285
  | Option | Type | Default | Description |
284
286
  |--------|------|---------|-------------|
287
+ | `theme` | `'dark' \| 'light'` | `'dark'` | Editor color theme (see [Theming](#theming)) |
285
288
  | `cancelButtonText` | `string` | `"Cancel"` | Cancel button text |
286
289
  | `saveButtonText` | `string` | `"Save"` | Save button text |
287
290
  | `trimmingText` | `string` | `"Trimming video..."` | Progress dialog text |
288
291
  | `headerText` | `string` | - | Header text |
289
292
  | `headerTextSize` | `number` | `16` | Header text size |
290
- | `headerTextColor` | `string` | - | Header text color |
293
+ | `headerTextColor` | `string` | - | Header text color (defaults to black in light theme, white in dark theme) |
291
294
  | `trimmerColor` | `string` | - | Trimmer bar color |
292
- | `handleIconColor` | `string` | - | Trimmer left/right handles color |
295
+ | `handleIconColor` | `string` | - | Trimmer left/right handles color (defaults to black in light theme, white in dark theme) |
293
296
  | `fullScreenModalIOS` | `boolean` | `false` | Use fullscreen modal on iOS |
294
297
 
295
298
  ### Dialog Options
@@ -367,6 +370,7 @@ showEditor(videoPath, {
367
370
  removeAfterSavedToPhoto: true,
368
371
 
369
372
  // UI customization
373
+ theme: 'light',
370
374
  headerText: "Trim Your Video",
371
375
  cancelButtonText: "Back",
372
376
  saveButtonText: "Done",
@@ -398,6 +402,34 @@ buildscript {
398
402
 
399
403
  ## Advanced Features
400
404
 
405
+ ### Theming
406
+
407
+ The editor supports dark and light themes. Set the `theme` option to switch between them:
408
+
409
+ ```javascript
410
+ // Light theme
411
+ showEditor(videoUrl, {
412
+ theme: 'light',
413
+ });
414
+
415
+ // Dark theme (default)
416
+ showEditor(videoUrl, {
417
+ theme: 'dark',
418
+ });
419
+ ```
420
+
421
+ | | Dark (default) | Light |
422
+ |---|---|---|
423
+ | **Background** | Black | White |
424
+ | **Icons & text** | White | Black |
425
+ | **Cancel/Save text** | White | Black |
426
+ | **Crop brackets & grid** | White | Black |
427
+ | **Progress indicator** | White | White |
428
+ | **Trimmer handle chevrons** | White | White |
429
+ | **Dialogs** | Dark style | Light style |
430
+
431
+ The `headerTextColor` and `handleIconColor` options automatically adapt to the active theme but can still be overridden explicitly.
432
+
401
433
  ### Audio Trimming
402
434
 
403
435
  <div align="center">
@@ -6,8 +6,6 @@ import android.graphics.Color
6
6
  import android.graphics.Paint
7
7
  import android.graphics.Path
8
8
  import android.graphics.RectF
9
- import android.graphics.Region
10
- import android.os.Build
11
9
  import android.util.AttributeSet
12
10
  import android.util.TypedValue
13
11
  import android.view.MotionEvent
@@ -46,6 +44,16 @@ class CropOverlayView @JvmOverloads constructor(
46
44
  var onCropBegan: (() -> Unit)? = null
47
45
  var onCropEnded: (() -> Unit)? = null
48
46
 
47
+ var isLightTheme = false
48
+ set(value) {
49
+ field = value
50
+ val c = if (value) Color.BLACK else Color.WHITE
51
+ borderPaint.color = c
52
+ gridPaint.color = c
53
+ cornerPaint.color = c
54
+ invalidate()
55
+ }
56
+
49
57
  private val minCropSize = dpToPx(60f)
50
58
  private val borderWidth = dpToPx(1f)
51
59
  private val cornerLength = dpToPx(20f)
@@ -71,10 +79,6 @@ class CropOverlayView @JvmOverloads constructor(
71
79
  strokeCap = Paint.Cap.ROUND
72
80
  strokeJoin = Paint.Join.ROUND
73
81
  }
74
- private val dimmingPaint = Paint().apply {
75
- color = Color.argb(140, 0, 0, 0)
76
- style = Paint.Style.FILL
77
- }
78
82
 
79
83
  private enum class DragEdge {
80
84
  TOP, BOTTOM, LEFT, RIGHT,
@@ -128,8 +132,6 @@ class CropOverlayView @JvmOverloads constructor(
128
132
  if (cropRect.isEmpty) return
129
133
  val cr = cropRect
130
134
 
131
- drawDimming(canvas, cr)
132
-
133
135
  canvas.drawRect(cr, borderPaint)
134
136
 
135
137
  for (i in 1..2) {
@@ -163,22 +165,6 @@ class CropOverlayView @JvmOverloads constructor(
163
165
  canvas.drawPath(path, cornerPaint)
164
166
  }
165
167
 
166
- private fun drawDimming(canvas: Canvas, cr: RectF) {
167
- canvas.save()
168
- val fullPath = Path()
169
- fullPath.addRect(0f, 0f, width.toFloat(), height.toFloat(), Path.Direction.CW)
170
- val cropPath = Path()
171
- cropPath.addRect(cr, Path.Direction.CW)
172
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
173
- fullPath.op(cropPath, Path.Op.DIFFERENCE)
174
- canvas.drawPath(fullPath, dimmingPaint)
175
- } else {
176
- @Suppress("DEPRECATION")
177
- canvas.clipPath(cropPath, Region.Op.DIFFERENCE)
178
- canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), dimmingPaint)
179
- }
180
- canvas.restore()
181
- }
182
168
 
183
169
  override fun onTouchEvent(event: MotionEvent): Boolean {
184
170
  if (event.pointerCount > 1) {
@@ -181,6 +181,9 @@ class VideoTrimmerView(
181
181
 
182
182
  private var trimmerColor = context.getString(R.string.trim_color).toColorInt()
183
183
  private var handleIconColor = Color.BLACK
184
+ private var isLightTheme = false
185
+ private val iconColor: Int get() = if (isLightTheme) Color.BLACK else Color.WHITE
186
+ private val dimmedIconColor: Int get() = if (isLightTheme) Color.argb(128, 0, 0, 0) else Color.argb(128, 255, 255, 255)
184
187
  private lateinit var leadingChevron: ImageView
185
188
  private lateinit var trailingChevron: ImageView
186
189
 
@@ -266,10 +269,19 @@ class VideoTrimmerView(
266
269
  }
267
270
  mVideoView.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
268
271
  override fun onSurfaceTextureAvailable(st: SurfaceTexture, w: Int, h: Int) {
269
- setupVideoPlayer(st, videoURI)
272
+ val mp = mediaPlayer
273
+ if (mp != null) {
274
+ videoSurface?.release()
275
+ videoSurface = Surface(st)
276
+ mp.setSurface(videoSurface)
277
+ } else {
278
+ setupVideoPlayer(st, videoURI)
279
+ }
270
280
  }
271
281
  override fun onSurfaceTextureSizeChanged(st: SurfaceTexture, w: Int, h: Int) {}
272
- override fun onSurfaceTextureDestroyed(st: SurfaceTexture): Boolean = true
282
+ override fun onSurfaceTextureDestroyed(st: SurfaceTexture): Boolean {
283
+ return false
284
+ }
273
285
  override fun onSurfaceTextureUpdated(st: SurfaceTexture) {}
274
286
  }
275
287
  } else {
@@ -525,9 +537,9 @@ class VideoTrimmerView(
525
537
  undoBtn.setOnClickListener { onUndoTapped() }
526
538
  redoBtn.setOnClickListener { onRedoTapped() }
527
539
 
528
- cropBtn.setColorFilter(Color.argb(128, 255, 255, 255), android.graphics.PorterDuff.Mode.SRC_IN)
529
- undoBtn.setColorFilter(Color.argb(128, 255, 255, 255), android.graphics.PorterDuff.Mode.SRC_IN)
530
- redoBtn.setColorFilter(Color.argb(128, 255, 255, 255), android.graphics.PorterDuff.Mode.SRC_IN)
540
+ cropBtn.setColorFilter(dimmedIconColor, android.graphics.PorterDuff.Mode.SRC_IN)
541
+ undoBtn.setColorFilter(dimmedIconColor, android.graphics.PorterDuff.Mode.SRC_IN)
542
+ redoBtn.setColorFilter(dimmedIconColor, android.graphics.PorterDuff.Mode.SRC_IN)
531
543
  }
532
544
 
533
545
  fun onSaveClicked() {
@@ -642,6 +654,8 @@ class VideoTrimmerView(
642
654
  mMinDuration = maxOf(1000L, config.getDouble("minDuration").toLong())
643
655
  }
644
656
 
657
+ isLightTheme = config.hasKey("theme") && config.getString("theme") == "light"
658
+
645
659
  cancelBtn.text = config.getString("cancelButtonText")
646
660
  saveBtn.text = config.getString("saveButtonText")
647
661
  isVideoType = config.hasKey("type") && config.getString("type") == "video"
@@ -682,9 +696,10 @@ class VideoTrimmerView(
682
696
  trimmerColor = if (config.hasKey("trimmerColor")) config.getInt("trimmerColor") else context.getString(
683
697
  R.string.trim_color
684
698
  ).toColorInt()
685
- handleIconColor = if (config.hasKey("handleIconColor")) config.getInt("handleIconColor") else Color.BLACK
699
+ handleIconColor = if (config.hasKey("handleIconColor")) config.getInt("handleIconColor") else (if (isLightTheme) Color.WHITE else Color.BLACK)
686
700
 
687
701
  applyTrimmerColor()
702
+ applyThemeColors()
688
703
  }
689
704
 
690
705
  private fun applyTrimmerColor() {
@@ -713,6 +728,39 @@ class VideoTrimmerView(
713
728
  trailingChevron.setColorFilter(handleIconColor, android.graphics.PorterDuff.Mode.SRC_IN)
714
729
  }
715
730
 
731
+ private fun applyThemeColors() {
732
+ val bgColor = if (isLightTheme) Color.WHITE else Color.BLACK
733
+ val textColor = if (isLightTheme) Color.BLACK else Color.WHITE
734
+ val overlayColor = if (isLightTheme) Color.argb(153, 255, 255, 255) else Color.argb(191, 0, 0, 0)
735
+
736
+ // Backgrounds
737
+ (findViewById<View>(R.id.layout) as? RelativeLayout)?.setBackgroundColor(bgColor)
738
+ headerView.setBackgroundColor(bgColor)
739
+ transformRow.setBackgroundColor(bgColor)
740
+ videoContainer.setBackgroundColor(bgColor)
741
+
742
+ // Text colors
743
+ cancelBtn.setTextColor(iconColor)
744
+ startTimeText.setTextColor(textColor)
745
+ currentTimeText.setTextColor(textColor)
746
+ endTimeText.setTextColor(textColor)
747
+
748
+ // Play icon
749
+ mPlayView.setColorFilter(iconColor, android.graphics.PorterDuff.Mode.SRC_IN)
750
+
751
+ // Transform toolbar icons
752
+ flipBtn.setColorFilter(iconColor, android.graphics.PorterDuff.Mode.SRC_IN)
753
+ rotateBtn.setColorFilter(iconColor, android.graphics.PorterDuff.Mode.SRC_IN)
754
+ cropBtn.setColorFilter(dimmedIconColor, android.graphics.PorterDuff.Mode.SRC_IN)
755
+ undoBtn.setColorFilter(dimmedIconColor, android.graphics.PorterDuff.Mode.SRC_IN)
756
+ redoBtn.setColorFilter(dimmedIconColor, android.graphics.PorterDuff.Mode.SRC_IN)
757
+
758
+ // Overlays
759
+ leadingOverlay.setBackgroundColor(overlayColor)
760
+ trailingOverlay.setBackgroundColor(overlayColor)
761
+
762
+ }
763
+
716
764
  private fun dpToPx(dp: Int): Int {
717
765
  return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), resources.displayMetrics).toInt()
718
766
  }
@@ -925,9 +973,14 @@ class VideoTrimmerView(
925
973
  var newX = event.rawX - view.width.toFloat() / 2
926
974
 
927
975
  if (isLeading) {
976
+ val unclamped = newX
928
977
  newX = maxOf(0f, minOf(newX, trailingHandle.x - view.width))
978
+ if (unclamped < 0f) didClamp = true
929
979
  } else {
930
- newX = minOf(trimmerContainerBg.width.toFloat() + view.width, maxOf(newX, leadingHandle.x + view.width))
980
+ val unclamped = newX
981
+ val maxX = trimmerContainerBg.width.toFloat() + view.width
982
+ newX = minOf(maxX, maxOf(newX, leadingHandle.x + view.width))
983
+ if (unclamped > maxX) didClamp = true
931
984
  }
932
985
 
933
986
  view.x = newX
@@ -1071,7 +1124,8 @@ class VideoTrimmerView(
1071
1124
 
1072
1125
  private fun playHapticFeedback(isLight: Boolean) {
1073
1126
  if (vibrator != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && enableHapticFeedback) {
1074
- vibrator!!.vibrate(VibrationEffect.createOneShot(if (isLight) 10L else 25L, VibrationEffect.DEFAULT_AMPLITUDE))
1127
+ val amplitude = if (isLight) 30 else 80
1128
+ vibrator!!.vibrate(VibrationEffect.createOneShot(if (isLight) 8L else 15L, amplitude))
1075
1129
  }
1076
1130
  }
1077
1131
 
@@ -1320,7 +1374,7 @@ class VideoTrimmerView(
1320
1374
  (videoContainer.height - videoContainer.paddingTop - videoContainer.paddingBottom).toFloat()
1321
1375
 
1322
1376
  private fun bracketOverflow(): Int =
1323
- TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4f, resources.displayMetrics).toInt()
1377
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8f, resources.displayMetrics).toInt()
1324
1378
 
1325
1379
  private fun onFlipTapped() {
1326
1380
  pushUndo()
@@ -1329,7 +1383,12 @@ class VideoTrimmerView(
1329
1383
  val fitScale = if (rotationCount % 2 != 0) {
1330
1384
  val cw = containerContentWidth()
1331
1385
  val ch = containerContentHeight()
1332
- if (cw > 0 && ch > 0) minOf(cw / ch, ch / cw) else 1f
1386
+ val vw = mVideoView.width.toFloat()
1387
+ val vh = mVideoView.height.toFloat()
1388
+ val margin = bracketOverflow().toFloat()
1389
+ val availW = cw - 2 * margin
1390
+ val availH = ch - 2 * margin
1391
+ if (availW > 0 && availH > 0 && vw > 0 && vh > 0) minOf(availW / vh, availH / vw) else 1f
1333
1392
  } else {
1334
1393
  1f
1335
1394
  }
@@ -1402,12 +1461,24 @@ class VideoTrimmerView(
1402
1461
  if (cw <= 0 || ch <= 0) return
1403
1462
 
1404
1463
  val fitScale = if (rotationCount % 2 != 0) {
1405
- minOf(cw / ch, ch / cw)
1464
+ val vw = mVideoView.width.toFloat()
1465
+ val vh = mVideoView.height.toFloat()
1466
+ val margin = bracketOverflow().toFloat()
1467
+ val availW = cw - 2 * margin
1468
+ val availH = ch - 2 * margin
1469
+ if (vw > 0 && vh > 0 && availW > 0 && availH > 0) minOf(availW / vh, availH / vw) else 1f
1406
1470
  } else {
1407
1471
  1f
1408
1472
  }
1409
1473
  val flipMul = if (isFlipped) -1f else 1f
1410
1474
 
1475
+ if (isCropActive) {
1476
+ cropOverlay?.animate()
1477
+ ?.alpha(0f)
1478
+ ?.setDuration(125)
1479
+ ?.start()
1480
+ }
1481
+
1411
1482
  mVideoView.animate()
1412
1483
  .scaleX(flipMul * fitScale)
1413
1484
  .scaleY(fitScale)
@@ -1418,6 +1489,10 @@ class VideoTrimmerView(
1418
1489
  if (resetCrop && isCropActive) {
1419
1490
  updateCropAllowedRect()
1420
1491
  cropOverlay?.resetCrop()
1492
+ cropOverlay?.animate()
1493
+ ?.alpha(1f)
1494
+ ?.setDuration(125)
1495
+ ?.start()
1421
1496
  }
1422
1497
  }
1423
1498
  .start()
@@ -1430,7 +1505,7 @@ class VideoTrimmerView(
1430
1505
  private fun onCropTapped() {
1431
1506
  isCropActive = !isCropActive
1432
1507
  cropBtn.setColorFilter(
1433
- if (isCropActive) Color.WHITE else Color.argb(128, 255, 255, 255),
1508
+ if (isCropActive) iconColor else dimmedIconColor,
1434
1509
  android.graphics.PorterDuff.Mode.SRC_IN
1435
1510
  )
1436
1511
  playHapticFeedback(true)
@@ -1440,6 +1515,7 @@ class VideoTrimmerView(
1440
1515
  private fun showCropOverlay() {
1441
1516
  hideCropOverlayImmediate()
1442
1517
  val overlay = CropOverlayView(mContext)
1518
+ overlay.isLightTheme = isLightTheme
1443
1519
  overlay.layoutParams = FrameLayout.LayoutParams(
1444
1520
  FrameLayout.LayoutParams.MATCH_PARENT,
1445
1521
  FrameLayout.LayoutParams.MATCH_PARENT
@@ -1475,6 +1551,7 @@ class VideoTrimmerView(
1475
1551
  private fun showCropOverlayImmediate() {
1476
1552
  hideCropOverlayImmediate()
1477
1553
  val overlay = CropOverlayView(mContext)
1554
+ overlay.isLightTheme = isLightTheme
1478
1555
  overlay.layoutParams = FrameLayout.LayoutParams(
1479
1556
  FrameLayout.LayoutParams.MATCH_PARENT,
1480
1557
  FrameLayout.LayoutParams.MATCH_PARENT
@@ -1519,8 +1596,11 @@ class VideoTrimmerView(
1519
1596
 
1520
1597
  val pivotX = cw / 2f
1521
1598
  val pivotY = ch / 2f
1599
+ val margin = bracketOverflow().toFloat()
1600
+ val availW = cw - 2 * margin
1601
+ val availH = ch - 2 * margin
1522
1602
  val fitScale = if (rotationCount % 2 != 0) {
1523
- minOf(cw / ch, ch / cw)
1603
+ if (tvW > 0 && tvH > 0 && availW > 0 && availH > 0) minOf(availW / tvH, availH / tvW) else 1f
1524
1604
  } else {
1525
1605
  1f
1526
1606
  }
@@ -1623,8 +1703,13 @@ class VideoTrimmerView(
1623
1703
 
1624
1704
  val cw = containerContentWidth()
1625
1705
  val ch = containerContentHeight()
1626
- val fitScale = if (rotationCount % 2 != 0 && cw > 0 && ch > 0) {
1627
- minOf(cw / ch, ch / cw)
1706
+ val vw = mVideoView.width.toFloat()
1707
+ val vh = mVideoView.height.toFloat()
1708
+ val margin = bracketOverflow().toFloat()
1709
+ val availW = cw - 2 * margin
1710
+ val availH = ch - 2 * margin
1711
+ val fitScale = if (rotationCount % 2 != 0 && availW > 0 && availH > 0 && vw > 0 && vh > 0) {
1712
+ minOf(availW / vh, availH / vw)
1628
1713
  } else {
1629
1714
  1f
1630
1715
  }
@@ -1634,17 +1719,14 @@ class VideoTrimmerView(
1634
1719
  val onComplete = Runnable {
1635
1720
  if (snap.isCropActive) {
1636
1721
  isCropActive = true
1637
- cropBtn.setColorFilter(Color.WHITE, android.graphics.PorterDuff.Mode.SRC_IN)
1722
+ cropBtn.setColorFilter(iconColor, android.graphics.PorterDuff.Mode.SRC_IN)
1638
1723
  showCropOverlayImmediate()
1639
1724
  updateCropAllowedRect()
1640
1725
  val norm = snap.cropNormalized
1641
1726
  if (norm != null) setCropFromNormalized(norm) else cropOverlay?.resetCrop()
1642
1727
  } else {
1643
1728
  isCropActive = false
1644
- cropBtn.setColorFilter(
1645
- Color.argb(128, 255, 255, 255),
1646
- android.graphics.PorterDuff.Mode.SRC_IN
1647
- )
1729
+ cropBtn.setColorFilter(dimmedIconColor, android.graphics.PorterDuff.Mode.SRC_IN)
1648
1730
  hideCropOverlayImmediate()
1649
1731
  }
1650
1732
  }
@@ -1698,16 +1780,14 @@ class VideoTrimmerView(
1698
1780
  }
1699
1781
 
1700
1782
  private fun updateUndoRedoButtons() {
1701
- val dimmed = Color.argb(128, 255, 255, 255)
1702
- val active = Color.WHITE
1703
1783
  undoBtn.isEnabled = undoStack.isNotEmpty()
1704
1784
  undoBtn.setColorFilter(
1705
- if (undoStack.isNotEmpty()) active else dimmed,
1785
+ if (undoStack.isNotEmpty()) iconColor else dimmedIconColor,
1706
1786
  android.graphics.PorterDuff.Mode.SRC_IN
1707
1787
  )
1708
1788
  redoBtn.isEnabled = redoStack.isNotEmpty()
1709
1789
  redoBtn.setColorFilter(
1710
- if (redoStack.isNotEmpty()) active else dimmed,
1790
+ if (redoStack.isNotEmpty()) iconColor else dimmedIconColor,
1711
1791
  android.graphics.PorterDuff.Mode.SRC_IN
1712
1792
  )
1713
1793
  }
@@ -26,6 +26,10 @@ class CropOverlayView: UIView {
26
26
  var onCropBegan: (() -> Void)?
27
27
  var onCropEnded: (() -> Void)?
28
28
 
29
+ var isLightTheme = false {
30
+ didSet { setNeedsDisplay() }
31
+ }
32
+
29
33
  private let minCropSize: CGFloat = 60
30
34
  private let borderWidth: CGFloat = 1.0
31
35
  private let cornerLength: CGFloat = 20
@@ -73,16 +77,8 @@ class CropOverlayView: UIView {
73
77
  guard !cropRect.isEmpty, let ctx = UIGraphicsGetCurrentContext() else { return }
74
78
  let cr = cropRect
75
79
 
76
- ctx.saveGState()
77
- let fullPath = UIBezierPath(rect: bounds)
78
- fullPath.append(UIBezierPath(rect: cr))
79
- fullPath.usesEvenOddFillRule = true
80
- ctx.addPath(fullPath.cgPath)
81
- ctx.setFillColor(UIColor.black.withAlphaComponent(0.55).cgColor)
82
- ctx.fillPath(using: .evenOdd)
83
- ctx.restoreGState()
84
-
85
- ctx.setStrokeColor(UIColor.white.cgColor)
80
+ let strokeColor = (isLightTheme ? UIColor.black : UIColor.white).cgColor
81
+ ctx.setStrokeColor(strokeColor)
86
82
  ctx.setLineWidth(borderWidth)
87
83
  ctx.stroke(cr)
88
84
 
@@ -99,7 +95,7 @@ class CropOverlayView: UIView {
99
95
  }
100
96
  ctx.strokePath()
101
97
 
102
- ctx.setStrokeColor(UIColor.white.cgColor)
98
+ ctx.setStrokeColor(strokeColor)
103
99
  ctx.setLineWidth(cornerWidth)
104
100
  ctx.setLineCap(.round)
105
101
  ctx.setLineJoin(.round)
package/ios/VideoTrim.mm CHANGED
@@ -160,6 +160,11 @@ RCT_EXPORT_MODULE()
160
160
  dict[@"zoomOnWaitingDuration"] = @(zoomOnWaitingDurationOpt.value());
161
161
  }
162
162
 
163
+ NSString *theme = config.theme();
164
+ if (theme != nil) {
165
+ dict[@"theme"] = theme;
166
+ }
167
+
163
168
  [self->videoTrim showEditor:filePath withConfig:dict];
164
169
  }
165
170
 
@@ -13,6 +13,9 @@ public class VideoTrim: RCTEventEmitter, AssetLoaderDelegate, UIDocumentPickerDe
13
13
  private var vc: VideoTrimmerViewController?
14
14
  private var outputFile: URL?
15
15
  private var editorConfig: NSDictionary?
16
+ private var isLightTheme: Bool {
17
+ return (editorConfig?["theme"] as? String) == "light"
18
+ }
16
19
 
17
20
  // MARK: base options
18
21
  private var saveToPhoto: Bool {
@@ -289,7 +292,7 @@ public class VideoTrim: RCTEventEmitter, AssetLoaderDelegate, UIDocumentPickerDe
289
292
  progressAlert.onDismiss = {
290
293
  if self.enableCancelTrimmingDialog {
291
294
  let dialogMessage = UIAlertController(title: self.cancelTrimmingDialogTitle, message: self.cancelTrimmingDialogMessage, preferredStyle: .alert)
292
- dialogMessage.overrideUserInterfaceStyle = .dark
295
+ dialogMessage.overrideUserInterfaceStyle = self.isLightTheme ? .light : .dark
293
296
 
294
297
  // Create OK button with action handler
295
298
  let ok = UIAlertAction(title: self.cancelTrimmingDialogConfirmText, style: .destructive, handler: { (action) -> Void in
@@ -879,7 +882,7 @@ extension VideoTrim {
879
882
 
880
883
  // Create Alert
881
884
  let dialogMessage = UIAlertController(title: self.cancelDialogTitle, message: self.cancelDialogMessage, preferredStyle: .alert)
882
- dialogMessage.overrideUserInterfaceStyle = .dark
885
+ dialogMessage.overrideUserInterfaceStyle = self.isLightTheme ? .light : .dark
883
886
 
884
887
  // Create OK button with action handler
885
888
  let ok = UIAlertAction(title: self.cancelDialogConfirmText, style: .destructive, handler: { (action) -> Void in
@@ -911,7 +914,7 @@ extension VideoTrim {
911
914
 
912
915
  // Create Alert
913
916
  let dialogMessage = UIAlertController(title: self.saveDialogTitle, message: self.saveDialogMessage, preferredStyle: .alert)
914
- dialogMessage.overrideUserInterfaceStyle = .dark
917
+ dialogMessage.overrideUserInterfaceStyle = self.isLightTheme ? .light : .dark
915
918
 
916
919
  // Create OK button with action handler
917
920
  let ok = UIAlertAction(title: self.saveDialogConfirmText, style: .default, handler: { (action) -> Void in
@@ -1134,7 +1137,7 @@ extension VideoTrim {
1134
1137
 
1135
1138
  if alertOnFailToLoad {
1136
1139
  let dialogMessage = UIAlertController(title: alertOnFailTitle, message: alertOnFailMessage, preferredStyle: .alert)
1137
- dialogMessage.overrideUserInterfaceStyle = .dark
1140
+ dialogMessage.overrideUserInterfaceStyle = isLightTheme ? .light : .dark
1138
1141
 
1139
1142
  // Create Cancel button with action handlder
1140
1143
  let ok = UIAlertAction(title: alertOnFailCloseText, style: .default)
@@ -133,10 +133,10 @@ import AVFoundation
133
133
  }
134
134
  }
135
135
 
136
- // the asset to use
137
136
  var asset: AVAsset? {
138
137
  didSet {
139
138
  if let asset = asset {
139
+ applyThemeColors()
140
140
  let duration = asset.duration
141
141
  range = CMTimeRange(start: .zero, duration: duration)
142
142
  selectedRange = range
@@ -159,6 +159,7 @@ import AVFoundation
159
159
  var maximumDuration: CMTime = .positiveInfinity
160
160
  var enableHapticFeedback = true
161
161
  var zoomOnWaitingDuration: Double = 5.0 // Default: 5 seconds
162
+ var isLightTheme = false
162
163
 
163
164
  // the available range of the asset.
164
165
  // Will be set to the full duration of the asset when assigning a new asset
@@ -219,14 +220,12 @@ import AVFoundation
219
220
  // yes if the user is scrubbing the progress indicator
220
221
  private(set) var isScrubbing = false
221
222
 
222
- // background color for the track
223
223
  var trackBackgroundColor = UIColor.black {
224
224
  didSet {
225
225
  thumbnailWrapperView.backgroundColor = trackBackgroundColor
226
226
  }
227
227
  }
228
228
 
229
- // background color for the place where the thumbs rest on when the selectedRange == range
230
229
  var thumbRestColor = UIColor.black {
231
230
  didSet {
232
231
  leadingThumbRest.backgroundColor = thumbRestColor
@@ -276,6 +275,16 @@ import AVFoundation
276
275
 
277
276
 
278
277
  // MARK: - Private
278
+ private func applyThemeColors() {
279
+ let bg: UIColor = isLightTheme ? .white : .black
280
+ let coverAlpha: CGFloat = isLightTheme ? 0.6 : 0.75
281
+ trackBackgroundColor = bg
282
+ thumbRestColor = bg
283
+ thumbnailLeadingCoverView.backgroundColor = UIColor(white: isLightTheme ? 1 : 0, alpha: coverAlpha)
284
+ thumbnailTrailingCoverView.backgroundColor = UIColor(white: isLightTheme ? 1 : 0, alpha: coverAlpha)
285
+ shadowView.layer.shadowColor = (isLightTheme ? UIColor.gray : UIColor.black).cgColor
286
+ }
287
+
279
288
  private func setup() {
280
289
  addSubview(thumbnailClipView)
281
290
  thumbnailClipView.addSubview(thumbnailWrapperView)
@@ -285,8 +294,6 @@ import AVFoundation
285
294
  thumbnailWrapperView.addSubview(thumbnailLeadingCoverView)
286
295
  thumbnailWrapperView.addSubview(thumbnailTrailingCoverView)
287
296
 
288
- progressIndicator.backgroundColor = .white
289
- progressIndicator.layer.shadowColor = UIColor.black.cgColor
290
297
  progressIndicator.layer.shadowOffset = .zero
291
298
  progressIndicator.layer.shadowRadius = 2
292
299
  progressIndicator.layer.shadowOpacity = 0.25
@@ -302,13 +309,7 @@ import AVFoundation
302
309
 
303
310
  thumbnailClipView.clipsToBounds = true
304
311
  thumbnailTrackView.clipsToBounds = true
305
- thumbnailLeadingCoverView.backgroundColor = UIColor(white: 0, alpha: 0.75)
306
- thumbnailTrailingCoverView.backgroundColor = UIColor(white: 0, alpha: 0.75)
307
312
 
308
- leadingThumbRest.backgroundColor = thumbRestColor
309
- trailingThumbRest.backgroundColor = thumbRestColor
310
-
311
- thumbnailWrapperView.backgroundColor = trackBackgroundColor
312
313
  thumbnailWrapperView.layer.cornerRadius = 6
313
314
  thumbnailWrapperView.layer.cornerCurve = .continuous
314
315
 
@@ -320,11 +321,20 @@ import AVFoundation
320
321
  trailingThumbRest.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner]
321
322
  trailingThumbRest.layer.cornerCurve = .continuous
322
323
 
323
- shadowView.layer.shadowColor = UIColor.black.cgColor
324
324
  shadowView.layer.shadowOffset = .zero
325
325
  shadowView.layer.shadowRadius = 2
326
326
  shadowView.layer.shadowOpacity = 0.25
327
327
 
328
+ // Apply default (dark theme) colors — overridden by applyThemeColors() when asset is set
329
+ progressIndicator.backgroundColor = .white
330
+ progressIndicator.layer.shadowColor = UIColor.black.cgColor
331
+ thumbnailLeadingCoverView.backgroundColor = UIColor(white: 0, alpha: 0.75)
332
+ thumbnailTrailingCoverView.backgroundColor = UIColor(white: 0, alpha: 0.75)
333
+ leadingThumbRest.backgroundColor = thumbRestColor
334
+ trailingThumbRest.backgroundColor = thumbRestColor
335
+ thumbnailWrapperView.backgroundColor = trackBackgroundColor
336
+ shadowView.layer.shadowColor = UIColor.black.cgColor
337
+
328
338
  setupConstraints()
329
339
  setupGestures()
330
340
  }
@@ -49,9 +49,11 @@ class VideoTrimmerViewController: UIViewController {
49
49
  private var enableHapticFeedback = true
50
50
  private var zoomOnWaitingDuration: Double = 5.0 // Default: 5 seconds
51
51
 
52
- // New color properties
53
52
  private var trimmerColor: UIColor = UIColor.systemYellow
54
53
  private var handleIconColor: UIColor = UIColor.black
54
+ private var isLightTheme = false
55
+ private var iconColor: UIColor { isLightTheme ? .black : .white }
56
+ private var dimmedIconColor: UIColor { iconColor.withAlphaComponent(0.5) }
55
57
 
56
58
  private let playerController = AVPlayerViewController()
57
59
  private var trimmer: VideoTrimmer!
@@ -212,6 +214,14 @@ class VideoTrimmerViewController: UIViewController {
212
214
  setupView()
213
215
  setupButtons()
214
216
  setupTimeLabels()
217
+
218
+ NotificationCenter.default.addObserver(self, selector: #selector(appWillResignActive), name: UIApplication.willResignActiveNotification, object: nil)
219
+ }
220
+
221
+ @objc private func appWillResignActive() {
222
+ guard asset != nil else { return }
223
+ player.pause()
224
+ setPlayBtnIcon()
215
225
  }
216
226
 
217
227
  override func viewWillDisappear(_ animated: Bool) {
@@ -228,8 +238,8 @@ class VideoTrimmerViewController: UIViewController {
228
238
  player.removeTimeObserver(token)
229
239
  timeObserverToken = nil
230
240
  }
231
- // Remove observer
232
241
  NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: player.currentItem)
242
+ NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)
233
243
 
234
244
  playerController.player = nil
235
245
  playerController.dismiss(animated: false, completion: nil)
@@ -276,8 +286,8 @@ class VideoTrimmerViewController: UIViewController {
276
286
 
277
287
  // MARK: - Setup Methods
278
288
  private func setupView() {
279
- self.overrideUserInterfaceStyle = .dark
280
- view.backgroundColor = .black // need to have this otherwise during animation the background of this VC is still white in white theme
289
+ self.overrideUserInterfaceStyle = isLightTheme ? .light : .dark
290
+ view.backgroundColor = isLightTheme ? .white : .black
281
291
 
282
292
  if let headerText = headerText {
283
293
  headerView = UIView()
@@ -326,8 +336,8 @@ class VideoTrimmerViewController: UIViewController {
326
336
  }
327
337
 
328
338
  private func setupButtons() {
329
- cancelBtn = UIButton.createButton(title: cancelButtonText, font: .systemFont(ofSize: 18), titleColor: .white, target: self, action: #selector(onCancelBtnClicked))
330
- playBtn = UIButton.createButton(image: playIcon, tintColor: .white, target: self, action: #selector(togglePlay(sender:)))
339
+ cancelBtn = UIButton.createButton(title: cancelButtonText, font: .systemFont(ofSize: 18), titleColor: iconColor, target: self, action: #selector(onCancelBtnClicked))
340
+ playBtn = UIButton.createButton(image: playIcon, tintColor: iconColor, target: self, action: #selector(togglePlay(sender:)))
331
341
  playBtn.alpha = 0
332
342
  playBtn.isEnabled = false
333
343
 
@@ -354,11 +364,12 @@ class VideoTrimmerViewController: UIViewController {
354
364
  }
355
365
 
356
366
  private func setupTimeLabels() {
357
- leadingTrimLabel = UILabel.createLabel(textAlignment: .left, textColor: .white)
367
+ let labelColor = isLightTheme ? UIColor.black : UIColor.white
368
+ leadingTrimLabel = UILabel.createLabel(textAlignment: .left, textColor: labelColor)
358
369
  leadingTrimLabel.text = "00:00.000"
359
- currentTimeLabel = UILabel.createLabel(textAlignment: .center, textColor: .white)
370
+ currentTimeLabel = UILabel.createLabel(textAlignment: .center, textColor: labelColor)
360
371
  currentTimeLabel.text = "00:00.000"
361
- trailingTrimLabel = UILabel.createLabel(textAlignment: .right, textColor: .white)
372
+ trailingTrimLabel = UILabel.createLabel(textAlignment: .right, textColor: labelColor)
362
373
  trailingTrimLabel.text = "00:00.000"
363
374
 
364
375
  timingStackView = UIStackView(arrangedSubviews: [leadingTrimLabel, currentTimeLabel, trailingTrimLabel])
@@ -377,6 +388,7 @@ class VideoTrimmerViewController: UIViewController {
377
388
 
378
389
  private func setupVideoTrimmer() {
379
390
  trimmer = VideoTrimmer()
391
+ trimmer.isLightTheme = isLightTheme
380
392
  trimmer.asset = asset
381
393
  trimmer.minimumDuration = CMTime(seconds: 1, preferredTimescale: 600)
382
394
  trimmer.enableHapticFeedback = enableHapticFeedback
@@ -469,12 +481,14 @@ class VideoTrimmerViewController: UIViewController {
469
481
  addChild(playerController)
470
482
  playerContainerView.addSubview(playerController.view)
471
483
  playerController.view.translatesAutoresizingMaskIntoConstraints = false
472
- let bracketInset: CGFloat = 4
484
+ playerController.view.backgroundColor = .clear
485
+
486
+ let bracketInset: CGFloat = 5
473
487
  NSLayoutConstraint.activate([
488
+ playerController.view.topAnchor.constraint(equalTo: playerContainerView.topAnchor, constant: bracketInset),
489
+ playerController.view.bottomAnchor.constraint(equalTo: playerContainerView.bottomAnchor, constant: -bracketInset),
474
490
  playerController.view.leadingAnchor.constraint(equalTo: playerContainerView.leadingAnchor, constant: bracketInset),
475
491
  playerController.view.trailingAnchor.constraint(equalTo: playerContainerView.trailingAnchor, constant: -bracketInset),
476
- playerController.view.topAnchor.constraint(equalTo: playerContainerView.topAnchor, constant: bracketInset),
477
- playerController.view.bottomAnchor.constraint(equalTo: playerContainerView.bottomAnchor, constant: -bracketInset)
478
492
  ])
479
493
 
480
494
  // Add observer for the end of playback
@@ -492,34 +506,33 @@ class VideoTrimmerViewController: UIViewController {
492
506
  guard isVideoType else { return }
493
507
 
494
508
  let symbolConfig = UIImage.SymbolConfiguration(pointSize: 14, weight: .medium)
495
- let dimmed = UIColor.white.withAlphaComponent(0.5)
496
509
 
497
510
  let flipBtn = UIButton(type: .system)
498
511
  flipBtn.setImage(UIImage(systemName: "arrow.trianglehead.left.and.right.righttriangle.left.righttriangle.right", withConfiguration: symbolConfig), for: .normal)
499
- flipBtn.tintColor = .white
512
+ flipBtn.tintColor = iconColor
500
513
  flipBtn.addTarget(self, action: #selector(onFlipTapped), for: .touchUpInside)
501
514
 
502
515
  let rotateBtn = UIButton(type: .system)
503
516
  rotateBtn.setImage(UIImage(systemName: "rotate.left", withConfiguration: symbolConfig), for: .normal)
504
- rotateBtn.tintColor = .white
517
+ rotateBtn.tintColor = iconColor
505
518
  rotateBtn.addTarget(self, action: #selector(onRotateTapped), for: .touchUpInside)
506
519
 
507
520
  let cropButton = UIButton(type: .system)
508
521
  cropButton.setImage(UIImage(systemName: "crop", withConfiguration: symbolConfig), for: .normal)
509
- cropButton.tintColor = UIColor.white.withAlphaComponent(0.5)
522
+ cropButton.tintColor = dimmedIconColor
510
523
  cropButton.addTarget(self, action: #selector(onCropTapped), for: .touchUpInside)
511
524
  self.cropBtn = cropButton
512
525
 
513
526
  let undoButton = UIButton(type: .system)
514
527
  undoButton.setImage(UIImage(systemName: "arrow.uturn.backward", withConfiguration: symbolConfig), for: .normal)
515
- undoButton.tintColor = dimmed
528
+ undoButton.tintColor = dimmedIconColor
516
529
  undoButton.isEnabled = false
517
530
  undoButton.addTarget(self, action: #selector(onUndoTapped), for: .touchUpInside)
518
531
  self.undoBtn = undoButton
519
532
 
520
533
  let redoButton = UIButton(type: .system)
521
534
  redoButton.setImage(UIImage(systemName: "arrow.uturn.forward", withConfiguration: symbolConfig), for: .normal)
522
- redoButton.tintColor = dimmed
535
+ redoButton.tintColor = dimmedIconColor
523
536
  redoButton.isEnabled = false
524
537
  redoButton.addTarget(self, action: #selector(onRedoTapped), for: .touchUpInside)
525
538
  self.redoBtn = redoButton
@@ -583,29 +596,63 @@ class VideoTrimmerViewController: UIViewController {
583
596
  updateVideoTransform(resetCrop: true)
584
597
  }
585
598
 
586
- private func updateVideoTransform(resetCrop: Bool = false) {
599
+ private func buildVideoTransform() -> CGAffineTransform {
587
600
  let angle = -CGFloat(rotationCount) * (.pi / 2)
588
601
  var transform = CGAffineTransform.identity
589
-
590
602
  if isFlipped {
591
603
  transform = transform.scaledBy(x: -1, y: 1)
592
604
  }
593
605
  transform = transform.rotated(by: angle)
594
-
595
606
  if rotationCount % 2 != 0 {
596
- let bounds = playerContainerView.bounds
597
- if bounds.width > 0 && bounds.height > 0 {
598
- let fitScale = min(bounds.width / bounds.height, bounds.height / bounds.width)
607
+ let pvBounds = playerController.view.bounds
608
+ let cBounds = playerContainerView.bounds
609
+ if pvBounds.width > 0 && pvBounds.height > 0 && cBounds.width > 0 && cBounds.height > 0 {
610
+ var videoW = pvBounds.width
611
+ var videoH = pvBounds.height
612
+ if let track = asset?.tracks(withMediaType: .video).first {
613
+ let raw = track.naturalSize
614
+ let pt = track.preferredTransform
615
+ let a = atan2(pt.b, pt.a)
616
+ let srcRotated = abs(a - .pi / 2) < 0.1 || abs(a + .pi / 2) < 0.1
617
+ let ds = srcRotated ? CGSize(width: raw.height, height: raw.width) : raw
618
+ if ds.width > 0 && ds.height > 0 {
619
+ let videoAR = ds.width / ds.height
620
+ let viewAR = pvBounds.width / pvBounds.height
621
+ if videoAR > viewAR {
622
+ videoW = pvBounds.width
623
+ videoH = pvBounds.width / videoAR
624
+ } else {
625
+ videoH = pvBounds.height
626
+ videoW = pvBounds.height * videoAR
627
+ }
628
+ }
629
+ }
630
+ let bracketMargin: CGFloat = 5
631
+ let availW = cBounds.width - 2 * bracketMargin
632
+ let availH = cBounds.height - 2 * bracketMargin
633
+ let fitScale = min(availW / videoH, availH / videoW)
599
634
  transform = transform.scaledBy(x: fitScale, y: fitScale)
600
635
  }
601
636
  }
602
-
637
+ return transform
638
+ }
639
+
640
+ private func updateVideoTransform(resetCrop: Bool = false) {
641
+ let transform = buildVideoTransform()
642
+ if isCropActive {
643
+ UIView.animate(withDuration: 0.15) {
644
+ self.cropOverlayView?.alpha = 0
645
+ }
646
+ }
603
647
  UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseInOut]) {
604
648
  self.playerController.view.transform = transform
605
649
  } completion: { _ in
606
650
  if resetCrop && self.isCropActive {
607
651
  self.updateCropAllowedRect()
608
652
  self.cropOverlayView?.resetCrop()
653
+ UIView.animate(withDuration: 0.15) {
654
+ self.cropOverlayView?.alpha = 1
655
+ }
609
656
  }
610
657
  }
611
658
  }
@@ -645,21 +692,11 @@ class VideoTrimmerViewController: UIViewController {
645
692
  rotationCount = snap.rotationCount
646
693
  isFlipped = snap.isFlipped
647
694
 
648
- let angle = -CGFloat(rotationCount) * (.pi / 2)
649
- var transform = CGAffineTransform.identity
650
- if isFlipped { transform = transform.scaledBy(x: -1, y: 1) }
651
- transform = transform.rotated(by: angle)
652
- if rotationCount % 2 != 0 {
653
- let bounds = playerContainerView.bounds
654
- if bounds.width > 0 && bounds.height > 0 {
655
- let fitScale = min(bounds.width / bounds.height, bounds.height / bounds.width)
656
- transform = transform.scaledBy(x: fitScale, y: fitScale)
657
- }
658
- }
695
+ let transform = buildVideoTransform()
659
696
 
660
697
  let wasActive = isCropActive
661
698
  isCropActive = snap.isCropActive
662
- cropBtn?.tintColor = isCropActive ? .white : UIColor.white.withAlphaComponent(0.5)
699
+ cropBtn?.tintColor = isCropActive ? iconColor : dimmedIconColor
663
700
 
664
701
  UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseInOut]) {
665
702
  self.playerController.view.transform = transform
@@ -691,10 +728,9 @@ class VideoTrimmerViewController: UIViewController {
691
728
  }
692
729
 
693
730
  private func updateUndoRedoButtons() {
694
- let dimmed = UIColor.white.withAlphaComponent(0.5)
695
- undoBtn?.tintColor = undoStack.isEmpty ? dimmed : .white
731
+ undoBtn?.tintColor = undoStack.isEmpty ? dimmedIconColor : iconColor
696
732
  undoBtn?.isEnabled = !undoStack.isEmpty
697
- redoBtn?.tintColor = redoStack.isEmpty ? dimmed : .white
733
+ redoBtn?.tintColor = redoStack.isEmpty ? dimmedIconColor : iconColor
698
734
  redoBtn?.isEnabled = !redoStack.isEmpty
699
735
  }
700
736
 
@@ -702,7 +738,7 @@ class VideoTrimmerViewController: UIViewController {
702
738
 
703
739
  @objc private func onCropTapped() {
704
740
  isCropActive.toggle()
705
- cropBtn?.tintColor = isCropActive ? .white : UIColor.white.withAlphaComponent(0.5)
741
+ cropBtn?.tintColor = isCropActive ? iconColor : dimmedIconColor
706
742
 
707
743
  if enableHapticFeedback {
708
744
  UIImpactFeedbackGenerator(style: .light).impactOccurred()
@@ -743,6 +779,7 @@ class VideoTrimmerViewController: UIViewController {
743
779
 
744
780
  private func createCropOverlay() {
745
781
  let overlay = CropOverlayView()
782
+ overlay.isLightTheme = isLightTheme
746
783
  overlay.translatesAutoresizingMaskIntoConstraints = false
747
784
  overlay.alpha = 0
748
785
  playerContainerView.addSubview(overlay)
@@ -916,6 +953,8 @@ class VideoTrimmerViewController: UIViewController {
916
953
  minimumDuration = minDuration
917
954
  }
918
955
 
956
+ isLightTheme = (config["theme"] as? String) == "light"
957
+
919
958
  cancelButtonText = config["cancelButtonText"] as? String ?? "Cancel"
920
959
  saveButtonText = config["saveButtonText"] as? String ?? "Save"
921
960
  jumpToPositionOnLoad = config["jumpToPositionOnLoad"] as? Double ?? 0
@@ -927,12 +966,11 @@ class VideoTrimmerViewController: UIViewController {
927
966
  headerTextSize = config["headerTextSize"] as? Int ?? 16
928
967
  headerTextColor = config["headerTextColor"] as? Double
929
968
 
930
- // Handle new color properties
931
969
  if let trimmerColorValue = config["trimmerColor"] as? Double {
932
970
  trimmerColor = RCTConvert.uiColor(trimmerColorValue) ?? UIColor.systemYellow
933
971
  }
934
972
  if let handleIconColorValue = config["handleIconColor"] as? Double {
935
- handleIconColor = RCTConvert.uiColor(handleIconColorValue) ?? UIColor.black
973
+ handleIconColor = RCTConvert.uiColor(handleIconColorValue) ?? (isLightTheme ? .white : .black)
936
974
  }
937
975
  }
938
976
 
@@ -1 +1 @@
1
- {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeVideoTrim.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;;AAGlD;AACA;AACA;;AAwBA;AACA;AACA;;AAgGA;AACA;AACA;;AAQA;AACA;AACA;;AAUA;AACA;AACA;;AAcA;AACA;AACA;;AAmEA,eAAeA,mBAAmB,CAACC,YAAY,CAAO,WAAW,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeVideoTrim.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;;AAGlD;AACA;AACA;;AAwBA;AACA;AACA;;AAqGA;AACA;AACA;;AAQA;AACA;AACA;;AAUA;AACA;AACA;;AAcA;AACA;AACA;;AAmEA,eAAeA,mBAAmB,CAACC,YAAY,CAAO,WAAW,CAAC","ignoreList":[]}
@@ -90,9 +90,10 @@ export function showEditor(filePath, config) {
90
90
  trimmerColor,
91
91
  handleIconColor
92
92
  } = config;
93
- const _headerTextColor = processColor(headerTextColor || 'white');
93
+ const isLight = config.theme === 'light';
94
+ const _headerTextColor = processColor(headerTextColor || (isLight ? 'black' : 'white'));
94
95
  const _trimmerColor = processColor(trimmerColor || '#f1d247');
95
- const _handleIconColor = processColor(handleIconColor || 'black');
96
+ const _handleIconColor = processColor(handleIconColor || (isLight ? 'white' : 'black'));
96
97
  VideoTrim.showEditor(filePath, createEditorConfig({
97
98
  ...config,
98
99
  headerTextColor: _headerTextColor,
@@ -1 +1 @@
1
- {"version":3,"names":["VideoTrimNewArch","VideoTrimOldArch","processColor","isFabric","global","nativeFabricUIManager","VideoTrim","createBaseOptions","overrides","saveToPhoto","type","outputExt","removeAfterSavedToPhoto","removeAfterFailedToSavePhoto","enablePreciseTrimming","createEditorConfig","enableHapticFeedback","maxDuration","minDuration","openDocumentsOnFinish","openShareSheetOnFinish","removeAfterSavedToDocuments","removeAfterFailedToSaveDocuments","removeAfterShared","removeAfterFailedToShare","cancelButtonText","saveButtonText","enableCancelDialog","cancelDialogTitle","cancelDialogMessage","cancelDialogCancelText","cancelDialogConfirmText","enableSaveDialog","saveDialogTitle","saveDialogMessage","saveDialogCancelText","saveDialogConfirmText","trimmingText","fullScreenModalIOS","autoplay","jumpToPositionOnLoad","closeWhenFinish","enableCancelTrimming","cancelTrimmingButtonText","enableCancelTrimmingDialog","cancelTrimmingDialogTitle","cancelTrimmingDialogMessage","cancelTrimmingDialogCancelText","cancelTrimmingDialogConfirmText","headerText","headerTextSize","headerTextColor","trimmerColor","handleIconColor","zoomOnWaitingDuration","alertOnFailToLoad","alertOnFailTitle","alertOnFailMessage","alertOnFailCloseText","createTrimOptions","startTime","endTime","showEditor","filePath","config","_headerTextColor","_trimmerColor","_handleIconColor","listFiles","cleanFiles","deleteFile","trim","length","Error","closeEditor","isValidFile","url","options"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,gBAAgB,MAAM,sBAAmB;AAChD,OAAOC,gBAAgB,MAAM,cAAW;AAQxC,SAASC,YAAY,QAAQ,cAAc;;AAE3C;AACA,MAAMC,QAAQ,GAAG,CAAC,CAAEC,MAAM,CAASC,qBAAqB;AACxD,MAAMC,SAAS,GAAGH,QAAQ,GAAGH,gBAAgB,GAAGC,gBAAgB;AAEhE,SAASM,iBAAiBA,CAACC,SAA+B,GAAG,CAAC,CAAC,EAAe;EAC5E,OAAO;IACLC,WAAW,EAAE,KAAK;IAClBC,IAAI,EAAE,OAAO;IACbC,SAAS,EAAE,KAAK;IAChBC,uBAAuB,EAAE,KAAK;IAC9BC,4BAA4B,EAAE,KAAK;IACnCC,qBAAqB,EAAE,KAAK;IAC5B,GAAGN;EACL,CAAC;AACH;AAEA,SAASO,kBAAkBA,CACzBP,SAAgC,GAAG,CAAC,CAAC,EACvB;EACd,OAAO;IACLQ,oBAAoB,EAAE,IAAI;IAC1BC,WAAW,EAAE,CAAC,CAAC;IACfC,WAAW,EAAE,CAAC,CAAC;IACfC,qBAAqB,EAAE,KAAK;IAC5BC,sBAAsB,EAAE,KAAK;IAC7BC,2BAA2B,EAAE,KAAK;IAClCC,gCAAgC,EAAE,KAAK;IACvCC,iBAAiB,EAAE,KAAK;IACxBC,wBAAwB,EAAE,KAAK;IAC/BC,gBAAgB,EAAE,QAAQ;IAC1BC,cAAc,EAAE,MAAM;IACtBC,kBAAkB,EAAE,IAAI;IACxBC,iBAAiB,EAAE,UAAU;IAC7BC,mBAAmB,EAAE,8BAA8B;IACnDC,sBAAsB,EAAE,OAAO;IAC/BC,uBAAuB,EAAE,SAAS;IAClCC,gBAAgB,EAAE,IAAI;IACtBC,eAAe,EAAE,eAAe;IAChCC,iBAAiB,EAAE,4BAA4B;IAC/CC,oBAAoB,EAAE,OAAO;IAC7BC,qBAAqB,EAAE,SAAS;IAChCC,YAAY,EAAE,mBAAmB;IACjCC,kBAAkB,EAAE,KAAK;IACzBC,QAAQ,EAAE,KAAK;IACfC,oBAAoB,EAAE,CAAC,CAAC;IACxBC,eAAe,EAAE,IAAI;IACrBC,oBAAoB,EAAE,IAAI;IAC1BC,wBAAwB,EAAE,QAAQ;IAClCC,0BAA0B,EAAE,IAAI;IAChCC,yBAAyB,EAAE,UAAU;IACrCC,2BAA2B,EAAE,uCAAuC;IACpEC,8BAA8B,EAAE,OAAO;IACvCC,+BAA+B,EAAE,SAAS;IAC1CC,UAAU,EAAE,EAAE;IACdC,cAAc,EAAE,EAAE;IAClBC,eAAe,EAAEjD,YAAY,CAAC,OAAO,CAAW;IAChDkD,YAAY,EAAElD,YAAY,CAAC,SAAS,CAAW;IAC/CmD,eAAe,EAAEnD,YAAY,CAAC,OAAO,CAAW;IAChDoD,qBAAqB,EAAE,IAAI;IAC3BC,iBAAiB,EAAE,IAAI;IACvBC,gBAAgB,EAAE,OAAO;IACzBC,kBAAkB,EAChB,oEAAoE;IACtEC,oBAAoB,EAAE,OAAO;IAC7B,GAAGnD,iBAAiB,CAACC,SAAS,CAAC;IAC/B,GAAGA;EACL,CAAC;AACH;AAEA,SAASmD,iBAAiBA,CAACnD,SAA+B,GAAG,CAAC,CAAC,EAAe;EAC5E,OAAO;IACLoD,SAAS,EAAE,CAAC;IACZC,OAAO,EAAE,IAAI;IACb,GAAGtD,iBAAiB,CAACC,SAAS,CAAC;IAC/B,GAAGA;EACL,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASsD,UAAUA,CACxBC,QAAgB,EAChBC,MAMC,EACK;EACN,MAAM;IAAEb,eAAe;IAAEC,YAAY;IAAEC;EAAgB,CAAC,GAAGW,MAAM;EACjE,MAAMC,gBAAgB,GAAG/D,YAAY,CAACiD,eAAe,IAAI,OAAO,CAAC;EACjE,MAAMe,aAAa,GAAGhE,YAAY,CAACkD,YAAY,IAAI,SAAS,CAAC;EAC7D,MAAMe,gBAAgB,GAAGjE,YAAY,CAACmD,eAAe,IAAI,OAAO,CAAC;EAEjE/C,SAAS,CAACwD,UAAU,CAClBC,QAAQ,EACRhD,kBAAkB,CAAC;IACjB,GAAGiD,MAAM;IACTb,eAAe,EAAEc,gBAAuB;IACxCb,YAAY,EAAEc,aAAoB;IAClCb,eAAe,EAAEc;EACnB,CAAC,CACH,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,SAASA,CAAA,EAAsB;EAC7C,OAAO9D,SAAS,CAAC8D,SAAS,CAAC,CAAC;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAAA,EAAoB;EAC5C,OAAO/D,SAAS,CAAC+D,UAAU,CAAC,CAAC;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAACP,QAAgB,EAAoB;EAC7D,IAAI,CAACA,QAAQ,EAAEQ,IAAI,CAAC,CAAC,CAACC,MAAM,EAAE;IAC5B,MAAM,IAAIC,KAAK,CAAC,4BAA4B,CAAC;EAC/C;EACA,OAAOnE,SAAS,CAACgE,UAAU,CAACP,QAAQ,CAAC;AACvC;;AAEA;AACA;AACA;AACA,OAAO,SAASW,WAAWA,CAAA,EAAS;EAClC,OAAOpE,SAAS,CAACoE,WAAW,CAAC,CAAC;AAChC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,WAAWA,CAACC,GAAW,EAAiC;EACtE,OAAOtE,SAAS,CAACqE,WAAW,CAACC,GAAG,CAAC;AACnC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASL,IAAIA,CAClBK,GAAW,EACXC,OAA6B,EACR;EACrB,OAAOvE,SAAS,CAACiE,IAAI,CAACK,GAAG,EAAEjB,iBAAiB,CAACkB,OAAO,CAAC,CAAC;AACxD;AAEA,cAAc,sBAAmB;AACjC,eAAevE,SAAS","ignoreList":[]}
1
+ {"version":3,"names":["VideoTrimNewArch","VideoTrimOldArch","processColor","isFabric","global","nativeFabricUIManager","VideoTrim","createBaseOptions","overrides","saveToPhoto","type","outputExt","removeAfterSavedToPhoto","removeAfterFailedToSavePhoto","enablePreciseTrimming","createEditorConfig","enableHapticFeedback","maxDuration","minDuration","openDocumentsOnFinish","openShareSheetOnFinish","removeAfterSavedToDocuments","removeAfterFailedToSaveDocuments","removeAfterShared","removeAfterFailedToShare","cancelButtonText","saveButtonText","enableCancelDialog","cancelDialogTitle","cancelDialogMessage","cancelDialogCancelText","cancelDialogConfirmText","enableSaveDialog","saveDialogTitle","saveDialogMessage","saveDialogCancelText","saveDialogConfirmText","trimmingText","fullScreenModalIOS","autoplay","jumpToPositionOnLoad","closeWhenFinish","enableCancelTrimming","cancelTrimmingButtonText","enableCancelTrimmingDialog","cancelTrimmingDialogTitle","cancelTrimmingDialogMessage","cancelTrimmingDialogCancelText","cancelTrimmingDialogConfirmText","headerText","headerTextSize","headerTextColor","trimmerColor","handleIconColor","zoomOnWaitingDuration","alertOnFailToLoad","alertOnFailTitle","alertOnFailMessage","alertOnFailCloseText","createTrimOptions","startTime","endTime","showEditor","filePath","config","isLight","theme","_headerTextColor","_trimmerColor","_handleIconColor","listFiles","cleanFiles","deleteFile","trim","length","Error","closeEditor","isValidFile","url","options"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
@@ -121,6 +121,11 @@ export interface EditorConfig extends BaseOptions {
121
121
  * this duration around the current trim position for more precise editing.
122
122
  */
123
123
  zoomOnWaitingDuration?: number;
124
+ /**
125
+ * Editor theme. `"dark"` (default) uses a black background with white UI elements.
126
+ * `"light"` uses a white background with black icons/text and white trimmer-handle chevrons.
127
+ */
128
+ theme?: string;
124
129
  }
125
130
  /**
126
131
  * Options for headless (non-UI) trim operations.
@@ -1 +1 @@
1
- {"version":3,"file":"NativeVideoTrim.d.ts","sourceRoot":"","sources":["../../../src/NativeVideoTrim.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NativeVideoTrim.d.ts","sourceRoot":"","sources":["../../../src/NativeVideoTrim.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,YAAY,EACZ,oBAAoB,EACpB,WAAW,EACX,UAAU,EACX,MAAM,mBAAmB,CAAC;AAK3B,QAAA,MAAM,SAAS,KAAiD,CAAC;AA4EjE;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,CACb,IAAI,CAAC,YAAY,EAAE,iBAAiB,GAAG,cAAc,GAAG,iBAAiB,CAAC,CAC3E,GAAG;IACF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GACA,IAAI,CAeN;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAK7D;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAEtE;AAED;;;;;;GAMG;AACH,wBAAgB,IAAI,CAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAC5B,OAAO,CAAC,UAAU,CAAC,CAErB;AAED,cAAc,mBAAmB,CAAC;AAClC,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,YAAY,EACZ,oBAAoB,EACpB,WAAW,EACX,UAAU,EACX,MAAM,mBAAmB,CAAC;AAK3B,QAAA,MAAM,SAAS,KAAiD,CAAC;AA4EjE;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,CACb,IAAI,CAAC,YAAY,EAAE,iBAAiB,GAAG,cAAc,GAAG,iBAAiB,CAAC,CAC3E,GAAG;IACF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GACA,IAAI,CAoBN;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAK7D;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAEtE;AAED;;;;;;GAMG;AACH,wBAAgB,IAAI,CAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAC5B,OAAO,CAAC,UAAU,CAAC,CAErB;AAED,cAAc,mBAAmB,CAAC;AAClC,eAAe,SAAS,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-video-trim",
3
- "version": "7.0.1",
3
+ "version": "7.1.0",
4
4
  "description": "Video trimmer for your React Native app",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -124,6 +124,11 @@ export interface EditorConfig extends BaseOptions {
124
124
  * this duration around the current trim position for more precise editing.
125
125
  */
126
126
  zoomOnWaitingDuration?: number;
127
+ /**
128
+ * Editor theme. `"dark"` (default) uses a black background with white UI elements.
129
+ * `"light"` uses a white background with black icons/text and white trimmer-handle chevrons.
130
+ */
131
+ theme?: string;
127
132
  }
128
133
 
129
134
  /**
package/src/index.tsx CHANGED
@@ -106,9 +106,14 @@ export function showEditor(
106
106
  }
107
107
  ): void {
108
108
  const { headerTextColor, trimmerColor, handleIconColor } = config;
109
- const _headerTextColor = processColor(headerTextColor || 'white');
109
+ const isLight = config.theme === 'light';
110
+ const _headerTextColor = processColor(
111
+ headerTextColor || (isLight ? 'black' : 'white')
112
+ );
110
113
  const _trimmerColor = processColor(trimmerColor || '#f1d247');
111
- const _handleIconColor = processColor(handleIconColor || 'black');
114
+ const _handleIconColor = processColor(
115
+ handleIconColor || (isLight ? 'white' : 'black')
116
+ );
112
117
 
113
118
  VideoTrim.showEditor(
114
119
  filePath,