fix: enrich player track info from API + share button feedback

PlayerTrackInfoView auto-fetches full release data when current track
is missing audio/lastfm fields (e.g. after device transfer). Share
button turns green with checkmark for 1.5s after copying URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ultradesu
2026-06-09 11:00:51 +01:00
parent 88297cbc91
commit 80aa04f625
2 changed files with 29 additions and 3 deletions
+11 -3
View File
@@ -36,6 +36,7 @@ struct ContentView: View {
@State private var showingQueue = false
@State private var showingDevices = false
@State private var remoteSeekOverride: Double? = nil // optimistic seek for client mode
@State private var shareCopied = false
// ViewModels bound to session (optional)
@State private var globalVM: GlobalArtistsViewModel?
@@ -560,9 +561,11 @@ struct ContentView: View {
.disabled(player.currentTrack == nil)
Button(action: shareCurrentTrack) {
Image(systemName: "square.and.arrow.up").font(.system(size: 14))
Image(systemName: shareCopied ? "checkmark" : "square.and.arrow.up")
.font(.system(size: 14))
}
.buttonStyle(.plain).foregroundColor(.secondary)
.buttonStyle(.plain)
.foregroundColor(shareCopied ? .green : .secondary)
.disabled(player.currentTrack == nil)
Button(action: { showingTrackInfo.toggle() }) {
@@ -572,7 +575,7 @@ struct ContentView: View {
.disabled(player.currentTrack == nil)
.popover(isPresented: $showingTrackInfo, arrowEdge: .bottom) {
if let track = player.currentTrack {
TrackInfoView(track: track)
PlayerTrackInfoView(track: track, service: authManager.catalogService)
}
}
@@ -706,6 +709,11 @@ struct ContentView: View {
let url = "\(baseUrl.trimmingCharacters(in: CharacterSet(charactersIn: "/")))/share/track/\(track.id)"
NSPasteboard.general.clearContents()
NSPasteboard.general.setString(url, forType: .string)
withAnimation(.easeIn(duration: 0.1)) { shareCopied = true }
Task {
try? await Task.sleep(nanoseconds: 1_500_000_000)
withAnimation(.easeOut(duration: 0.4)) { shareCopied = false }
}
}
}
+18
View File
@@ -5,6 +5,24 @@
import SwiftUI
/// Wrapper used by the player bar enriches track data from the API if fields are missing
struct PlayerTrackInfoView: View {
let track: TrackCard
let service: CatalogService?
@State private var enriched: TrackCard?
var body: some View {
TrackInfoView(track: enriched ?? track)
.task(id: track.id) {
guard track.audioFormat == nil, track.releaseId > 0, let service else { return }
guard let detail = try? await service.releaseDetail(id: track.releaseId),
let full = detail.tracks.first(where: { $0.id == track.id }) else { return }
enriched = full
}
}
}
struct TrackInfoView: View {
let track: TrackCard