import SwiftUI struct NowPlayingView: View { @StateObject private var viewModel = NowPlayingController() var body: some View { VStack(spacing: 0) { Spacer() coverArtSection trackInfoSection .padding(.horizontal) Spacer() playbackControls volumeSlider .padding(.horizontal) statusFooter .padding() } .onAppear { viewModel.connect() } .onChange(of: viewModel.volume) { _, _ in // slider binding handles this } } // MARK: - Sections private var coverArtSection: some View { ZStack { if let image = viewModel.coverArt { Image(uiImage: image) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 280, height: 280) .clipShape(RoundedRectangle(cornerRadius: 16)) } else { RoundedRectangle(cornerRadius: 16) .fill(Color.gray.opacity(0.2)) .frame(width: 280, height: 280) .overlay( Image(systemName: "music.note") .font(.system(size: 60)) .foregroundColor(.gray.opacity(0.5)) ) } } .padding(.vertical, 40) } private var trackInfoSection: some View { VStack(alignment: .leading, spacing: 8) { Text(viewModel.currentTrack?.name ?? "No track") .font(.title.bold()) .foregroundColor(.white) if let artists = viewModel.currentTrack?.artistNames, !artists.isEmpty { Text(artists.joined(separator: ", ")) .font(.title3) .foregroundColor(.gray) } if let album = viewModel.currentTrack?.album?.name { Text(album) .font(.subheadline) .foregroundColor(.gray.opacity(0.7)) } } } private var playbackControls: some View { HStack(spacing: 40) { Button(action: {}) { Image(systemName: "backward.fill") .font(.title) .foregroundColor(.gray) } Button(action: { viewModel.togglePlay() }) { Image(systemName: viewModel.isPlaying ? "pause.circle.fill" : "play.circle.fill") .font(.system(size: 72)) .foregroundColor(.white) } Button(action: {}) { Image(systemName: "forward.fill") .font(.title) .foregroundColor(.gray) } } .padding(.vertical, 30) } private var volumeSlider: some View { HStack { Image(systemName: "speaker.fill") .foregroundColor(.gray) Slider(value: $viewModel.volume, in: 0...100) .onChange(of: viewModel.volume) { newValue in viewModel.setVolume(newValue) } Image(systemName: "speaker.wave.3.fill") .foregroundColor(.gray) } .padding(.vertical, 10) } private var statusFooter: some View { HStack { Circle() .fill(viewModel.isPlaying ? Color.green : Color.red) .frame(width: 8, height: 8) Text(viewModel.connectionStatus) .font(.caption) .foregroundColor(.gray) Spacer() NavigationLink(destination: SettingsView()) { Image(systemName: "gear") .foregroundColor(.gray) } } } } struct NowPlayingView_Previews: PreviewProvider { static var previews: some View { NowPlayingView() } }