fix the restored position display, detail controls, mini player colour and source bar inset

This commit is contained in:
austinried
2026-10-04 00:29:56 +00:00
parent bd23f4369f
commit 0e55ce65f5
5 changed files with 30 additions and 15 deletions
@@ -917,7 +917,10 @@ class PlaybackController(
private fun refresh(position: Long? = currentPosition()) {
val player = player ?: return
updateBuffering()
lastDurationMs = player.durationMs.takeIf { it > 0 } ?: lastDurationMs
lastDurationMs =
player.durationMs.takeIf { it > 0 }
?: player.currentItem?.durationMs?.takeIf { it > 0 }
?: lastDurationMs
_state.value =
PlaybackState(
item = player.currentItem,
@@ -27,7 +27,6 @@ import androidx.compose.material.icons.rounded.Download
import androidx.compose.material.icons.rounded.MoreHoriz
import androidx.compose.material.icons.rounded.PlayArrow
import androidx.compose.material.icons.rounded.Shuffle
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.Icon
@@ -253,20 +252,31 @@ fun HeroHeader(
}
Spacer(Modifier.height(20.dp))
Row(
modifier = controlsModifier,
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = controlsModifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
IconButton(onClick = onDownload) {
Icon(Icons.Rounded.Download, contentDescription = "Download")
}
Button(onClick = onPlay, enabled = hasSongs) {
Icon(Icons.Rounded.PlayArrow, contentDescription = null)
Spacer(Modifier.width(8.dp))
Text("Play")
}
FilledIconButton(onClick = onShuffle, enabled = hasSongs) {
Icon(Icons.Rounded.Shuffle, contentDescription = "Shuffle play")
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterHorizontally),
verticalAlignment = Alignment.CenterVertically,
) {
FilledIconButton(
onClick = onPlay,
enabled = hasSongs,
modifier = Modifier.width(64.dp).height(48.dp),
) {
Icon(Icons.Rounded.PlayArrow, contentDescription = "Play")
}
FilledIconButton(
onClick = onShuffle,
enabled = hasSongs,
modifier = Modifier.width(64.dp).height(48.dp),
) {
Icon(Icons.Rounded.Shuffle, contentDescription = "Shuffle play")
}
}
IconButton(onClick = onMore) {
Icon(Icons.Rounded.MoreHoriz, contentDescription = "More options")
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
@@ -85,7 +86,7 @@ fun AddSourceScreen(
},
bottomBar = {
Row(
modifier = Modifier.fillMaxWidth().padding(16.dp),
modifier = Modifier.fillMaxWidth().navigationBarsPadding().padding(16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.End),
verticalAlignment = Alignment.CenterVertically,
) {
@@ -205,7 +205,7 @@ fun ArtworkTheme(
}
}
fun playerSurfaceColor(artwork: ArtworkColors): Color = lerp(artwork.scheme.surfaceContainerHigh, artwork.gradientHigh, 0.5f)
fun playerSurfaceColor(artwork: ArtworkColors): Color = artwork.gradientHigh
fun heroBarColor(
artwork: ArtworkColors?,
@@ -145,7 +145,7 @@ class PlaybackControllerTest {
}
@Test
fun theDurationDoesNotDropToZeroWhenTheNextTrackIsStillLoading() {
fun theDurationUsesTheNextTracksMetadataWhileItLoads() {
seedAlbum(3, sourceId = 1)
controller.playAlbum(1, "al1", 0)
@@ -165,7 +165,7 @@ class PlaybackControllerTest {
?.id == "s2"
}
assertEquals(284_000L, controller.state.value.durationMs)
assertEquals(100_000L, controller.state.value.durationMs)
}
@Test
@@ -925,6 +925,7 @@ class PlaybackControllerTest {
}
assertEquals(12_000L, restored.state.value.positionMs)
assertEquals(100_000L, restored.state.value.durationMs)
assertEquals(
"setWindow(size=3, start=0, position=12000)",
restoredHandle.operations.first { it.startsWith("setWindow") },