From 154368e616a7fabe2536dae0715a0080b10e03c2 Mon Sep 17 00:00:00 2001 From: Alexey Haidamaka Date: Fri, 12 Sep 2025 20:03:19 +0200 Subject: [PATCH] Added capability to paste last enhancement --- VoiceInk/HotkeyManager.swift | 8 +++++ .../Services/LastTranscriptionService.swift | 35 ++++++++++++++----- VoiceInk/Views/Settings/SettingsView.swift | 17 +++++++++ 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/VoiceInk/HotkeyManager.swift b/VoiceInk/HotkeyManager.swift index 407986e..5872f81 100644 --- a/VoiceInk/HotkeyManager.swift +++ b/VoiceInk/HotkeyManager.swift @@ -7,6 +7,7 @@ extension KeyboardShortcuts.Name { static let toggleMiniRecorder = Self("toggleMiniRecorder") static let toggleMiniRecorder2 = Self("toggleMiniRecorder2") static let pasteLastTranscription = Self("pasteLastTranscription") + static let pasteLastEnhancement = Self("pasteLastEnhancement") } @MainActor @@ -153,6 +154,13 @@ class HotkeyManager: ObservableObject { } } + KeyboardShortcuts.onKeyUp(for: .pasteLastEnhancement) { [weak self] in + guard let self = self else { return } + Task { @MainActor in + LastTranscriptionService.pasteLastEnhancement(from: self.whisperState.modelContext) + } + } + Task { @MainActor in try? await Task.sleep(nanoseconds: 100_000_000) self.setupHotkeyMonitoring() diff --git a/VoiceInk/Services/LastTranscriptionService.swift b/VoiceInk/Services/LastTranscriptionService.swift index 4ef46fa..28899e4 100644 --- a/VoiceInk/Services/LastTranscriptionService.swift +++ b/VoiceInk/Services/LastTranscriptionService.swift @@ -29,7 +29,7 @@ class LastTranscriptionService: ObservableObject { return } - let success = ClipboardManager.copyToClipboard(lastTranscription.enhancedText?.isEmpty == false ? lastTranscription.enhancedText! : lastTranscription.text) + let success = ClipboardManager.copyToClipboard(lastTranscription.text) Task { @MainActor in if success { @@ -57,13 +57,7 @@ class LastTranscriptionService: ObservableObject { return } - // Use enhanced text if available and not empty, otherwise use original text - let textToPaste: String - if let enhancedText = lastTranscription.enhancedText, !enhancedText.isEmpty { - textToPaste = enhancedText - } else { - textToPaste = lastTranscription.text - } + let textToPaste = lastTranscription.text // Delay to give the user time to release modifier keys (especially Control) DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { @@ -71,6 +65,29 @@ class LastTranscriptionService: ObservableObject { } } + static func pasteLastEnhancement(from modelContext: ModelContext) { + guard let lastTranscription = getLastTranscription(from: modelContext) else { + Task { @MainActor in + NotificationManager.shared.showNotification( + title: "No transcription available", + type: .error + ) + } + return + } + + // Only paste if enhancement exists; this includes actual enhancement text or an error message saved in enhancedText. + guard let enhancedText = lastTranscription.enhancedText, !enhancedText.isEmpty else { + // Per requirements, do nothing when there is no enhancement. + return + } + + // Delay to allow modifier keys to be released + DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { + CursorPaster.pasteAtCursor(enhancedText + " ") + } + } + static func retryLastTranscription(from modelContext: ModelContext, whisperState: WhisperState) { Task { @MainActor in guard let lastTranscription = getLastTranscription(from: modelContext), @@ -111,4 +128,4 @@ class LastTranscriptionService: ObservableObject { } } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/VoiceInk/Views/Settings/SettingsView.swift b/VoiceInk/Views/Settings/SettingsView.swift index e54ae0a..2db6b98 100644 --- a/VoiceInk/Views/Settings/SettingsView.swift +++ b/VoiceInk/Views/Settings/SettingsView.swift @@ -128,6 +128,23 @@ struct SettingsView: View { Spacer() } + // Paste Last Enhancement + HStack(spacing: 12) { + Text("Paste Last Enhancement") + .font(.system(size: 13, weight: .medium)) + .foregroundColor(.secondary) + + KeyboardShortcuts.Recorder(for: .pasteLastEnhancement) + .controlSize(.small) + + InfoTip( + title: "Paste Last Enhancement", + message: "Shortcut for pasting the most recent AI-enhanced text. If no enhancement exists, nothing is pasted. If the enhancement failed, the error message is pasted." + ) + + Spacer() + } + Divider() // Middle-Click Toggle