new: display playback progress with a progress bar
This commit is contained in:
@@ -4,7 +4,9 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
@@ -16,6 +18,7 @@ import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
@@ -85,7 +88,8 @@ fun PlayerScreen(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(innerPadding)
|
||||
.fillMaxSize(),
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Column(
|
||||
@@ -97,9 +101,11 @@ fun PlayerScreen(
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "${uiState.positionMs} ms",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
LinearProgressIndicator(
|
||||
progress = { uiState.progress },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
|
||||
Button(
|
||||
@@ -137,7 +143,7 @@ private fun PlayerScreenPlayingPreview() {
|
||||
GwenedegTheme {
|
||||
PlayerScreen(
|
||||
recordTitle = "Demat",
|
||||
uiState = PlayerUiState(playbackState = PlaybackState.PLAYING, positionMs = 1234),
|
||||
uiState = PlayerUiState(playbackState = PlaybackState.PLAYING, positionMs = 1234, durationMs = 5000),
|
||||
onMainPlayActionButtonClicked = {},
|
||||
onBackClicked = {},
|
||||
)
|
||||
@@ -150,7 +156,7 @@ private fun PlayerScreenPausedPreview() {
|
||||
GwenedegTheme {
|
||||
PlayerScreen(
|
||||
recordTitle = "Demat",
|
||||
uiState = PlayerUiState(playbackState = PlaybackState.PAUSED, positionMs = 1234),
|
||||
uiState = PlayerUiState(playbackState = PlaybackState.PAUSED, positionMs = 1234, durationMs = 5000),
|
||||
onMainPlayActionButtonClicked = {},
|
||||
onBackClicked = {},
|
||||
)
|
||||
@@ -163,7 +169,7 @@ private fun PlayerScreenEndedPreview() {
|
||||
GwenedegTheme {
|
||||
PlayerScreen(
|
||||
recordTitle = "Demat",
|
||||
uiState = PlayerUiState(playbackState = PlaybackState.ENDED, positionMs = 1234),
|
||||
uiState = PlayerUiState(playbackState = PlaybackState.ENDED, positionMs = 1234, durationMs = 5000),
|
||||
onMainPlayActionButtonClicked = {},
|
||||
onBackClicked = {},
|
||||
)
|
||||
|
||||
+5
-1
@@ -5,4 +5,8 @@ import fr.ajaury.gwenedeg.player.PlaybackState
|
||||
data class PlayerUiState(
|
||||
val playbackState: PlaybackState = PlaybackState.IDLE,
|
||||
val positionMs: Long = 0L,
|
||||
)
|
||||
val durationMs: Long = 0L,
|
||||
) {
|
||||
val progress: Float
|
||||
get() = if (durationMs > 0) (positionMs.toFloat() / durationMs).coerceIn(0f, 1f) else 0f
|
||||
}
|
||||
|
||||
+4
-3
@@ -35,12 +35,12 @@ class PlayerViewModel(
|
||||
if (state == PlaybackState.PLAYING) {
|
||||
flow {
|
||||
while (true) {
|
||||
emit(audioPlayer.currentPosition())
|
||||
emit(audioPlayer.currentPosition)
|
||||
delay(POSITION_POLL_INTERVAL)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
flowOf(audioPlayer.currentPosition())
|
||||
flowOf(audioPlayer.currentPosition)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ class PlayerViewModel(
|
||||
PlayerUiState(
|
||||
playbackState = playbackState,
|
||||
positionMs = currentPositionMs.inWholeMilliseconds,
|
||||
durationMs = audioPlayer.duration.inWholeMilliseconds,
|
||||
)
|
||||
}.stateIn(
|
||||
scope = viewModelScope,
|
||||
@@ -91,6 +92,6 @@ class PlayerViewModel(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val POSITION_POLL_INTERVAL = 200.milliseconds
|
||||
private val POSITION_POLL_INTERVAL = 50.milliseconds
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user