From d337e49a64c48ad7d12430c4ef41ea1b43a6ff31 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Wed, 23 Sep 2026 07:29:06 +0000 Subject: [PATCH] overlay the artist name on the image with a fading header --- .../ui/library/ArtistDetailScreen.kt | 55 +++++++++++++------ .../com/subtracks/ui/library/LibraryScreen.kt | 2 +- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/app/src/main/kotlin/com/subtracks/ui/library/ArtistDetailScreen.kt b/app/src/main/kotlin/com/subtracks/ui/library/ArtistDetailScreen.kt index 503450b7..db6bec03 100644 --- a/app/src/main/kotlin/com/subtracks/ui/library/ArtistDetailScreen.kt +++ b/app/src/main/kotlin/com/subtracks/ui/library/ArtistDetailScreen.kt @@ -1,5 +1,6 @@ package com.subtracks.ui.library +import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -15,6 +16,7 @@ import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.itemsIndexed +import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.rounded.ArrowBack @@ -26,7 +28,9 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.BlurredEdgeTreatment @@ -35,6 +39,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shadow +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -78,8 +83,30 @@ fun ArtistDetailScreen( onAlbumClick: (Album) -> Unit, modifier: Modifier = Modifier, ) { + val listState = rememberLazyGridState() + val artHeightPx = with(LocalDensity.current) { ART_HEIGHT.toPx() } + val barFraction by remember { + derivedStateOf { + if (listState.firstVisibleItemIndex > 0) { + 1f + } else { + (listState.firstVisibleItemScrollOffset / artHeightPx).coerceIn(0f, 1f) + } + } + } + val nameStyle = + MaterialTheme.typography.headlineLarge.copy( + shadow = + Shadow( + color = Color.Black.copy(alpha = 0.8f), + offset = Offset(0f, 2f), + blurRadius = 10f, + ), + ) + Box(modifier.fillMaxSize()) { LazyVerticalGrid( + state = listState, columns = GridCells.Fixed(2), contentPadding = PaddingValues(bottom = 16.dp), horizontalArrangement = Arrangement.spacedBy(12.dp), @@ -93,6 +120,14 @@ fun ArtistDetailScreen( name = artist?.name.orEmpty(), modifier = Modifier.fillMaxWidth().height(ART_HEIGHT), ) + Text( + text = artist?.name.orEmpty(), + style = nameStyle, + color = Color.White, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.align(Alignment.BottomStart).padding(16.dp), + ) } } itemsIndexed(albums, key = { _, album -> album.id }) { index, album -> @@ -130,15 +165,8 @@ fun ArtistDetailScreen( title = { Text( text = artist?.name.orEmpty(), - style = - MaterialTheme.typography.headlineLarge.copy( - shadow = - Shadow( - color = Color.Black.copy(alpha = 0.8f), - offset = Offset(0f, 2f), - blurRadius = 10f, - ), - ), + style = nameStyle, + color = Color.White.copy(alpha = barFraction), maxLines = 1, overflow = TextOverflow.Ellipsis, ) @@ -163,13 +191,8 @@ fun ArtistDetailScreen( } } }, - colors = - TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - titleContentColor = Color.White, - navigationIconContentColor = Color.White, - ), - modifier = Modifier.align(Alignment.TopStart), + colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent), + modifier = Modifier.align(Alignment.TopStart).background(Color.Black.copy(alpha = barFraction)), ) } } diff --git a/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt b/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt index 4fb50304..456a3d1f 100644 --- a/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt +++ b/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt @@ -204,7 +204,7 @@ fun LibraryScreen( tint = MaterialTheme.colorScheme.onBackground, modifier = Modifier - .padding(start = 12.dp, top = titleTop + (titleLineHeight - logoSize) / 2) + .padding(start = 20.dp, top = titleTop + (titleLineHeight - logoSize) / 2) .size(logoSize), ) Text(