Files
aris-old/IrisCompanion/iris/Views/SettingsView.swift

152 lines
5.5 KiB
Swift
Raw Normal View History

//
// SettingsView.swift
// iris
//
// Settings UI for music source selection and Spotify connection.
//
import MusicKit
import SwiftUI
@available(iOS 16.0, *)
struct SettingsView: View {
@EnvironmentObject private var orchestrator: ContextOrchestrator
@EnvironmentObject private var spotifyAuth: SpotifyAuthManager
var body: some View {
NavigationStack {
List {
Section("Music Source") {
Picker("Source", selection: Binding(
get: { orchestrator.musicSource },
set: { newValue in
if newValue == .spotify && !spotifyAuth.isConnected {
return
}
orchestrator.musicSource = newValue
}
)) {
ForEach(MusicSource.allCases, id: \.self) { source in
Text(source.displayName).tag(source)
}
}
.pickerStyle(.segmented)
if !spotifyAuth.isConnected {
Text("Connect Spotify below to enable it as a source")
.font(.caption)
.foregroundStyle(.secondary)
}
}
Section {
if spotifyAuth.isConnected {
HStack {
Label("Connected", systemImage: "checkmark.circle.fill")
.foregroundColor(.green)
Spacer()
}
Button("Disconnect", role: .destructive) {
spotifyAuth.disconnect()
if orchestrator.musicSource == .spotify {
orchestrator.musicSource = .appleMusic
}
}
} else {
Button {
spotifyAuth.startAuth()
} label: {
HStack {
Label("Connect to Spotify", systemImage: "link")
Spacer()
if spotifyAuth.isAuthenticating {
ProgressView()
}
}
}
.disabled(spotifyAuth.isAuthenticating)
}
if let error = spotifyAuth.error {
Text(error)
.font(.caption)
.foregroundColor(.red)
}
} header: {
Text("Spotify")
} footer: {
if !spotifyAuth.isConnected {
Text("Connect your Spotify account to display current track on Glass.")
}
}
Section {
HStack {
Text("Authorization")
Spacer()
Text(authStatusText(orchestrator.musicAuthorization))
.foregroundStyle(.secondary)
}
} header: {
Text("Apple Music")
}
Section {
if let nowPlayingInfo = currentNowPlaying {
VStack(alignment: .leading, spacing: 4) {
Text(nowPlayingInfo.title)
.font(.headline)
if let artist = nowPlayingInfo.artist {
Text(artist)
.font(.subheadline)
.foregroundStyle(.secondary)
}
}
} else {
Text("Nothing playing")
.foregroundStyle(.secondary)
}
} header: {
Text("Now Playing")
} footer: {
Text("Source: \(orchestrator.musicSource.displayName)")
}
}
.navigationTitle("Settings")
}
}
private var currentNowPlaying: (title: String, artist: String?)? {
switch orchestrator.musicSource {
case .appleMusic:
guard let np = orchestrator.nowPlaying else { return nil }
return (np.title, np.artist)
case .spotify:
guard let np = orchestrator.spotifyNowPlaying else { return nil }
return (np.title, np.artist)
}
}
private func authStatusText(_ status: MusicAuthorization.Status) -> String {
switch status {
case .notDetermined: return "Not Determined"
case .denied: return "Denied"
case .restricted: return "Restricted"
case .authorized: return "Authorized"
@unknown default: return "Unknown"
}
}
}
@available(iOS 16.0, *)
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
let ble = BlePeripheralManager()
let spotifyAuth = SpotifyAuthManager()
let orchestrator = ContextOrchestrator(ble: ble, spotifyAuth: spotifyAuth)
SettingsView()
.environmentObject(orchestrator)
.environmentObject(spotifyAuth)
}
}