diff --git a/MyVoxtral/MyVoxtral/Models/AppSettings.swift b/MyVoxtral/MyVoxtral/Models/AppSettings.swift new file mode 100644 index 0000000..43c4c8a --- /dev/null +++ b/MyVoxtral/MyVoxtral/Models/AppSettings.swift @@ -0,0 +1,45 @@ +import SwiftUI +import Carbon.HIToolbox + +enum OutputMode: String, CaseIterable { + case textBox = "Text Window" + case cursorInjection = "Type at Cursor" +} + +final class AppSettings: ObservableObject { + static let shared = AppSettings() + + @AppStorage("apiKey") var apiKey: String = "" + @AppStorage("outputMode") var outputMode: OutputMode = .textBox + @AppStorage("streamingDelayMs") var streamingDelayMs: Int = 480 + @AppStorage("shortcutKeyCode") private var shortcutKeyCodeStorage: Int = 0 + @AppStorage("shortcutModifiers") private var shortcutModifiersStorage: Int = 0 + + var shortcutKeyCode: UInt16 { + get { UInt16(shortcutKeyCodeStorage) } + set { shortcutKeyCodeStorage = Int(newValue) } + } + + var shortcutModifiers: UInt { + get { UInt(bitPattern: shortcutModifiersStorage) } + set { shortcutModifiersStorage = Int(bitPattern: newValue) } + } + + var hasAPIKey: Bool { !apiKey.isEmpty } + + var hasShortcut: Bool { shortcutKeyCode != 0 || shortcutModifiers != 0 } + + var shortcutDisplayString: String { + guard hasShortcut else { return "Not Set" } + var parts: [String] = [] + let mods = NSEvent.ModifierFlags(rawValue: shortcutModifiers) + if mods.contains(.control) { parts.append("⌃") } + if mods.contains(.option) { parts.append("⌥") } + if mods.contains(.shift) { parts.append("⇧") } + if mods.contains(.command) { parts.append("⌘") } + if let scalar = Unicode.Scalar(shortcutKeyCode) { + parts.append(String(Character(scalar)).uppercased()) + } + return parts.joined() + } +}