diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index c769fc3..0361dc2 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -4,10 +4,8 @@
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0ad17cb..8978d23 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,3 @@
-
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58ceebf..e78413f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,13 @@
> - 🏠 Internal
> - 💅 Polish
+## Unreleased
+
+* 💥 Updated to Jetpack Compose version 1.6.1 ([BOM](https://developer.android.com/jetpack/compose/bom) 2024.02.00).
+* 🐛 Fixed dragging the `SeekBar` when
+ using [Compose Material 3 version 1.2.0](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.2.0)
+ or higher. ([#24](https://github.com/THEOplayer/android-ui/issues/24))
+
## v1.4.0 (2023-11-27)
* 💥 Updated to Jetpack Compose version 1.5.4 ([BOM](https://developer.android.com/jetpack/compose/bom) 2023.10.01).
@@ -44,7 +51,7 @@
* 💥 Renamed `PlayerState` to `Player`.
* 🚀 Added overloads to `DefaultUI` and `UIController` that accept a `Player`.
This allows constructing a player instance in advance, and even moving it between custom UIs when recomposing.
-* 🚀 Added `UIControllerScope.player` as an non-null alternative to `Player.current`.
+* 🚀 Added `UIControllerScope.player` as an non-null alternative to `Player.current`.
## v1.1.0 (2023-06-27)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index f5cea2e..bfef9ef 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,11 +1,11 @@
[versions]
-gradle = "8.1.4"
+gradle = "8.2.2"
kotlin-gradle-plugin = "1.8.10"
ktx = "1.12.0"
lifecycle-runtime = "2.6.2"
activity-compose = "1.8.1"
appcompat = "1.6.1"
-compose-bom = "2023.10.01"
+compose-bom = "2024.02.00"
junit4 = "4.13.2"
androidx-junit = "1.1.5"
androidx-espresso = "3.5.1"
diff --git a/ui/src/main/java/com/theoplayer/android/ui/SeekBar.kt b/ui/src/main/java/com/theoplayer/android/ui/SeekBar.kt
index 7c72b8f..39fe984 100644
--- a/ui/src/main/java/com/theoplayer/android/ui/SeekBar.kt
+++ b/ui/src/main/java/com/theoplayer/android/ui/SeekBar.kt
@@ -27,8 +27,11 @@ fun SeekBar(
val player = Player.current
val currentTime = player?.currentTime?.toFloat() ?: 0.0f
val seekable = player?.seekable ?: TimeRanges(listOf())
- val valueRange = seekable.bounds ?: 0.0..0.0
+ val valueRange = remember(seekable) {
+ val bounds = seekable.bounds ?: 0.0..0.0
+ bounds.start.toFloat()..bounds.endInclusive.toFloat()
+ }
var seekTime by remember { mutableStateOf(null) }
var wasPlayingBeforeSeek by remember { mutableStateOf(false) }
@@ -36,23 +39,30 @@ fun SeekBar(
modifier = modifier,
colors = colors,
value = seekTime ?: currentTime,
- valueRange = valueRange.start.toFloat()..valueRange.endInclusive.toFloat(),
+ valueRange = valueRange,
enabled = seekable.isNotEmpty(),
- onValueChange = { time ->
- seekTime = time
- player?.player?.let {
- if (!it.isPaused) {
- wasPlayingBeforeSeek = true
- it.pause()
+ onValueChange = remember {
+ { time ->
+ seekTime = time
+ player?.player?.let {
+ if (!it.isPaused) {
+ wasPlayingBeforeSeek = true
+ it.pause()
+ }
+ it.currentTime = time.toDouble()
}
- it.currentTime = time.toDouble()
}
},
- onValueChangeFinished = {
- seekTime = null
- if (wasPlayingBeforeSeek) {
- player?.player?.play()
- wasPlayingBeforeSeek = false
+ // This needs to always be the *same* callback,
+ // otherwise Slider will reset its internal SliderState while dragging.
+ // https://github.com/androidx/androidx/blob/4d69c45e6361a2e5af77edc9f7f92af3d0db3877/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt#L270-L282
+ onValueChangeFinished = remember {
+ {
+ seekTime = null
+ if (wasPlayingBeforeSeek) {
+ player?.player?.play()
+ wasPlayingBeforeSeek = false
+ }
}
}
)