Files
2026-07-13 13:12:00 +08:00

73 lines
2.3 KiB
Swift

import Foundation
@MainActor
final class SettingsStore: ObservableObject {
@Published var serverURL: String? {
didSet { defaults.set(serverURL, forKey: Keys.serverURL) }
}
@Published private(set) var recentServers: [String] {
didSet { defaults.set(recentServers, forKey: Keys.recentServers) }
}
private let defaults: UserDefaults
private let maxRecentServers = 5
init(defaults: UserDefaults = .standard) {
self.defaults = defaults
#if DEBUG
serverURL =
ProcessInfo.processInfo.omnigentArgumentValue(after: "--omnigent-server-url")
?? ProcessInfo.processInfo.environment["OMNIGENT_SCREENSHOT_APP_URL"]
?? defaults.string(forKey: Keys.serverURL)
#else
serverURL = defaults.string(forKey: Keys.serverURL)
#endif
recentServers = defaults.stringArray(forKey: Keys.recentServers) ?? []
}
func rememberRecentServer(_ url: URL) {
let value = url.absoluteString
let deduped: [String] = [value] + recentServers.filter { $0 != value }
recentServers = Array(deduped.prefix(maxRecentServers))
}
func isProtocolAllowed(_ scheme: String, from origin: String) -> Bool {
allowedProtocols()[origin]?.contains(scheme.lowercased()) == true
}
func allowProtocol(_ scheme: String, from origin: String) {
var grants = allowedProtocols()
var schemes = grants[origin] ?? []
let normalized = scheme.lowercased()
if !schemes.contains(normalized) {
schemes.append(normalized)
}
grants[origin] = schemes
defaults.set(grants, forKey: Keys.allowedProtocols)
}
private func allowedProtocols() -> [String: [String]] {
defaults.dictionary(forKey: Keys.allowedProtocols) as? [String: [String]] ?? [:]
}
private enum Keys {
static let serverURL = "omnigent.serverURL"
static let recentServers = "omnigent.recentServers"
static let allowedProtocols = "omnigent.allowedProtocols"
}
}
#if DEBUG
extension ProcessInfo {
fileprivate func omnigentArgumentValue(after argumentName: String) -> String? {
guard let index = arguments.firstIndex(of: argumentName) else { return nil }
let valueIndex = arguments.index(after: index)
guard arguments.indices.contains(valueIndex) else { return nil }
let value = arguments[valueIndex].trimmingCharacters(in: .whitespacesAndNewlines)
return value.isEmpty ? nil : value
}
}
#endif