package at.lockstep.player.ui import androidx.compose.foundation.layout.Arrangement 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.padding import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Pause import androidx.compose.material.icons.filled.PlayArrow import androidx.compose.material.icons.filled.SkipNext import androidx.compose.material.icons.filled.SkipPrevious import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp data class NowPlayingUiState( val title: String, val artist: String, /** 0f..1f until real timing is wired to Oboe / JNI. */ val progress: Float, /** Total track length in seconds (placeholder for UI formatting). */ val durationSeconds: Int, val isPlaying: Boolean, ) @Composable fun NowPlayingScreen( state: NowPlayingUiState, onProgressChange: (Float) -> Unit, onPrevious: () -> Unit, onTogglePlayPause: () -> Unit, onNext: () -> Unit, modifier: Modifier = Modifier, ) { val elapsed = (state.progress * state.durationSeconds).toInt().coerceIn(0, state.durationSeconds) Column( modifier = modifier .fillMaxSize() .padding(horizontal = 24.dp, vertical = 16.dp), verticalArrangement = Arrangement.spacedBy(24.dp), ) { Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { Text( text = state.title, style = MaterialTheme.typography.headlineSmall, maxLines = 2, overflow = TextOverflow.Ellipsis, ) Text( text = state.artist, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1, overflow = TextOverflow.Ellipsis, ) } Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(12.dp), ) { Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(4.dp), ) { Slider( value = state.progress, onValueChange = onProgressChange, modifier = Modifier.fillMaxWidth(), ) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = formatMmSs(elapsed), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, ) Text( text = formatMmSs(state.durationSeconds), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, ) } } Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly, verticalAlignment = Alignment.CenterVertically, ) { IconButton(onClick = onPrevious, modifier = Modifier.size(80.dp)) { Icon(Icons.Default.SkipPrevious, contentDescription = "Previous track") } IconButton(onClick = onTogglePlayPause, modifier = Modifier.size(104.dp)) { Icon( imageVector = if (state.isPlaying) Icons.Default.Pause else Icons.Default.PlayArrow, contentDescription = if (state.isPlaying) "Pause" else "Play", modifier = Modifier.size(56.dp), ) } IconButton(onClick = onNext, modifier = Modifier.size(80.dp)) { Icon(Icons.Default.SkipNext, contentDescription = "Next track") } } } } } private fun formatMmSs(totalSeconds: Int): String { val s = totalSeconds.coerceAtLeast(0) val m = s / 60 val r = s % 60 return "%d:%02d".format(m, r) } @Preview(showBackground = true) @Composable private fun NowPlayingScreenPreview() { MaterialTheme { var progress by remember { mutableFloatStateOf(0.35f) } var playing by remember { mutableStateOf(true) } NowPlayingScreen( state = NowPlayingUiState( title = "Example Track Title", artist = "Example Artist", progress = progress, durationSeconds = 215, isPlaying = playing, ), onProgressChange = { progress = it }, onPrevious = {}, onTogglePlayPause = { playing = !playing }, onNext = {}, ) } }