feat(android): ArtistDetail avatar falls back to first album cover (parity map)
Ports flutter_client/lib/library/artist_detail_screen.dart:177-208
_ArtistAvatar: server coverUrl wins; when empty, use the first loaded
album's /api/albums/{id}/cover; only show the bare Lucide.User icon
when the artist has neither. Threads detail.albums.firstOrNull()?.id
through ArtistHeader → ArtistAvatar. (Seeded-loading header passes
null since the seed carries no album list.)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+15
-4
@@ -141,6 +141,7 @@ private fun ArtistBody(
|
||||
ArtistHeader(
|
||||
artist = detail.artist,
|
||||
artistLiked = artistLiked,
|
||||
fallbackAlbumId = detail.albums.firstOrNull()?.id,
|
||||
onPlay = onPlay,
|
||||
onToggleLike = onToggleLike,
|
||||
)
|
||||
@@ -161,6 +162,7 @@ private fun ArtistBody(
|
||||
private fun ArtistHeader(
|
||||
artist: ArtistRef,
|
||||
artistLiked: Boolean,
|
||||
fallbackAlbumId: String?,
|
||||
onPlay: () -> Unit,
|
||||
onToggleLike: () -> Unit,
|
||||
) {
|
||||
@@ -171,7 +173,7 @@ private fun ArtistHeader(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
ArtistAvatar(artist)
|
||||
ArtistAvatar(artist, fallbackAlbumId)
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = artist.name,
|
||||
@@ -198,7 +200,16 @@ private fun ArtistHeader(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ArtistAvatar(artist: ArtistRef) {
|
||||
private fun ArtistAvatar(artist: ArtistRef, fallbackAlbumId: String? = null) {
|
||||
// Server coverUrl wins; otherwise mirror the server's "use the
|
||||
// first album's cover" rule via the loaded album list (Flutter
|
||||
// _ArtistAvatar). Bare Lucide.User only when neither exists.
|
||||
val model = when {
|
||||
artist.coverUrl.isNotEmpty() -> artist.coverUrl
|
||||
fallbackAlbumId != null ->
|
||||
"http://placeholder.invalid/api/albums/$fallbackAlbumId/cover"
|
||||
else -> null
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(96.dp)
|
||||
@@ -206,7 +217,7 @@ private fun ArtistAvatar(artist: ArtistRef) {
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
if (artist.coverUrl.isEmpty()) {
|
||||
if (model == null) {
|
||||
Icon(
|
||||
imageVector = Lucide.User,
|
||||
contentDescription = null,
|
||||
@@ -215,7 +226,7 @@ private fun ArtistAvatar(artist: ArtistRef) {
|
||||
)
|
||||
} else {
|
||||
AsyncImage(
|
||||
model = artist.coverUrl,
|
||||
model = model,
|
||||
contentDescription = artist.name,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentScale = ContentScale.Crop,
|
||||
|
||||
Reference in New Issue
Block a user