fix(android): show artist images in Apple-Music search (Erkunden)
iTunes artist entities carry no artwork, so search results rendered as bare grey circles. Mirror the web PWA: after showing results, fetch one album per artist and borrow its cover (entity=album, limit=1), applied only if the user is still viewing the same artist set. Also give ArtistCard a Person-icon fallback instead of an empty grey dot, and fall back to the artist id for Subsonic (library) artist covers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
03bc736725
commit
03046cd631
2 files changed
+48
-6
No files matched your search
@@ -283,7 +283,9 @@ private fun LibrarySearchContent(
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
items(artists, key = { it.id }) { a ->
|
||||
ArtistCard(name = a.name, imageUrl = coverUrl(a.coverArt)) { onArtistClick(a) }
|
||||
// search3 artist results usually omit coverArt → fall back to the artist
|
||||
// id, which Navidrome's getCoverArt accepts and resolves to the artist image.
|
||||
ArtistCard(name = a.name, imageUrl = coverUrl(a.coverArt ?: a.id)) { onArtistClick(a) }
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(8.dp))
|
||||
@@ -597,15 +599,27 @@ private fun ArtistCard(name: String, imageUrl: String?, onClick: () -> Unit) {
|
||||
.width(80.dp)
|
||||
.clickable(onClick = onClick),
|
||||
) {
|
||||
AsyncImage(
|
||||
model = imageUrl,
|
||||
contentDescription = name,
|
||||
contentScale = ContentScale.Crop,
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier
|
||||
.size(72.dp)
|
||||
.clip(androidx.compose.foundation.shape.CircleShape)
|
||||
.background(NsSurface2),
|
||||
) {
|
||||
if (imageUrl != null) {
|
||||
AsyncImage(
|
||||
model = imageUrl,
|
||||
contentDescription = name,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
Icons.Default.Person, contentDescription = null,
|
||||
tint = NsOnSurface2, modifier = Modifier.size(32.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(6.dp))
|
||||
Text(
|
||||
name, fontFamily = Outfit, fontSize = 12.sp, fontWeight = FontWeight.Medium,
|
||||
|
||||
@@ -110,18 +110,46 @@ class ExploreViewModel(app: Application) : AndroidViewModel(app) {
|
||||
try {
|
||||
val resp = ItunesClient.search(term)
|
||||
val results = resp.results
|
||||
val artists = results.filter { it.wrapperType == "artist" }
|
||||
_state.value = _state.value.copy(
|
||||
artists = results.filter { it.wrapperType == "artist" },
|
||||
artists = artists,
|
||||
albums = results.filter { it.wrapperType == "collection" },
|
||||
tracks = results.filter { it.wrapperType == "track" && it.kind == "song" },
|
||||
isSearching = false,
|
||||
)
|
||||
enrichArtistArt(artists)
|
||||
} catch (e: Exception) {
|
||||
_state.value = _state.value.copy(isSearching = false, error = e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* iTunes artist entities carry no artwork, so search results render as grey circles. Mirror the
|
||||
* web PWA: fetch one album per artist and borrow its cover. Runs after the main results are shown
|
||||
* (list appears instantly) and only applies if the user is still viewing the same artist set.
|
||||
*/
|
||||
private fun enrichArtistArt(artists: List<ItunesItem>) {
|
||||
if (artists.none { it.artworkUrl100.isNullOrBlank() && it.artistName != null }) return
|
||||
viewModelScope.launch {
|
||||
val enriched = artists.map { a ->
|
||||
async {
|
||||
if (!a.artworkUrl100.isNullOrBlank()) return@async a
|
||||
val name = a.artistName ?: return@async a
|
||||
val art = runCatching {
|
||||
ItunesClient.search(name, entity = "album", limit = 1).results
|
||||
.firstOrNull { it.wrapperType == "collection" }?.artworkUrl100
|
||||
}.getOrNull()
|
||||
if (art != null) a.copy(artworkUrl100 = art) else a
|
||||
}
|
||||
}.awaitAll()
|
||||
val cur = _state.value.artists
|
||||
if (cur.map { it.artistId } == artists.map { it.artistId }) {
|
||||
_state.value = _state.value.copy(artists = enriched)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadAlbum(album: ItunesItem) {
|
||||
val id = album.collectionId ?: return
|
||||
viewModelScope.launch {
|
||||
|
||||
Reference in new issue
Block a user