// // MiniPlayerView.swift // Mobile Music Assistant // // Created by Sven Hanold on 26.03.26. // import SwiftUI struct MiniPlayerView: View { @Environment(MAService.self) private var service let audioPlayer: MAAudioPlayer @Binding var isExpanded: Bool var body: some View { HStack(spacing: 12) { // Album Art Thumbnail if let item = audioPlayer.currentItem, let mediaItem = item.mediaItem, let imageUrl = mediaItem.imageUrl { let coverURL = service.imageProxyURL(path: imageUrl, size: 128) CachedAsyncImage(url: coverURL) { image in image .resizable() .aspectRatio(contentMode: .fill) } placeholder: { Rectangle() .fill(Color.gray.opacity(0.2)) } .frame(width: 48, height: 48) .clipShape(RoundedRectangle(cornerRadius: 6)) } else { RoundedRectangle(cornerRadius: 6) .fill(Color.gray.opacity(0.2)) .frame(width: 48, height: 48) .overlay { Image(systemName: "music.note") .foregroundStyle(.secondary) .font(.caption) } } // Track Info VStack(alignment: .leading, spacing: 4) { if let item = audioPlayer.currentItem { Text(item.name) .font(.subheadline) .fontWeight(.medium) .lineLimit(1) if let mediaItem = item.mediaItem, let artists = mediaItem.artists, !artists.isEmpty { Text(artists.map { $0.name }.joined(separator: ", ")) .font(.caption) .foregroundStyle(.secondary) .lineLimit(1) } } else { Text("No Track") .font(.subheadline) .fontWeight(.medium) .lineLimit(1) } } Spacer() // Play/Pause Button Button { if audioPlayer.isPlaying { audioPlayer.pause() } else { audioPlayer.play() } } label: { Image(systemName: audioPlayer.isPlaying ? "pause.fill" : "play.fill") .font(.title3) .foregroundStyle(.primary) } .padding(.trailing, 8) } .padding(12) .background(Color(.systemBackground)) .clipShape(RoundedRectangle(cornerRadius: 12)) .shadow(radius: 5) .padding(.horizontal) .padding(.bottom, 8) .contentShape(Rectangle()) .onTapGesture { isExpanded = true } } } #Preview { MiniPlayerView( audioPlayer: MAAudioPlayer(service: MAService()), isExpanded: .constant(false) ) .environment(MAService()) }