add mobile androida and ios apps

This commit is contained in:
2026-05-18 22:30:45 +02:00
parent 0e40a23828
commit 6146bf18b0
32 changed files with 1594 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
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()
}
}