From 803331e807eca3ce3a8a6e66c772957ba78cae2e Mon Sep 17 00:00:00 2001 From: Honey Date: Fri, 14 Aug 2026 01:12:47 +0200 Subject: [PATCH] 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 --- CHANGELOG.md | 1 + .../novasonic/app/ui/screen/ArtistDetailScreen.kt | 14 +++++++++++++- .../com/novasonic/app/viewmodel/ArtistViewModel.kt | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9842326..c6d78c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -449,6 +449,7 @@ Primary causes identified: - Open questions: where downloaded-but-temporary tracks live vs. the main library (separate folder + retention job), how Navidrome should/shouldn't index them, and dedupe against tracks you already own. - **Web + Android** — **Artist following + new-release & concert notifications** — follow artists and get notified when they drop something new or play nearby. Idea: - A **follow list** of artists (stored per user, e.g. in app settings / a small backend table). + - A **"Following" view** listing all artists you follow (grid of artist photos), as an entry point to their pages — a dedicated overview so you can see and manage who you follow, plus a follow/unfollow toggle on the artist page. - **New-release alerts:** periodic check for new albums/singles by followed artists (sources: iTunes lookup / MusicBrainz / Last.fm), surfaced in the existing in-app notification bell (and optionally push). - **Concert alerts:** reuse the existing **Ticketmaster** events integration to notify when a followed artist has nearby/upcoming shows. - Ties into the importer: a "download this new release" action straight from the notification. diff --git a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ArtistDetailScreen.kt b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ArtistDetailScreen.kt index a0c0f20..332adc4 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ArtistDetailScreen.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ArtistDetailScreen.kt @@ -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, diff --git a/android/app/src/main/kotlin/com/novasonic/app/viewmodel/ArtistViewModel.kt b/android/app/src/main/kotlin/com/novasonic/app/viewmodel/ArtistViewModel.kt index b178725..618a99d 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/viewmodel/ArtistViewModel.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/viewmodel/ArtistViewModel.kt @@ -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 {