feat(android): pinned similar artists tap through to library; note Following view idea
Pinned similar artists (Deezer related) were non-clickable on Android because Deezer artists carry no Navidrome id. On tap, resolve the name against the library (exact case-insensitive match) and navigate to that Navidrome artist if present, else a short "not in your library" toast. Also: extend the CHANGELOG "Artist following" backlog idea with a dedicated "Following" view (grid of followed artists) + follow/unfollow toggle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
26de85a140
commit
803331e807
3 files changed
+26
-1
No files matched your search
@@ -51,6 +51,7 @@ import com.novasonic.app.ui.component.ItunesDownloadSheet
|
||||
import com.novasonic.app.ui.component.SongRow
|
||||
import com.novasonic.app.ui.theme.*
|
||||
import com.novasonic.app.viewmodel.ArtistViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun ArtistDetailScreen(
|
||||
@@ -66,6 +67,7 @@ fun ArtistDetailScreen(
|
||||
val vm: ArtistViewModel = viewModel()
|
||||
val state by vm.state.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
BackHandler(enabled = state.partialAlbum != null) { vm.dismissPartialAlbum() }
|
||||
BackHandler(enabled = state.subAlbumItem != null && state.partialAlbum == null) { vm.dismissSubAlbum() }
|
||||
@@ -340,7 +342,17 @@ fun ArtistDetailScreen(
|
||||
items(state.pinnedRelated, key = { it.artistId ?: 0L }) { rel ->
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.width(70.dp),
|
||||
modifier = Modifier
|
||||
.width(70.dp)
|
||||
// Deezer-related has no Navidrome id → resolve by name on tap; navigate
|
||||
// if the artist is in the library, else say so.
|
||||
.clickable {
|
||||
scope.launch {
|
||||
val id = vm.libraryArtistId(rel.artistName)
|
||||
if (id != null && onArtistClick != null) onArtistClick(id)
|
||||
else Toast.makeText(context, "Nicht in deiner Bibliothek", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
},
|
||||
) {
|
||||
AsyncImage(
|
||||
model = rel.artworkUrl100,
|
||||
|
||||
@@ -354,6 +354,18 @@ class ArtistViewModel(app: Application, savedState: SavedStateHandle) : AndroidV
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a (Deezer-related) artist name to a Navidrome library artist id, so a pinned artist's
|
||||
* "Similar" chips are tappable when that artist is actually in the library. Exact name match only
|
||||
* (case-insensitive) to avoid navigating to the wrong artist; null if not in the library.
|
||||
*/
|
||||
suspend fun libraryArtistId(name: String?): String? {
|
||||
val n = name?.trim()?.lowercase() ?: return null
|
||||
if (n.isEmpty()) return null
|
||||
val res = runCatching { repo.search(n) }.getOrNull() ?: return null
|
||||
return res.artist.firstOrNull { it.name.trim().lowercase() == n }?.id
|
||||
}
|
||||
|
||||
fun clearPin() {
|
||||
val id = artistId ?: return
|
||||
viewModelScope.launch {
|
||||
|
||||
Reference in new issue
Block a user