From 61a0e82a6d0637e55af1c4e032331fd12107b67d Mon Sep 17 00:00:00 2001 From: Beingpax Date: Tue, 30 Dec 2025 10:20:12 +0545 Subject: [PATCH] Add global keyboard shortcut to open history window from anywhere --- VoiceInk/HotkeyManager.swift | 13 ++++- .../History/HistoryShortcutTipView.swift | 47 +++++++++++++++++++ .../History/TranscriptionHistoryView.swift | 35 ++++++++++---- 3 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 VoiceInk/Views/History/HistoryShortcutTipView.swift diff --git a/VoiceInk/HotkeyManager.swift b/VoiceInk/HotkeyManager.swift index 2cc8309..2481942 100644 --- a/VoiceInk/HotkeyManager.swift +++ b/VoiceInk/HotkeyManager.swift @@ -9,6 +9,7 @@ extension KeyboardShortcuts.Name { static let pasteLastTranscription = Self("pasteLastTranscription") static let pasteLastEnhancement = Self("pasteLastEnhancement") static let retryLastTranscription = Self("retryLastTranscription") + static let openHistoryWindow = Self("openHistoryWindow") } @MainActor @@ -147,7 +148,17 @@ class HotkeyManager: ObservableObject { LastTranscriptionService.retryLastTranscription(from: self.whisperState.modelContext, whisperState: self.whisperState) } } - + + KeyboardShortcuts.onKeyUp(for: .openHistoryWindow) { [weak self] in + guard let self = self else { return } + Task { @MainActor in + HistoryWindowController.shared.showHistoryWindow( + modelContainer: self.whisperState.modelContext.container, + whisperState: self.whisperState + ) + } + } + Task { @MainActor in try? await Task.sleep(nanoseconds: 100_000_000) self.setupHotkeyMonitoring() diff --git a/VoiceInk/Views/History/HistoryShortcutTipView.swift b/VoiceInk/Views/History/HistoryShortcutTipView.swift new file mode 100644 index 0000000..d3df02e --- /dev/null +++ b/VoiceInk/Views/History/HistoryShortcutTipView.swift @@ -0,0 +1,47 @@ +import SwiftUI +import KeyboardShortcuts + +struct HistoryShortcutTipView: View { + var body: some View { + VStack(alignment: .leading, spacing: 12) { + HStack(spacing: 12) { + Image(systemName: "command.circle") + .font(.system(size: 20)) + .foregroundColor(.accentColor) + .frame(width: 24, height: 24) + + VStack(alignment: .leading, spacing: 2) { + Text("Quick Access") + .font(.headline) + Text("Open history from anywhere with a global shortcut") + .font(.subheadline) + .foregroundColor(.secondary) + } + } + + Divider() + .padding(.vertical, 4) + + HStack(spacing: 12) { + Text("Open History Window") + .font(.system(size: 13, weight: .medium)) + .foregroundColor(.secondary) + + KeyboardShortcuts.Recorder(for: .openHistoryWindow) + .controlSize(.small) + + Spacer() + } + } + .padding(16) + .frame(maxWidth: .infinity, alignment: .leading) + .background( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .fill(Color(NSColor.controlBackgroundColor).opacity(0.5)) + ) + .overlay( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .strokeBorder(Color(NSColor.separatorColor).opacity(0.3), lineWidth: 1) + ) + } +} diff --git a/VoiceInk/Views/History/TranscriptionHistoryView.swift b/VoiceInk/Views/History/TranscriptionHistoryView.swift index 4c6c66c..bd27746 100644 --- a/VoiceInk/Views/History/TranscriptionHistoryView.swift +++ b/VoiceInk/Views/History/TranscriptionHistoryView.swift @@ -223,16 +223,31 @@ struct TranscriptionHistoryView: View { TranscriptionDetailView(transcription: transcription) .id(transcription.id) } else { - VStack(spacing: 12) { - Image(systemName: "doc.text") - .font(.system(size: 50)) - .foregroundColor(.secondary) - Text("No Selection") - .font(.system(size: 18, weight: .medium)) - .foregroundColor(.secondary) - Text("Select a transcription to view details") - .font(.system(size: 14)) - .foregroundColor(.secondary) + ScrollView { + VStack(spacing: 32) { + Spacer() + .frame(minHeight: 40) + + VStack(spacing: 12) { + Image(systemName: "doc.text") + .font(.system(size: 50)) + .foregroundColor(.secondary) + Text("No Selection") + .font(.system(size: 18, weight: .medium)) + .foregroundColor(.secondary) + Text("Select a transcription to view details") + .font(.system(size: 14)) + .foregroundColor(.secondary) + } + + HistoryShortcutTipView() + .padding(.horizontal, 24) + + Spacer() + .frame(minHeight: 40) + } + .frame(maxWidth: .infinity) + .frame(minHeight: 600) } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color(NSColor.controlBackgroundColor))