diff --git a/android/app/src/main/java/com/fabledsword/minstrel/library/ui/AlbumDetailScreen.kt b/android/app/src/main/java/com/fabledsword/minstrel/library/ui/AlbumDetailScreen.kt index 54ce5f00..1fdcc399 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/library/ui/AlbumDetailScreen.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/library/ui/AlbumDetailScreen.kt @@ -222,7 +222,7 @@ private fun AlbumCover(album: AlbumRef) { .background(MaterialTheme.colorScheme.surfaceVariant), contentAlignment = Alignment.Center, ) { - if (album.coverUrl.isEmpty()) { + if (album.id.isEmpty()) { Icon( imageVector = Lucide.Disc3, contentDescription = null, @@ -231,7 +231,7 @@ private fun AlbumCover(album: AlbumRef) { ) } else { AsyncImage( - model = album.coverUrl, + model = album.displayCoverUrl, contentDescription = album.title, modifier = Modifier.fillMaxSize(), ) diff --git a/android/app/src/main/java/com/fabledsword/minstrel/player/ui/MiniPlayer.kt b/android/app/src/main/java/com/fabledsword/minstrel/player/ui/MiniPlayer.kt index de8b1bf4..571cbc54 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/player/ui/MiniPlayer.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/player/ui/MiniPlayer.kt @@ -1,5 +1,6 @@ package com.fabledsword.minstrel.player.ui +import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -21,10 +22,12 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import coil3.compose.AsyncImage import com.composables.icons.lucide.Lucide import com.composables.icons.lucide.Music import com.composables.icons.lucide.Pause @@ -41,9 +44,9 @@ private const val COVER_SIZE_DP = 48 * fresh install. Tapping the body navigates to the full * NowPlayingScreen via [onExpandClick]. * - * Cover art is a placeholder Lucide icon for now — TrackRef carries - * no coverUrl; covers come from the AlbumRef join we'll add in a - * later 5.x slice. AsyncImage / Coil wire-up lands then. + * Cover comes from TrackRef.coverUrl (derived from albumId via the + * BaseUrlInterceptor placeholder); falls back to the Lucide.Music + * icon when the album binding is missing. */ @Composable fun MiniPlayer( @@ -69,14 +72,24 @@ fun MiniPlayer( Box( modifier = Modifier .size(COVER_SIZE_DP.dp) - .clip(RoundedCornerShape(FabledSwordFlatTokens.radiusSm)), + .clip(RoundedCornerShape(FabledSwordFlatTokens.radiusSm)) + .background(MaterialTheme.colorScheme.surfaceVariant), contentAlignment = Alignment.Center, ) { - Icon( - imageVector = Lucide.Music, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant, - ) + if (track.coverUrl.isEmpty()) { + Icon( + imageVector = Lucide.Music, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } else { + AsyncImage( + model = track.coverUrl, + contentDescription = track.title, + modifier = Modifier.size(COVER_SIZE_DP.dp), + contentScale = ContentScale.Crop, + ) + } } Spacer(Modifier.width(12.dp)) Column(modifier = Modifier.weight(1f)) { diff --git a/android/app/src/main/java/com/fabledsword/minstrel/player/ui/NowPlayingScreen.kt b/android/app/src/main/java/com/fabledsword/minstrel/player/ui/NowPlayingScreen.kt index 8798f07b..587cb278 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/player/ui/NowPlayingScreen.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/player/ui/NowPlayingScreen.kt @@ -1,5 +1,6 @@ package com.fabledsword.minstrel.player.ui +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -24,12 +25,14 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController +import coil3.compose.AsyncImage import com.composables.icons.lucide.ListMusic import com.composables.icons.lucide.Lucide import com.composables.icons.lucide.Music @@ -75,7 +78,7 @@ fun NowPlayingScreen( verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { - CoverPlaceholder() + NowPlayingCover(coverUrl = track.coverUrl, contentDescription = track.title) Spacer(Modifier.height(24.dp)) TrackHeader( title = track.title, @@ -112,21 +115,31 @@ private fun ViewQueueButton(onClick: () -> Unit) { } @Composable -private fun CoverPlaceholder() { +private fun NowPlayingCover(coverUrl: String, contentDescription: String) { Box( modifier = Modifier .widthIn(max = COVER_MAX_WIDTH_DP.dp) .fillMaxWidth() .aspectRatio(1f) - .clip(RoundedCornerShape(FabledSwordFlatTokens.radiusLg)), + .clip(RoundedCornerShape(FabledSwordFlatTokens.radiusLg)) + .background(MaterialTheme.colorScheme.surfaceVariant), contentAlignment = Alignment.Center, ) { - Icon( - imageVector = Lucide.Music, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.size(96.dp), - ) + if (coverUrl.isEmpty()) { + Icon( + imageVector = Lucide.Music, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.size(96.dp), + ) + } else { + AsyncImage( + model = coverUrl, + contentDescription = contentDescription, + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop, + ) + } } }