Private
Public Access
1
0
Files
Kordophone/kordophone2/PreferencesView.swift

106 lines
2.9 KiB
Swift

//
// PreferencesView.swift
// kordophone2
//
// Created by James Magahern on 8/24/25.
//
import SwiftUI
struct PreferencesView: View
{
@State var accountSettingsModel = AccountSettings.ViewModel()
var body: some View {
TabView {
AccountSettings(model: $accountSettingsModel)
.tabItem { Label("Account", systemImage: "person.crop.circle") }
}
.frame(width: 480.0, height: 300.0)
.padding(20.0)
}
}
struct AccountSettings: View
{
@Binding var model: ViewModel
var body: some View {
Form {
Section("Server Settings") {
TextField("Server", text: $model.serverURL)
}
Spacer()
.frame(height: 44.0)
Section("Authentication") {
TextField("Username", text: $model.username)
.textContentType(.username)
SecureField("Password", text: $model.password)
.textContentType(.password)
}
}
.task { await model.load() }
}
// MARK: - Types
@Observable
class ViewModel
{
var serverURL: String
var username: String
var password: String
private let xpc = XPCClient()
init(serverURL: String = "", username: String = "", password: String = "") {
self.serverURL = serverURL
self.username = username
self.password = password
autosave()
}
func load() async {
do {
let settings = try await xpc.getSettings()
self.serverURL = settings.serverUrl
self.username = settings.username
} catch {
print("Error getting settings: \(error)")
}
}
private func autosave() {
withObservationTracking {
_ = serverURL
_ = username
_ = password
} onChange: {
Task { @MainActor [weak self] in
guard let self else { return }
do {
let currentSettings = try await xpc.getSettings()
if currentSettings.serverUrl != serverURL || currentSettings.username != username {
try await xpc.setSettings(settings: Serialized.Settings(
serverUrl: serverURL,
username: username
))
}
} catch {
print("Error saving settings: \(error)")
}
autosave()
}
}
}
}
}