NavidromeApp/watchOS/Views/WatchSetupView.swift

173 lines
5.7 KiB
Swift
Raw Normal View History

import SwiftUI
struct WatchSetupView: View {
@EnvironmentObject var watchManager: WatchSessionManager
@State private var showManualAdd = false
@State private var isSyncing = false
@State private var syncMessage = ""
var body: some View {
ScrollView {
VStack(spacing: 16) {
Image(systemName: "music.note.house.fill")
.font(.system(size: 36))
.foregroundColor(.pink)
Text("Navidrome")
.font(.headline)
Text("Set up your server to play music on your watch.")
.font(.caption2)
.foregroundColor(.gray)
.multilineTextAlignment(.center)
.padding(.horizontal)
// Sync from iPhone
Button(action: syncFromPhone) {
HStack {
if isSyncing {
ProgressView()
.scaleEffect(0.7)
}
Text(isSyncing ? "Syncing..." : "Sync from iPhone")
}
}
.buttonStyle(.borderedProminent)
.tint(.pink)
.disabled(isSyncing)
if !syncMessage.isEmpty {
Text(syncMessage)
.font(.caption2)
.foregroundColor(syncMessage.contains("Error") ? .red : .green)
}
Divider()
// Manual add
Button("Add Server Manually") {
showManualAdd = true
}
.font(.caption)
if watchManager.isPhoneReachable {
HStack(spacing: 4) {
Circle()
.fill(.green)
.frame(width: 6, height: 6)
Text("iPhone connected")
.font(.caption2)
.foregroundColor(.gray)
}
} else {
HStack(spacing: 4) {
Circle()
.fill(.orange)
.frame(width: 6, height: 6)
Text("iPhone not reachable")
.font(.caption2)
.foregroundColor(.gray)
}
}
}
.padding()
}
.sheet(isPresented: $showManualAdd) {
WatchAddServerView()
}
}
private func syncFromPhone() {
isSyncing = true
syncMessage = ""
watchManager.requestServersFromPhone()
// Check result after delay
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
isSyncing = false
if !watchManager.servers.isEmpty {
syncMessage = "Synced \(watchManager.servers.count) server(s)"
} else if !watchManager.isPhoneReachable {
syncMessage = "Error: iPhone not reachable"
} else {
syncMessage = "Error: No servers found"
}
}
}
}
// MARK: - Manual Add Server
struct WatchAddServerView: View {
@EnvironmentObject var watchManager: WatchSessionManager
@Environment(\.dismiss) private var dismiss
@State private var name = ""
@State private var url = ""
@State private var username = ""
@State private var password = ""
@State private var isTesting = false
@State private var testResult = ""
var body: some View {
ScrollView {
VStack(spacing: 10) {
Text("Add Server")
.font(.headline)
TextField("Name", text: $name)
TextField("URL", text: $url)
.textContentType(.URL)
TextField("Username", text: $username)
SecureField("Password", text: $password)
Button(action: testAndSave) {
if isTesting {
ProgressView().scaleEffect(0.7)
} else {
Text("Connect")
}
}
.buttonStyle(.borderedProminent)
.tint(.pink)
.disabled(url.isEmpty || username.isEmpty || isTesting)
if !testResult.isEmpty {
Text(testResult)
.font(.caption2)
.foregroundColor(testResult.contains("Success") ? .green : .red)
}
}
.padding()
}
}
private func testAndSave() {
isTesting = true
testResult = ""
let server = ServerConfig(
name: name.isEmpty ? "My Server" : name,
url: url.trimmingCharacters(in: CharacterSet(charactersIn: "/")),
username: username,
password: password
)
Task {
let ok = await watchManager.testConnection(server)
await MainActor.run {
isTesting = false
if ok {
testResult = "Success!"
watchManager.addServer(server)
watchManager.setActive(server)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
dismiss()
}
} else {
testResult = "Connection failed"
}
}
}
}
}