feat: add AppSettings
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// User preferences, persisted in UserDefaults as soon as a value changes.
|
||||||
|
public final class AppSettings: ObservableObject {
|
||||||
|
public static let defaultModelVariant = "large-v3-v20240930_turbo"
|
||||||
|
|
||||||
|
enum Key {
|
||||||
|
static let hotkey = "hotkeyID"
|
||||||
|
static let model = "modelVariant"
|
||||||
|
static let keepHistory = "keepHistory"
|
||||||
|
static let usePriming = "usePriming"
|
||||||
|
static let useCorrection = "useCorrection"
|
||||||
|
}
|
||||||
|
|
||||||
|
private let defaults: UserDefaults
|
||||||
|
|
||||||
|
/// `HotkeyBinding.id` of the key that has to be held.
|
||||||
|
@Published public var hotkeyID: String {
|
||||||
|
didSet { defaults.set(hotkeyID, forKey: Key.hotkey) }
|
||||||
|
}
|
||||||
|
@Published public var modelVariant: String {
|
||||||
|
didSet { defaults.set(modelVariant, forKey: Key.model) }
|
||||||
|
}
|
||||||
|
@Published public var keepHistory: Bool {
|
||||||
|
didSet { defaults.set(keepHistory, forKey: Key.keepHistory) }
|
||||||
|
}
|
||||||
|
/// Give the speech engine the dictionary words as context.
|
||||||
|
@Published public var usePriming: Bool {
|
||||||
|
didSet { defaults.set(usePriming, forKey: Key.usePriming) }
|
||||||
|
}
|
||||||
|
/// Apply the dictionary corrections after transcription.
|
||||||
|
@Published public var useCorrection: Bool {
|
||||||
|
didSet { defaults.set(useCorrection, forKey: Key.useCorrection) }
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(defaults: UserDefaults = .standard) {
|
||||||
|
self.defaults = defaults
|
||||||
|
hotkeyID = defaults.string(forKey: Key.hotkey) ?? "fn"
|
||||||
|
modelVariant = defaults.string(forKey: Key.model) ?? Self.defaultModelVariant
|
||||||
|
keepHistory = defaults.object(forKey: Key.keepHistory) as? Bool ?? true
|
||||||
|
usePriming = defaults.object(forKey: Key.usePriming) as? Bool ?? true
|
||||||
|
useCorrection = defaults.object(forKey: Key.useCorrection) as? Bool ?? true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
@testable import SstData
|
||||||
|
|
||||||
|
struct AppSettingsTests {
|
||||||
|
func freshDefaults() -> UserDefaults {
|
||||||
|
let name = "sst-tests-\(UUID().uuidString)"
|
||||||
|
let defaults = UserDefaults(suiteName: name)!
|
||||||
|
defaults.removePersistentDomain(forName: name)
|
||||||
|
return defaults
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func defaultsMatchTheSpec() {
|
||||||
|
let settings = AppSettings(defaults: freshDefaults())
|
||||||
|
#expect(settings.hotkeyID == "fn")
|
||||||
|
#expect(settings.modelVariant == "large-v3-v20240930_turbo")
|
||||||
|
#expect(settings.keepHistory)
|
||||||
|
#expect(settings.usePriming)
|
||||||
|
#expect(settings.useCorrection)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func changesArePersisted() {
|
||||||
|
let defaults = freshDefaults()
|
||||||
|
let settings = AppSettings(defaults: defaults)
|
||||||
|
settings.hotkeyID = "rightOption"
|
||||||
|
settings.modelVariant = "small"
|
||||||
|
settings.keepHistory = false
|
||||||
|
settings.usePriming = false
|
||||||
|
settings.useCorrection = false
|
||||||
|
|
||||||
|
let reloaded = AppSettings(defaults: defaults)
|
||||||
|
#expect(reloaded.hotkeyID == "rightOption")
|
||||||
|
#expect(reloaded.modelVariant == "small")
|
||||||
|
#expect(!reloaded.keepHistory)
|
||||||
|
#expect(!reloaded.usePriming)
|
||||||
|
#expect(!reloaded.useCorrection)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user