import Foundation import Combine /// User-facing settings, persisted to `UserDefaults`. /// /// Phase 0 scope: backend host + TLS-skip, output folder, and adapter toggles. /// The adapter toggles persist but do nothing yet (adapters arrive in Phase 3–4). @MainActor final class AppSettings: ObservableObject { /// Adapters the app will eventually run, in display order. static let adapterKeys: [(key: String, label: String)] = [ ("zoom", "Zoom"), ("teams", "Microsoft Teams"), ("signal", "Signal"), ("meet", "Google Meet"), ] @Published var backendBaseURL: String { didSet { defaults.set(backendBaseURL, forKey: Keys.backendBaseURL) } } @Published var skipTLSVerification: Bool { didSet { defaults.set(skipTLSVerification, forKey: Keys.skipTLS) } } @Published var outputFolderPath: String { didSet { defaults.set(outputFolderPath, forKey: Keys.outputFolder) } } @Published var adapterEnabled: [String: Bool] { didSet { defaults.set(adapterEnabled, forKey: Keys.adapterEnabled) } } /// Output folder as a resolved file URL (expands a leading `~`). var outputFolderURL: URL { URL(fileURLWithPath: (outputFolderPath as NSString).expandingTildeInPath, isDirectory: true) } private let defaults: UserDefaults init(defaults: UserDefaults = .standard) { self.defaults = defaults self.backendBaseURL = defaults.string(forKey: Keys.backendBaseURL) ?? "https://your-spark-backend.local:62419" self.skipTLSVerification = defaults.object(forKey: Keys.skipTLS) as? Bool ?? true self.outputFolderPath = defaults.string(forKey: Keys.outputFolder) ?? "~/Ten31Transcripts" let stored = defaults.dictionary(forKey: Keys.adapterEnabled) as? [String: Bool] self.adapterEnabled = stored ?? Dictionary( uniqueKeysWithValues: Self.adapterKeys.map { ($0.key, true) } ) } private enum Keys { static let backendBaseURL = "backendBaseURL" static let skipTLS = "skipTLSVerification" static let outputFolder = "outputFolderPath" static let adapterEnabled = "adapterEnabled" } }