Skip to content
Open
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
14 changes: 12 additions & 2 deletions Sources/Fluid/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,14 @@ struct ContentView: View {
shortcuts.append(shortcut)
}
}
self.primaryDictationShortcuts = shortcuts
self.updatePrimaryDictationShortcuts(shortcuts)
}

private func updatePrimaryDictationShortcuts(_ shortcuts: [HotkeyShortcut]) {
SettingsStore.shared.primaryDictationShortcuts = shortcuts
let storedShortcuts = SettingsStore.shared.primaryDictationShortcuts
self.primaryDictationShortcuts = storedShortcuts
self.hotkeyManager?.updatePrimaryShortcuts(storedShortcuts)
}

private func setShortcutTargetEnabled(_ enabled: Bool, for target: ShortcutRecordingTarget) {
Expand Down Expand Up @@ -1464,7 +1471,10 @@ struct ContentView: View {
inputDevices: self.$inputDevices,
outputDevices: self.$outputDevices,
accessibilityEnabled: self.$accessibilityEnabled,
primaryDictationShortcuts: self.$primaryDictationShortcuts,
primaryDictationShortcuts: Binding(
get: { self.primaryDictationShortcuts },
set: { self.updatePrimaryDictationShortcuts($0) }
),
activeShortcutRecordingTarget: self.$activeShortcutRecordingTarget,
shortcutRecordingMessage: self.$shortcutRecordingMessage,
commandModeShortcut: self.$commandModeHotkeyShortcut,
Expand Down
20 changes: 8 additions & 12 deletions Sources/Fluid/Persistence/SettingsStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1669,7 +1669,7 @@ final class SettingsStore: ObservableObject {
}
set {
objectWillChange.send()
let shortcuts = Self.normalizedPrimaryDictationShortcuts([newValue], fallback: Self.defaultPrimaryDictationShortcut)
let shortcuts = Self.normalizedPrimaryDictationShortcuts([newValue])
self.storePrimaryDictationShortcuts(shortcuts)
self.storeLegacyHotkeyShortcut(shortcuts[0])
}
Expand All @@ -1680,7 +1680,7 @@ final class SettingsStore: ObservableObject {
.map(\.displayString)
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.filter { !$0.isEmpty }
return displays.isEmpty ? Self.defaultPrimaryDictationShortcut.displayString : displays.joined(separator: " / ")
return displays.joined(separator: " / ")
}

var primaryDictationShortcuts: [HotkeyShortcut] {
Expand All @@ -1689,15 +1689,17 @@ final class SettingsStore: ObservableObject {
if let data = defaults.data(forKey: Keys.primaryDictationShortcutsKey),
let shortcuts = try? JSONDecoder().decode([HotkeyShortcut].self, from: data)
{
return Self.normalizedPrimaryDictationShortcuts(shortcuts, fallback: fallback)
return Self.normalizedPrimaryDictationShortcuts(shortcuts)
}
return [fallback]
}
set {
objectWillChange.send()
let shortcuts = Self.normalizedPrimaryDictationShortcuts(newValue, fallback: self.legacyHotkeyShortcut)
let shortcuts = Self.normalizedPrimaryDictationShortcuts(newValue)
self.storePrimaryDictationShortcuts(shortcuts)
self.storeLegacyHotkeyShortcut(shortcuts[0])
if let firstShortcut = shortcuts.first {
self.storeLegacyHotkeyShortcut(firstShortcut)
}
}
}

Expand All @@ -1714,17 +1716,11 @@ final class SettingsStore: ObservableObject {
return Self.defaultPrimaryDictationShortcut
}

private static func normalizedPrimaryDictationShortcuts(
_ shortcuts: [HotkeyShortcut],
fallback: HotkeyShortcut
) -> [HotkeyShortcut] {
private static func normalizedPrimaryDictationShortcuts(_ shortcuts: [HotkeyShortcut]) -> [HotkeyShortcut] {
var unique: [HotkeyShortcut] = []
for shortcut in shortcuts where !unique.contains(shortcut) {
unique.append(shortcut)
}
if unique.isEmpty {
unique.append(fallback)
}
return unique
}

Expand Down
6 changes: 2 additions & 4 deletions Sources/Fluid/UI/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2151,14 +2151,12 @@ struct SettingsView: View {
.disabled(!isRecording && self.isRecordingAnyShortcut)

Button("Remove") {
guard self.primaryDictationShortcuts.count > 1,
self.primaryDictationShortcuts.indices.contains(index)
else { return }
guard self.primaryDictationShortcuts.indices.contains(index) else { return }
self.primaryDictationShortcuts.remove(at: index)
}
.buttonStyle(.bordered)
.controlSize(.small)
.disabled(self.primaryDictationShortcuts.count <= 1 || self.isRecordingAnyShortcut)
.disabled(self.isRecordingAnyShortcut)

if isRecording,
let recordingMessage = self.shortcutRecordingMessage,
Expand Down
12 changes: 12 additions & 0 deletions Tests/FluidDictationIntegrationTests/HotkeyShortcutTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,18 @@ final class HotkeyShortcutTests: XCTestCase {
}
}

func testPrimaryDictationShortcutsCanBeExplicitlyCleared() throws {
try self.withRestoredDefaults(keys: [self.legacyHotkeyShortcutKey, self.primaryDictationShortcutsKey]) {
let legacyShortcut = HotkeyShortcut(keyCode: 12, modifierFlags: [.option])
SettingsStore.shared.hotkeyShortcut = legacyShortcut

SettingsStore.shared.primaryDictationShortcuts = []

XCTAssertEqual(SettingsStore.shared.primaryDictationShortcuts, [])
XCTAssertEqual(SettingsStore.shared.primaryDictationShortcutDisplayString, "")
}
}

func testPasteLastTranscriptionShortcutDefaultsToUnboundAndDisabled() throws {
try self.withRestoredDefaults(keys: [
self.pasteLastTranscriptionShortcutKey,
Expand Down
Loading