Selected server and better settings

This commit is contained in:
2025-06-10 23:10:13 -07:00
parent 0cdbecc031
commit 7e6d449c52
2 changed files with 89 additions and 27 deletions

View File

@@ -7,7 +7,7 @@
import Foundation
struct Server: Identifiable, Codable
struct Server: Identifiable, Codable, Equatable
{
let serviceName: String?
let baseURL: URL

View File

@@ -9,44 +9,106 @@ import Foundation
struct Settings
{
var configuredServers: [Server]
var selectedServer: Server?
var configuredServers: [Server] {
willSet {
// Set selected server to whatever the first server is, if we're adding the first one.
if configuredServers.isEmpty && !newValue.isEmpty && selectedServer == nil {
selectedServer = newValue.first
}
// If the selected server is being removed, set it to something else
if !newValue.contains(where: { $0 == selectedServer }) {
selectedServer = newValue.first // nil if empty
}
}
}
var isConfigured: Bool { !configuredServers.isEmpty }
static func fromDefaults() -> Settings {
let defaults = UserDefaults.standard
return Settings(
selectedServer: defaults[SelectedServerKey.self],
configuredServers: defaults[ConfiguredServersKey.self]
)
}
func save() {
let defaults = UserDefaults.standard
defaults[ConfiguredServersKey.self] = configuredServers
defaults[SelectedServerKey.self] = selectedServer
postSettingsChanged()
}
func postSettingsChanged() {
NotificationCenter.default.post(name: .settingsChanged, object: nil)
}
// MARK: - Modifiers
func selectedServer(_ server: Server?) -> Self {
var copy = self
copy.selectedServer = server
return copy
}
func configuredServers(_ servers: [Server]) -> Self {
var copy = self
copy.configuredServers = servers
return copy
}
var isConfigured: Bool {
!configuredServers.isEmpty
}
static func fromDefaults() -> Settings {
let configuredServers: [Server] = {
guard let configuredServersData = UserDefaults.standard.data(forKey: Keys.configuredServers.rawValue)
else { return [] }
guard let configuredServers = try? PropertyListDecoder().decode([Server].self, from: configuredServersData)
else { return [] }
return configuredServers
}()
return Settings(configuredServers: configuredServers)
}
func save() {
let configuredServersData = try! PropertyListEncoder().encode(configuredServers)
UserDefaults.standard.set(configuredServersData, forKey: Keys.configuredServers.rawValue)
NotificationCenter.default.post(name: .settingsChanged, object: nil)
return copy
}
// MARK: - Types
enum Keys: String
{
case selectedServer
case configuredServers
}
fileprivate protocol Key
{
associatedtype Value: Codable
static var defaultValue: Value { get }
static var key: String { get }
}
private struct ConfiguredServersKey: Key {
static var defaultValue: [Server] { [] }
}
private struct SelectedServerKey: Key {
static var defaultValue: Server? { nil }
}
}
extension UserDefaults
{
fileprivate subscript<T: Settings.Key>(_ type: T.Type) -> T.Value {
get {
guard let data = data(forKey: type.key)
else { return type.defaultValue }
guard let value = try? PropertyListDecoder().decode(type.Value, from: data)
else { return type.defaultValue }
return value
}
set {
let data = try? PropertyListEncoder().encode(newValue)
set(data, forKey: type.key)
}
}
}
extension Settings.Key
{
static var key: String { Mirror(reflecting: Self.self).description }
}
extension Notification.Name