Skip to content

Add array with options per HotKey #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 54 additions & 22 deletions Hex/Models/HexSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,111 @@ import Dependencies
import Foundation

// To add a new setting, add a new property to the struct, the CodingKeys enum, and the custom decoder
struct HexSettings: Codable, Equatable {
struct TranscriptionSettings: Codable, Equatable, Identifiable {
var soundEffectsEnabled: Bool = true
var hotkey: HotKey = .init(key: nil, modifiers: [.option])
var openOnLogin: Bool = false
var showDockIcon: Bool = true
var selectedModel: String = "openai_whisper-large-v3-v20240930"
var useClipboardPaste: Bool = true
var preventSystemSleep: Bool = true
var pauseMediaOnRecord: Bool = true
var outputLanguage: String? = nil
var hotkey: HotKey = .init(key: nil, modifiers: [.option])

// Define coding keys to match struct properties
enum CodingKeys: String, CodingKey {
case soundEffectsEnabled
case hotkey
case openOnLogin
case showDockIcon
case selectedModel
case useClipboardPaste
case preventSystemSleep
case pauseMediaOnRecord
case outputLanguage
case hotkey
}

var id: HotKey {
return hotkey
}

init(
soundEffectsEnabled: Bool = true,
hotkey: HotKey = .init(key: nil, modifiers: [.option]),
openOnLogin: Bool = false,
showDockIcon: Bool = true,
selectedModel: String = "openai_whisper-large-v3-v20240930",
useClipboardPaste: Bool = true,
preventSystemSleep: Bool = true,
pauseMediaOnRecord: Bool = true,
on outputLanguage: String? = nil
outputLanguage: String? = nil,
hotkey: HotKey = .init(key: nil, modifiers: [.option])
) {
self.soundEffectsEnabled = soundEffectsEnabled
self.hotkey = hotkey
self.openOnLogin = openOnLogin
self.showDockIcon = showDockIcon
self.selectedModel = selectedModel
self.useClipboardPaste = useClipboardPaste
self.preventSystemSleep = preventSystemSleep
self.pauseMediaOnRecord = pauseMediaOnRecord
self.outputLanguage = outputLanguage
self.hotkey = hotkey
}

// Custom decoder that handles missing fields
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

// Decode each property, using decodeIfPresent with default fallbacks
soundEffectsEnabled =
try container.decodeIfPresent(Bool.self, forKey: .soundEffectsEnabled) ?? true
hotkey =
try container.decodeIfPresent(HotKey.self, forKey: .hotkey)
?? .init(key: nil, modifiers: [.option])
openOnLogin = try container.decodeIfPresent(Bool.self, forKey: .openOnLogin) ?? false
showDockIcon = try container.decodeIfPresent(Bool.self, forKey: .showDockIcon) ?? true
selectedModel =
try container.decodeIfPresent(String.self, forKey: .selectedModel)
?? "openai_whisper-large-v3-v20240930"
useClipboardPaste = try container.decodeIfPresent(Bool.self, forKey: .useClipboardPaste) ?? true
useClipboardPaste =
try container.decodeIfPresent(Bool.self, forKey: .useClipboardPaste) ?? true
preventSystemSleep =
try container.decodeIfPresent(Bool.self, forKey: .preventSystemSleep) ?? true
pauseMediaOnRecord =
try container.decodeIfPresent(Bool.self, forKey: .pauseMediaOnRecord) ?? true
outputLanguage = try container.decodeIfPresent(String.self, forKey: .outputLanguage)
hotkey =
try container.decodeIfPresent(HotKey.self, forKey: .hotkey)
?? .init(key: nil, modifiers: [.option])
}
}

// To add a new setting, add a new property to the struct, the CodingKeys enum, and the custom decoder
struct HexSettings: Codable, Equatable {
var hotKeyOptions: IdentifiedArrayOf<TranscriptionSettings> = [.init()]
var openOnLogin: Bool = false
var showDockIcon: Bool = true

// Define coding keys to match struct properties
enum CodingKeys: String, CodingKey {
case openOnLogin
case showDockIcon
case hotKeyOptions
}

init(
openOnLogin: Bool = false,
showDockIcon: Bool = true,
hotKeyOptions: IdentifiedArrayOf<TranscriptionSettings> = [.init()]
) {
self.openOnLogin = openOnLogin
self.showDockIcon = showDockIcon
self.hotKeyOptions = hotKeyOptions
}

// Custom decoder that handles missing fields
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

// Decode each property, using decodeIfPresent with default fallbacks
openOnLogin = try container.decodeIfPresent(Bool.self, forKey: .openOnLogin) ?? false
showDockIcon = try container.decodeIfPresent(Bool.self, forKey: .showDockIcon) ?? true
/// TODO: Write code to upgrade settings from previous versions where transcriptionSettings was not present
hotKeyOptions =
try container.decodeIfPresent(
IdentifiedArrayOf<TranscriptionSettings>.self, forKey: .hotKeyOptions)
?? [.init()]
}
}

extension SharedReaderKey
where Self == FileStorageKey<HexSettings>.Default
{
where Self == FileStorageKey<HexSettings>.Default {
static var hexSettings: Self {
Self[
.fileStorage(URL.documentsDirectory.appending(component: "hex_settings.json")),
Expand Down
4 changes: 2 additions & 2 deletions Hex/Models/HotKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public enum Modifier: Identifiable, Codable, Equatable, Hashable, Comparable {
}
}

public struct Modifiers: Codable, Equatable, ExpressibleByArrayLiteral {
public struct Modifiers: Codable, Equatable, ExpressibleByArrayLiteral, Hashable {
var modifiers: Set<Modifier>

var sorted: [Modifier] {
Expand Down Expand Up @@ -102,7 +102,7 @@ public struct Modifiers: Codable, Equatable, ExpressibleByArrayLiteral {
}
}

public struct HotKey: Codable, Equatable {
public struct HotKey: Codable, Equatable, Hashable {
public var key: Key?
public var modifiers: Modifiers
}
Expand Down