Add option to disable Enhancemnent Shortcut Cmd + E
This commit is contained in:
parent
e3610c6db3
commit
4fb8bf361b
@ -49,15 +49,33 @@ class MiniRecorderShortcutManager: ObservableObject {
|
||||
setupEnhancementShortcut()
|
||||
setupEscapeHandlerOnce()
|
||||
setupCancelHandlerOnce()
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(settingsDidChange), name: .AppSettingsDidChange, object: nil)
|
||||
}
|
||||
|
||||
@objc private func settingsDidChange() {
|
||||
Task {
|
||||
if await whisperState.isMiniRecorderVisible {
|
||||
if EnhancementShortcutSettings.shared.isToggleEnhancementShortcutEnabled {
|
||||
KeyboardShortcuts.setShortcut(.init(.e, modifiers: .command), for: .toggleEnhancement)
|
||||
} else {
|
||||
removeEnhancementShortcut()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func setupVisibilityObserver() {
|
||||
visibilityTask = Task { @MainActor in
|
||||
for await isVisible in whisperState.$isMiniRecorderVisible.values {
|
||||
if isVisible {
|
||||
activateEscapeShortcut()
|
||||
activateCancelShortcut()
|
||||
KeyboardShortcuts.setShortcut(.init(.e, modifiers: .command), for: .toggleEnhancement)
|
||||
if EnhancementShortcutSettings.shared.isToggleEnhancementShortcutEnabled {
|
||||
KeyboardShortcuts.setShortcut(.init(.e, modifiers: .command), for: .toggleEnhancement)
|
||||
} else {
|
||||
removeEnhancementShortcut()
|
||||
}
|
||||
setupPromptShortcuts()
|
||||
setupPowerModeShortcuts()
|
||||
} else {
|
||||
@ -278,6 +296,7 @@ class MiniRecorderShortcutManager: ObservableObject {
|
||||
|
||||
deinit {
|
||||
visibilityTask?.cancel()
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
Task { @MainActor in
|
||||
deactivateEscapeShortcut()
|
||||
deactivateCancelShortcut()
|
||||
|
||||
17
VoiceInk/Services/EnhancementShortcutSettings.swift
Normal file
17
VoiceInk/Services/EnhancementShortcutSettings.swift
Normal file
@ -0,0 +1,17 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
class EnhancementShortcutSettings: ObservableObject {
|
||||
static let shared = EnhancementShortcutSettings()
|
||||
|
||||
@Published var isToggleEnhancementShortcutEnabled: Bool {
|
||||
didSet {
|
||||
UserDefaults.standard.set(isToggleEnhancementShortcutEnabled, forKey: "isToggleEnhancementShortcutEnabled")
|
||||
NotificationCenter.default.post(name: .AppSettingsDidChange, object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
private init() {
|
||||
self.isToggleEnhancementShortcutEnabled = UserDefaults.standard.object(forKey: "isToggleEnhancementShortcutEnabled") as? Bool ?? true
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,22 @@
|
||||
import SwiftUI
|
||||
import KeyboardShortcuts
|
||||
|
||||
struct EnhancementShortcutsView: View {
|
||||
private let shortcuts: [ShortcutRowData] = [
|
||||
.toggleEnhancement,
|
||||
.switchPrompt
|
||||
]
|
||||
@ObservedObject private var shortcutSettings = EnhancementShortcutSettings.shared
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 12) {
|
||||
ForEach(shortcuts) { shortcut in
|
||||
ShortcutRow(data: shortcut)
|
||||
}
|
||||
ShortcutRow(
|
||||
title: "Toggle AI Enhancement",
|
||||
description: "Quickly enable or disable enhancement while recording.",
|
||||
keyDisplay: ["⌘", "E"],
|
||||
isOn: $shortcutSettings.isToggleEnhancementShortcutEnabled
|
||||
)
|
||||
ShortcutRow(
|
||||
title: "Switch Enhancement Prompt",
|
||||
description: "Switch between your saved prompts without touching the UI. Use ⌘1–⌘0 to activate the corresponding prompt in the order they are saved.",
|
||||
keyDisplay: ["⌘", "1 – 0"]
|
||||
)
|
||||
}
|
||||
.background(Color.clear)
|
||||
}
|
||||
@ -80,54 +86,63 @@ struct EnhancementShortcutsSection: View {
|
||||
}
|
||||
|
||||
// MARK: - Supporting Views
|
||||
private struct ShortcutRowData: Identifiable {
|
||||
let id = UUID()
|
||||
private struct ShortcutRow: View {
|
||||
let title: String
|
||||
let description: String
|
||||
let keyDisplay: [String]
|
||||
|
||||
static let toggleEnhancement = ShortcutRowData(
|
||||
title: "Toggle AI Enhancement",
|
||||
description: "Quickly enable or disable enhancement while recording.",
|
||||
keyDisplay: ["⌘", "E"]
|
||||
)
|
||||
|
||||
static let switchPrompt = ShortcutRowData(
|
||||
title: "Switch Enhancement Prompt",
|
||||
description: "Switch between your saved prompts without touching the UI. Use ⌘1–⌘0 to activate the corresponding prompt in the order they are saved.",
|
||||
keyDisplay: ["⌘", "1 – 0"]
|
||||
)
|
||||
}
|
||||
private var isOn: Binding<Bool>?
|
||||
|
||||
init(title: String, description: String, keyDisplay: [String], isOn: Binding<Bool>? = nil) {
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.keyDisplay = keyDisplay
|
||||
self.isOn = isOn
|
||||
}
|
||||
|
||||
private struct ShortcutRow: View {
|
||||
let data: ShortcutRowData
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .center, spacing: 16) {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(spacing: 8) {
|
||||
Text(data.title)
|
||||
Text(title)
|
||||
.font(.system(size: 14, weight: .semibold))
|
||||
InfoTip(title: data.title, message: data.description, learnMoreURL: "https://tryvoiceink.com/docs/switching-enhancement-prompts")
|
||||
InfoTip(title: title, message: description, learnMoreURL: "https://tryvoiceink.com/docs/switching-enhancement-prompts")
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(minLength: 0)
|
||||
|
||||
HStack(spacing: 8) {
|
||||
ForEach(data.keyDisplay, id: \.self) { key in
|
||||
KeyChip(label: key)
|
||||
}
|
||||
if let isOn = isOn {
|
||||
keyDisplayView(isActive: isOn.wrappedValue)
|
||||
.onTapGesture {
|
||||
withAnimation(.bouncy) {
|
||||
isOn.wrappedValue.toggle()
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
} else {
|
||||
keyDisplayView()
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func keyDisplayView(isActive: Bool? = nil) -> some View {
|
||||
HStack(spacing: 8) {
|
||||
ForEach(keyDisplay, id: \.self) { key in
|
||||
KeyChip(label: key, isActive: isActive)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct KeyChip: View {
|
||||
let label: String
|
||||
|
||||
var isActive: Bool? = nil
|
||||
|
||||
var body: some View {
|
||||
let active = isActive ?? true
|
||||
|
||||
Text(label)
|
||||
.font(.system(size: 13, weight: .semibold, design: .monospaced))
|
||||
.padding(.horizontal, 12)
|
||||
@ -137,9 +152,11 @@ private struct KeyChip: View {
|
||||
.fill(Color(NSColor.controlBackgroundColor))
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 10, style: .continuous)
|
||||
.stroke(Color(NSColor.separatorColor).opacity(0.7), lineWidth: 0.8)
|
||||
.stroke(Color(NSColor.separatorColor).opacity(active ? 0.7 : 0.3), lineWidth: 1)
|
||||
)
|
||||
)
|
||||
.shadow(color: Color(NSColor.shadowColor).opacity(0.1), radius: 4, x: 0, y: 2)
|
||||
.foregroundColor(active ? .primary : .secondary)
|
||||
.shadow(color: Color(NSColor.shadowColor).opacity(active ? 0.1 : 0), radius: 4, x: 0, y: 2)
|
||||
.opacity(active ? 1.0 : 0.6)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user