feat: Added Auto Enter option in Power Mode

This commit is contained in:
Beingpax 2025-07-17 21:09:38 +05:45
parent fd03c1ca81
commit 1068dea78f
4 changed files with 54 additions and 3 deletions

View File

@ -80,4 +80,14 @@ class CursorPaster {
vUp?.post(tap: .cghidEventTap)
cmdUp?.post(tap: .cghidEventTap)
}
// Simulate pressing the Return / Enter key
static func pressEnter() {
guard AXIsProcessTrusted() else { return }
let source = CGEventSource(stateID: .hidSystemState)
let enterDown = CGEvent(keyboardEventSource: source, virtualKey: 0x24, keyDown: true)
let enterUp = CGEvent(keyboardEventSource: source, virtualKey: 0x24, keyDown: false)
enterDown?.post(tap: .cghidEventTap)
enterUp?.post(tap: .cghidEventTap)
}
}

View File

@ -13,10 +13,12 @@ struct PowerModeConfig: Codable, Identifiable, Equatable {
var useScreenCapture: Bool
var selectedAIProvider: String?
var selectedAIModel: String?
// NEW: Automatically press the Return key after pasting
var isAutoSendEnabled: Bool = false
// Custom coding keys to handle migration from selectedWhisperModel
enum CodingKeys: String, CodingKey {
case id, name, emoji, appConfigs, urlConfigs, isAIEnhancementEnabled, selectedPrompt, selectedLanguage, useScreenCapture, selectedAIProvider, selectedAIModel
case id, name, emoji, appConfigs, urlConfigs, isAIEnhancementEnabled, selectedPrompt, selectedLanguage, useScreenCapture, selectedAIProvider, selectedAIModel, isAutoSendEnabled
case selectedWhisperModel // Old key
case selectedTranscriptionModelName // New key
}
@ -24,7 +26,7 @@ struct PowerModeConfig: Codable, Identifiable, Equatable {
init(id: UUID = UUID(), name: String, emoji: String, appConfigs: [AppConfig]? = nil,
urlConfigs: [URLConfig]? = nil, isAIEnhancementEnabled: Bool, selectedPrompt: String? = nil,
selectedTranscriptionModelName: String? = nil, selectedLanguage: String? = nil, useScreenCapture: Bool = false,
selectedAIProvider: String? = nil, selectedAIModel: String? = nil) {
selectedAIProvider: String? = nil, selectedAIModel: String? = nil, isAutoSendEnabled: Bool = false) {
self.id = id
self.name = name
self.emoji = emoji
@ -33,6 +35,7 @@ struct PowerModeConfig: Codable, Identifiable, Equatable {
self.isAIEnhancementEnabled = isAIEnhancementEnabled
self.selectedPrompt = selectedPrompt
self.useScreenCapture = useScreenCapture
self.isAutoSendEnabled = isAutoSendEnabled
self.selectedAIProvider = selectedAIProvider ?? UserDefaults.standard.string(forKey: "selectedAIProvider")
self.selectedAIModel = selectedAIModel
self.selectedTranscriptionModelName = selectedTranscriptionModelName ?? UserDefaults.standard.string(forKey: "CurrentTranscriptionModel")
@ -52,6 +55,7 @@ struct PowerModeConfig: Codable, Identifiable, Equatable {
useScreenCapture = try container.decode(Bool.self, forKey: .useScreenCapture)
selectedAIProvider = try container.decodeIfPresent(String.self, forKey: .selectedAIProvider)
selectedAIModel = try container.decodeIfPresent(String.self, forKey: .selectedAIModel)
isAutoSendEnabled = try container.decodeIfPresent(Bool.self, forKey: .isAutoSendEnabled) ?? false
if let newModelName = try container.decodeIfPresent(String.self, forKey: .selectedTranscriptionModelName) {
selectedTranscriptionModelName = newModelName
@ -75,6 +79,7 @@ struct PowerModeConfig: Codable, Identifiable, Equatable {
try container.encode(useScreenCapture, forKey: .useScreenCapture)
try container.encodeIfPresent(selectedAIProvider, forKey: .selectedAIProvider)
try container.encodeIfPresent(selectedAIModel, forKey: .selectedAIModel)
try container.encode(isAutoSendEnabled, forKey: .isAutoSendEnabled)
try container.encodeIfPresent(selectedTranscriptionModelName, forKey: .selectedTranscriptionModelName)
}

View File

@ -35,6 +35,8 @@ struct ConfigurationView: View {
// New state for screen capture toggle
@State private var useScreenCapture = false
// NEW: Auto-send toggle state
@State private var isAutoSendEnabled = false
// State for prompt editing (similar to EnhancementSettingsView)
@State private var isEditingPrompt = false
@ -75,6 +77,7 @@ struct ConfigurationView: View {
_configName = State(initialValue: "")
_selectedEmoji = State(initialValue: "✏️")
_useScreenCapture = State(initialValue: false)
_isAutoSendEnabled = State(initialValue: false)
// Default to current global AI provider/model for new configurations - use UserDefaults only
_selectedAIProvider = State(initialValue: UserDefaults.standard.string(forKey: "selectedAIProvider"))
_selectedAIModel = State(initialValue: nil) // Initialize to nil and set it after view appears
@ -90,6 +93,7 @@ struct ConfigurationView: View {
_selectedAppConfigs = State(initialValue: latestConfig.appConfigs ?? [])
_websiteConfigs = State(initialValue: latestConfig.urlConfigs ?? [])
_useScreenCapture = State(initialValue: latestConfig.useScreenCapture)
_isAutoSendEnabled = State(initialValue: latestConfig.isAutoSendEnabled)
_selectedAIProvider = State(initialValue: latestConfig.selectedAIProvider)
_selectedAIModel = State(initialValue: latestConfig.selectedAIModel)
case .editDefault(let config):
@ -102,6 +106,7 @@ struct ConfigurationView: View {
_configName = State(initialValue: latestConfig.name)
_selectedEmoji = State(initialValue: latestConfig.emoji)
_useScreenCapture = State(initialValue: latestConfig.useScreenCapture)
_isAutoSendEnabled = State(initialValue: latestConfig.isAutoSendEnabled)
_selectedAIProvider = State(initialValue: latestConfig.selectedAIProvider)
_selectedAIModel = State(initialValue: latestConfig.selectedAIModel)
}
@ -588,6 +593,25 @@ struct ConfigurationView: View {
.background(CardBackground(isSelected: false))
.padding(.horizontal)
// SECTION 4: ADVANCED
VStack(spacing: 16) {
SectionHeader(title: "Advanced")
HStack {
Toggle("Auto Send", isOn: $isAutoSendEnabled)
InfoTip(
title: "Auto Send",
message: "Automatically presses the Return/Enter key after pasting text. This is useful for chat applications or forms where its not necessary to to make changes to the transcribed text"
)
Spacer()
}
}
.padding()
.background(CardBackground(isSelected: false))
.padding(.horizontal)
// Save Button
VoiceInkButton(
title: mode.isAdding ? "Add New Power Mode" : "Save Changes",
@ -671,7 +695,8 @@ struct ConfigurationView: View {
selectedLanguage: selectedLanguage,
useScreenCapture: useScreenCapture,
selectedAIProvider: selectedAIProvider,
selectedAIModel: selectedAIModel
selectedAIModel: selectedAIModel,
isAutoSendEnabled: isAutoSendEnabled
)
case .edit(let config):
var updatedConfig = config
@ -684,6 +709,7 @@ struct ConfigurationView: View {
updatedConfig.appConfigs = selectedAppConfigs.isEmpty ? nil : selectedAppConfigs
updatedConfig.urlConfigs = websiteConfigs.isEmpty ? nil : websiteConfigs
updatedConfig.useScreenCapture = useScreenCapture
updatedConfig.isAutoSendEnabled = isAutoSendEnabled
updatedConfig.selectedAIProvider = selectedAIProvider
updatedConfig.selectedAIModel = selectedAIModel
return updatedConfig
@ -697,6 +723,7 @@ struct ConfigurationView: View {
updatedConfig.selectedTranscriptionModelName = selectedTranscriptionModelName
updatedConfig.selectedLanguage = selectedLanguage
updatedConfig.useScreenCapture = useScreenCapture
updatedConfig.isAutoSendEnabled = isAutoSendEnabled
updatedConfig.selectedAIProvider = selectedAIProvider
updatedConfig.selectedAIModel = selectedAIModel
return updatedConfig

View File

@ -340,6 +340,15 @@ class WhisperState: NSObject, ObservableObject {
if self.isAutoCopyEnabled {
ClipboardManager.copyToClipboard(text)
}
// Automatically press Enter if the active Power Mode configuration allows it.
let powerMode = PowerModeManager.shared
if powerMode.isPowerModeEnabled && powerMode.currentActiveConfiguration.isAutoSendEnabled {
// Slight delay to ensure the paste operation completes
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
CursorPaster.pressEnter()
}
}
}
if let result = promptDetectionResult,