Change now playing layout with better animations

This commit is contained in:
Damontecres 2026-03-15 09:34:13 -04:00
parent 3e043d5118
commit 8ddd3fc7eb
No known key found for this signature in database
2 changed files with 110 additions and 89 deletions

View file

@ -5,7 +5,6 @@ import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -25,7 +24,7 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
@Composable @Composable
fun BoxScope.BarVisualizer( fun BarVisualizer(
data: IntArray, data: IntArray,
modifier: Modifier, modifier: Modifier,
) { ) {

View file

@ -9,6 +9,8 @@ import androidx.annotation.OptIn
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.expandHorizontally import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkHorizontally import androidx.compose.animation.shrinkHorizontally
import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically import androidx.compose.animation.slideOutVertically
@ -16,12 +18,13 @@ import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@ -163,96 +166,115 @@ fun NowPlayingPage(
.onPreviewKeyEvent(keyHandler::onKeyEvent) .onPreviewKeyEvent(keyHandler::onKeyEvent)
.focusRequester(focusRequester) .focusRequester(focusRequester)
.focusable(), .focusable(),
) { )
AnimatedVisibility( Row(
musicPrefs.showAlbumArt, horizontalArrangement = Arrangement.Start,
modifier = verticalAlignment = Alignment.CenterVertically,
Modifier modifier = Modifier.fillMaxSize(),
.padding(32.dp)
.fillMaxWidth(.5f)
.align(Alignment.CenterStart),
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
AsyncImage(
contentDescription = null,
model = current?.imageUrl,
modifier =
Modifier
.height(320.dp)
.clip(RoundedCornerShape(16.dp)),
)
current?.title?.let {
Text(
text = it,
style = MaterialTheme.typography.titleLarge,
)
}
current?.albumTitle?.let {
Text(
text = it,
style = MaterialTheme.typography.titleMedium,
)
}
current?.artistNames?.let {
Text(
text = it,
style = MaterialTheme.typography.titleMedium,
)
}
}
}
AnimatedVisibility(
musicPrefs.showVisualizer,
modifier =
Modifier
.padding(horizontal = 32.dp)
.fillMaxHeight(.75f)
.align(Alignment.CenterStart),
) {
val visualizerWidth by animateFloatAsState(if (musicPrefs.showLyrics && state.hasLyrics) .5f else 1f)
BarVisualizer(
data = viz,
modifier =
Modifier
.fillMaxHeight()
.fillMaxWidth(visualizerWidth)
.align(Alignment.CenterStart),
)
}
}
AnimatedVisibility(
visible = musicPrefs.showLyrics && state.hasLyrics,
enter = expandHorizontally(expandFrom = Alignment.End),
exit = shrinkHorizontally(shrinkTowards = Alignment.End),
modifier = Modifier.align(Alignment.CenterEnd),
) { ) {
Box( Box(
contentAlignment = Alignment.Center, modifier = Modifier.wrapContentWidth(),
modifier =
Modifier
.fillMaxWidth(.5f)
.fillMaxHeight(),
) { ) {
LyricsContent( val enter =
lyrics = state.lyrics, remember {
currentLyricPosition = state.currentLyricIndex, expandHorizontally(expandFrom = Alignment.Start) + fadeIn()
lyricsHaveFocus = lyricsHaveFocus, }
onFocusLyrics = { lyricsHaveFocus = it }, val exit =
onClick = { remember {
it.start shrinkHorizontally(shrinkTowards = Alignment.Start) + fadeOut()
?.ticks }
?.inWholeMilliseconds androidx.compose.animation.AnimatedVisibility(
?.let { player.seekTo(it) } visible = musicPrefs.showAlbumArt,
}, enter = enter,
exit = exit,
modifier = modifier =
Modifier Modifier
.padding(vertical = 120.dp) .padding(32.dp),
.fillMaxHeight() ) {
.width(320.dp), Column(
) horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.fillMaxWidth(.5f),
) {
AsyncImage(
contentDescription = null,
model = current?.imageUrl,
modifier =
Modifier
.size(320.dp)
.clip(RoundedCornerShape(16.dp)),
)
current?.title?.let {
Text(
text = it,
style = MaterialTheme.typography.titleLarge,
)
}
current?.albumTitle?.let {
Text(
text = it,
style = MaterialTheme.typography.titleMedium,
)
}
current?.artistNames?.let {
Text(
text = it,
style = MaterialTheme.typography.titleMedium,
)
}
}
}
androidx.compose.animation.AnimatedVisibility(
visible = musicPrefs.showVisualizer,
enter = enter,
exit = exit,
modifier =
Modifier
.padding(horizontal = 32.dp)
.align(Alignment.CenterStart),
) {
val visualizerWidth by animateFloatAsState(if (musicPrefs.showLyrics && state.hasLyrics) .5f else 1f)
BarVisualizer(
data = viz,
modifier =
Modifier
.fillMaxHeight(.75f)
.fillMaxWidth(visualizerWidth)
.align(Alignment.CenterStart),
)
}
}
AnimatedVisibility(
visible = musicPrefs.showLyrics && state.hasLyrics,
enter = expandHorizontally(expandFrom = Alignment.End),
exit = shrinkHorizontally(shrinkTowards = Alignment.End),
modifier = Modifier,
) {
Box(
contentAlignment = Alignment.Center,
modifier =
Modifier
.padding(horizontal = 32.dp, vertical = 100.dp)
.fillMaxHeight(),
) {
LyricsContent(
lyrics = state.lyrics,
currentLyricPosition = state.currentLyricIndex,
lyricsHaveFocus = lyricsHaveFocus,
onFocusLyrics = { lyricsHaveFocus = it },
onClick = {
it.start
?.ticks
?.inWholeMilliseconds
?.let { player.seekTo(it) }
},
modifier =
Modifier
.fillMaxSize(),
// .width(360.dp),
)
}
} }
} }
val showContextForItem = val showContextForItem =