Refactor Power Mode hotkeys into dedicated PowerModeShortcutManager for cleaner architecture and better observer lifecycle management
This commit is contained in:
parent
78ab6fb3b2
commit
f0df362fac
@ -43,6 +43,7 @@ class HotkeyManager: ObservableObject {
|
||||
|
||||
private var whisperState: WhisperState
|
||||
private var miniRecorderShortcutManager: MiniRecorderShortcutManager
|
||||
private var powerModeShortcutManager: PowerModeShortcutManager
|
||||
|
||||
// MARK: - Helper Properties
|
||||
private var canProcessHotkeyAction: Bool {
|
||||
@ -74,8 +75,6 @@ class HotkeyManager: ObservableObject {
|
||||
private var lastShortcutTriggerTime: Date?
|
||||
private let shortcutCooldownInterval: TimeInterval = 0.5
|
||||
|
||||
private var registeredPowerModeIds: Set<UUID> = []
|
||||
|
||||
enum HotkeyOption: String, CaseIterable {
|
||||
case none = "none"
|
||||
case rightOption = "rightOption"
|
||||
@ -129,6 +128,7 @@ class HotkeyManager: ObservableObject {
|
||||
|
||||
self.whisperState = whisperState
|
||||
self.miniRecorderShortcutManager = MiniRecorderShortcutManager(whisperState: whisperState)
|
||||
self.powerModeShortcutManager = PowerModeShortcutManager(whisperState: whisperState)
|
||||
|
||||
KeyboardShortcuts.onKeyUp(for: .pasteLastTranscription) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
@ -164,21 +164,6 @@ class HotkeyManager: ObservableObject {
|
||||
Task { @MainActor in
|
||||
try? await Task.sleep(nanoseconds: 100_000_000)
|
||||
self.setupHotkeyMonitoring()
|
||||
self.setupPowerModeHotkeys()
|
||||
}
|
||||
|
||||
// Observe PowerMode configuration changes
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(powerModeConfigurationsDidChange),
|
||||
name: NSNotification.Name("PowerModeConfigurationsDidChange"),
|
||||
object: nil
|
||||
)
|
||||
}
|
||||
|
||||
@objc private func powerModeConfigurationsDidChange() {
|
||||
Task { @MainActor in
|
||||
setupPowerModeHotkeys()
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,58 +422,8 @@ class HotkeyManager: ObservableObject {
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
Task { @MainActor in
|
||||
removeAllMonitoring()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - PowerMode Hotkey Management
|
||||
extension HotkeyManager {
|
||||
func setupPowerModeHotkeys() {
|
||||
let powerModesWithShortcuts = Set(PowerModeManager.shared.configurations
|
||||
.filter { $0.hotkeyShortcut != nil }
|
||||
.map { $0.id })
|
||||
|
||||
let idsToRemove = registeredPowerModeIds.subtracting(powerModesWithShortcuts)
|
||||
|
||||
idsToRemove.forEach { id in
|
||||
KeyboardShortcuts.setShortcut(nil, for: .powerMode(id: id))
|
||||
KeyboardShortcuts.disable(.powerMode(id: id))
|
||||
registeredPowerModeIds.remove(id)
|
||||
}
|
||||
|
||||
PowerModeManager.shared.configurations.forEach { config in
|
||||
guard config.hotkeyShortcut != nil else { return }
|
||||
guard !registeredPowerModeIds.contains(config.id) else { return }
|
||||
|
||||
KeyboardShortcuts.onKeyUp(for: .powerMode(id: config.id)) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
Task { @MainActor in
|
||||
await self.handlePowerModeHotkey(powerModeId: config.id)
|
||||
}
|
||||
}
|
||||
|
||||
registeredPowerModeIds.insert(config.id)
|
||||
}
|
||||
}
|
||||
|
||||
private func handlePowerModeHotkey(powerModeId: UUID) async {
|
||||
guard canProcessHotkeyAction else { return }
|
||||
|
||||
guard let config = PowerModeManager.shared.getConfiguration(with: powerModeId),
|
||||
config.hotkeyShortcut != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
await whisperState.toggleMiniRecorder(powerModeId: powerModeId)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - PowerMode Keyboard Shortcut Names
|
||||
extension KeyboardShortcuts.Name {
|
||||
static func powerMode(id: UUID) -> Self {
|
||||
Self("powerMode_\(id.uuidString)")
|
||||
}
|
||||
}
|
||||
}
|
||||
85
VoiceInk/PowerMode/PowerModeShortcutManager.swift
Normal file
85
VoiceInk/PowerMode/PowerModeShortcutManager.swift
Normal file
@ -0,0 +1,85 @@
|
||||
import Foundation
|
||||
import KeyboardShortcuts
|
||||
|
||||
@MainActor
|
||||
class PowerModeShortcutManager {
|
||||
private weak var whisperState: WhisperState?
|
||||
private var registeredPowerModeIds: Set<UUID> = []
|
||||
|
||||
init(whisperState: WhisperState) {
|
||||
self.whisperState = whisperState
|
||||
|
||||
setupPowerModeHotkeys()
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(powerModeConfigurationsDidChange),
|
||||
name: NSNotification.Name("PowerModeConfigurationsDidChange"),
|
||||
object: nil
|
||||
)
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
@objc private func powerModeConfigurationsDidChange() {
|
||||
Task { @MainActor in
|
||||
setupPowerModeHotkeys()
|
||||
}
|
||||
}
|
||||
|
||||
private func setupPowerModeHotkeys() {
|
||||
let powerModesWithShortcuts = Set(PowerModeManager.shared.configurations
|
||||
.filter { $0.hotkeyShortcut != nil }
|
||||
.map { $0.id })
|
||||
|
||||
// Remove shortcuts for deleted or updated configs
|
||||
let idsToRemove = registeredPowerModeIds.subtracting(powerModesWithShortcuts)
|
||||
idsToRemove.forEach { id in
|
||||
KeyboardShortcuts.setShortcut(nil, for: .powerMode(id: id))
|
||||
KeyboardShortcuts.disable(.powerMode(id: id))
|
||||
registeredPowerModeIds.remove(id)
|
||||
}
|
||||
|
||||
// Add new shortcuts
|
||||
PowerModeManager.shared.configurations.forEach { config in
|
||||
guard config.hotkeyShortcut != nil else { return }
|
||||
guard !registeredPowerModeIds.contains(config.id) else { return }
|
||||
|
||||
KeyboardShortcuts.onKeyUp(for: .powerMode(id: config.id)) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
Task { @MainActor in
|
||||
await self.handlePowerModeHotkey(powerModeId: config.id)
|
||||
}
|
||||
}
|
||||
|
||||
registeredPowerModeIds.insert(config.id)
|
||||
}
|
||||
}
|
||||
|
||||
private func handlePowerModeHotkey(powerModeId: UUID) async {
|
||||
guard let whisperState = whisperState,
|
||||
canProcessHotkeyAction(whisperState: whisperState) else { return }
|
||||
|
||||
guard let config = PowerModeManager.shared.getConfiguration(with: powerModeId),
|
||||
config.hotkeyShortcut != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
await whisperState.toggleMiniRecorder(powerModeId: powerModeId)
|
||||
}
|
||||
|
||||
private func canProcessHotkeyAction(whisperState: WhisperState) -> Bool {
|
||||
whisperState.recordingState != .transcribing &&
|
||||
whisperState.recordingState != .enhancing &&
|
||||
whisperState.recordingState != .busy
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - PowerMode Keyboard Shortcut Names
|
||||
extension KeyboardShortcuts.Name {
|
||||
static func powerMode(id: UUID) -> Self {
|
||||
Self("powerMode_\(id.uuidString)")
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user