Version 1.4 - Translations, Like toasts Queue redesign.

This commit is contained in:
2026-04-09 16:54:41 +02:00
parent ec1ffcb0b1
commit 5f3902cb54
30 changed files with 3472 additions and 654 deletions
@@ -59,7 +59,7 @@ struct ArtistDetailView: View {
.toolbarColorScheme(.dark, for: .navigationBar)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
FavoriteButton(uri: artist.uri, size: 22, showInLight: true)
FavoriteButton(uri: artist.uri, size: 22, showInLight: true, itemName: artist.name)
}
}
.task(id: "albums-\(artist.uri)") {
@@ -128,43 +128,6 @@ struct ArtistDetailView: View {
// MARK: - Artist Header
/// All distinct music providers for this artist.
/// Uses the authoritative provider_mappings field from MA when available,
/// and falls back to scanning loaded album metadata.
private var artistProviders: [MusicProvider] {
var seen = Set<MusicProvider>()
var result = [MusicProvider]()
// Primary: provider_mappings from the artist object (available immediately)
for mapping in artist.providerMappings {
if let p = MusicProvider.from(providerKey: mapping.providerDomain), !seen.contains(p) {
seen.insert(p)
result.append(p)
}
}
// Fallback: scan loaded albums when providerMappings is empty
if result.isEmpty {
for album in albums {
if let scheme = album.uri.components(separatedBy: "://").first,
let p = MusicProvider.from(scheme: scheme),
p != .library,
!seen.contains(p) {
seen.insert(p)
result.append(p)
}
for key in album.metadata?.images?.compactMap({ $0.provider }) ?? [] {
if let p = MusicProvider.from(providerKey: key), !seen.contains(p) {
seen.insert(p)
result.append(p)
}
}
}
}
return result
}
@ViewBuilder
private var artistHeader: some View {
VStack(spacing: 12) {
@@ -185,20 +148,6 @@ struct ArtistDetailView: View {
.clipShape(Circle())
.shadow(color: .black.opacity(0.5), radius: 20, y: 10)
// One badge per distinct source
if !artistProviders.isEmpty {
HStack(spacing: 4) {
ForEach(artistProviders, id: \.self) { provider in
Image(systemName: provider.icon)
.font(.system(size: 9, weight: .bold))
.foregroundStyle(.white)
.frame(width: 20, height: 20)
.background(.black.opacity(0.55))
.clipShape(Circle())
}
}
}
if !albums.isEmpty {
Text("\(albums.count) albums")
.font(.subheadline)