fix: M3.5 polish — genre splitting, radio button, search focus #24
+15
-4
@@ -141,6 +141,7 @@ private fun ArtistBody(
|
|||||||
ArtistHeader(
|
ArtistHeader(
|
||||||
artist = detail.artist,
|
artist = detail.artist,
|
||||||
artistLiked = artistLiked,
|
artistLiked = artistLiked,
|
||||||
|
fallbackAlbumId = detail.albums.firstOrNull()?.id,
|
||||||
onPlay = onPlay,
|
onPlay = onPlay,
|
||||||
onToggleLike = onToggleLike,
|
onToggleLike = onToggleLike,
|
||||||
)
|
)
|
||||||
@@ -161,6 +162,7 @@ private fun ArtistBody(
|
|||||||
private fun ArtistHeader(
|
private fun ArtistHeader(
|
||||||
artist: ArtistRef,
|
artist: ArtistRef,
|
||||||
artistLiked: Boolean,
|
artistLiked: Boolean,
|
||||||
|
fallbackAlbumId: String?,
|
||||||
onPlay: () -> Unit,
|
onPlay: () -> Unit,
|
||||||
onToggleLike: () -> Unit,
|
onToggleLike: () -> Unit,
|
||||||
) {
|
) {
|
||||||
@@ -171,7 +173,7 @@ private fun ArtistHeader(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
) {
|
) {
|
||||||
ArtistAvatar(artist)
|
ArtistAvatar(artist, fallbackAlbumId)
|
||||||
Column(modifier = Modifier.weight(1f)) {
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
Text(
|
Text(
|
||||||
text = artist.name,
|
text = artist.name,
|
||||||
@@ -198,7 +200,16 @@ private fun ArtistHeader(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@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(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(96.dp)
|
.size(96.dp)
|
||||||
@@ -206,7 +217,7 @@ private fun ArtistAvatar(artist: ArtistRef) {
|
|||||||
.background(MaterialTheme.colorScheme.surfaceVariant),
|
.background(MaterialTheme.colorScheme.surfaceVariant),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
if (artist.coverUrl.isEmpty()) {
|
if (model == null) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Lucide.User,
|
imageVector = Lucide.User,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
@@ -215,7 +226,7 @@ private fun ArtistAvatar(artist: ArtistRef) {
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = artist.coverUrl,
|
model = model,
|
||||||
contentDescription = artist.name,
|
contentDescription = artist.name,
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
|
|||||||
Reference in New Issue
Block a user