git-subtree-dir: osx git-subtree-mainline:034026e88agit-subtree-split:46755a07ef
111 lines
3.1 KiB
Swift
111 lines
3.1 KiB
Swift
//
|
|
// PreferencesView.swift
|
|
// kordophone2
|
|
//
|
|
// Created by James Magahern on 8/24/25.
|
|
//
|
|
|
|
import KeychainAccess
|
|
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()
|
|
private let keychain = Keychain(service: "net.buzzert.kordophonecd")
|
|
|
|
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
|
|
self.password = keychain[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
|
|
))
|
|
}
|
|
|
|
keychain[username] = password
|
|
} catch {
|
|
print("Error saving settings: \(error)")
|
|
}
|
|
|
|
autosave()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|