Add option to append trailing space after pasted text (#405)
This commit is contained in:
parent
244a99e623
commit
246feda45d
8 changed files with 61 additions and 1 deletions
|
|
@ -234,6 +234,13 @@ pub fn paste(text: String, app_handle: AppHandle) -> Result<(), String> {
|
||||||
let settings = get_settings(&app_handle);
|
let settings = get_settings(&app_handle);
|
||||||
let paste_method = settings.paste_method;
|
let paste_method = settings.paste_method;
|
||||||
|
|
||||||
|
// Append trailing space if setting is enabled
|
||||||
|
let text = if settings.append_trailing_space {
|
||||||
|
format!("{} ", text)
|
||||||
|
} else {
|
||||||
|
text
|
||||||
|
};
|
||||||
|
|
||||||
info!("Using paste method: {:?}", paste_method);
|
info!("Using paste method: {:?}", paste_method);
|
||||||
|
|
||||||
// Perform the paste operation
|
// Perform the paste operation
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,7 @@ pub fn run() {
|
||||||
shortcut::suspend_binding,
|
shortcut::suspend_binding,
|
||||||
shortcut::resume_binding,
|
shortcut::resume_binding,
|
||||||
shortcut::change_mute_while_recording_setting,
|
shortcut::change_mute_while_recording_setting,
|
||||||
|
shortcut::change_append_trailing_space_setting,
|
||||||
shortcut::change_update_checks_setting,
|
shortcut::change_update_checks_setting,
|
||||||
trigger_update_check,
|
trigger_update_check,
|
||||||
commands::cancel_operation,
|
commands::cancel_operation,
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,8 @@ pub struct AppSettings {
|
||||||
pub post_process_selected_prompt_id: Option<String>,
|
pub post_process_selected_prompt_id: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub mute_while_recording: bool,
|
pub mute_while_recording: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub append_trailing_space: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_model() -> String {
|
fn default_model() -> String {
|
||||||
|
|
@ -483,6 +485,7 @@ pub fn get_default_settings() -> AppSettings {
|
||||||
post_process_prompts: default_post_process_prompts(),
|
post_process_prompts: default_post_process_prompts(),
|
||||||
post_process_selected_prompt_id: None,
|
post_process_selected_prompt_id: None,
|
||||||
mute_while_recording: false,
|
mute_while_recording: false,
|
||||||
|
append_trailing_space: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -693,6 +693,16 @@ pub fn change_mute_while_recording_setting(app: AppHandle, enabled: bool) -> Res
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
#[specta::specta]
|
||||||
|
pub fn change_append_trailing_space_setting(app: AppHandle, enabled: bool) -> Result<(), String> {
|
||||||
|
let mut settings = settings::get_settings(&app);
|
||||||
|
settings.append_trailing_space = enabled;
|
||||||
|
settings::write_settings(&app, settings);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Determine whether a shortcut string contains at least one non-modifier key.
|
/// Determine whether a shortcut string contains at least one non-modifier key.
|
||||||
/// We allow single non-modifier keys (e.g. "f5" or "space") but disallow
|
/// We allow single non-modifier keys (e.g. "f5" or "space") but disallow
|
||||||
/// modifier-only combos (e.g. "ctrl" or "ctrl+shift").
|
/// modifier-only combos (e.g. "ctrl" or "ctrl+shift").
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,14 @@ async changeMuteWhileRecordingSetting(enabled: boolean) : Promise<Result<null, s
|
||||||
else return { status: "error", error: e as any };
|
else return { status: "error", error: e as any };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async changeAppendTrailingSpaceSetting(enabled: boolean) : Promise<Result<null, string>> {
|
||||||
|
try {
|
||||||
|
return { status: "ok", data: await TAURI_INVOKE("change_append_trailing_space_setting", { enabled }) };
|
||||||
|
} catch (e) {
|
||||||
|
if(e instanceof Error) throw e;
|
||||||
|
else return { status: "error", error: e as any };
|
||||||
|
}
|
||||||
|
},
|
||||||
async changeUpdateChecksSetting(enabled: boolean) : Promise<Result<null, string>> {
|
async changeUpdateChecksSetting(enabled: boolean) : Promise<Result<null, string>> {
|
||||||
try {
|
try {
|
||||||
return { status: "ok", data: await TAURI_INVOKE("change_update_checks_setting", { enabled }) };
|
return { status: "ok", data: await TAURI_INVOKE("change_update_checks_setting", { enabled }) };
|
||||||
|
|
@ -602,7 +610,7 @@ async isLaptop() : Promise<Result<boolean, string>> {
|
||||||
|
|
||||||
/** user-defined types **/
|
/** user-defined types **/
|
||||||
|
|
||||||
export type AppSettings = { bindings: Partial<{ [key in string]: ShortcutBinding }>; push_to_talk: boolean; audio_feedback: boolean; audio_feedback_volume?: number; sound_theme?: SoundTheme; start_hidden?: boolean; autostart_enabled?: boolean; update_checks_enabled?: boolean; selected_model?: string; always_on_microphone?: boolean; selected_microphone?: string | null; clamshell_microphone?: string | null; selected_output_device?: string | null; translate_to_english?: boolean; selected_language?: string; overlay_position?: OverlayPosition; debug_mode?: boolean; log_level?: LogLevel; custom_words?: string[]; model_unload_timeout?: ModelUnloadTimeout; word_correction_threshold?: number; history_limit?: string; recording_retention_period?: RecordingRetentionPeriod; paste_method?: PasteMethod; clipboard_handling?: ClipboardHandling; post_process_enabled?: boolean; post_process_provider_id?: string; post_process_providers?: PostProcessProvider[]; post_process_api_keys?: Partial<{ [key in string]: string }>; post_process_models?: Partial<{ [key in string]: string }>; post_process_prompts?: LLMPrompt[]; post_process_selected_prompt_id?: string | null; mute_while_recording?: boolean }
|
export type AppSettings = { bindings: Partial<{ [key in string]: ShortcutBinding }>; push_to_talk: boolean; audio_feedback: boolean; audio_feedback_volume?: number; sound_theme?: SoundTheme; start_hidden?: boolean; autostart_enabled?: boolean; update_checks_enabled?: boolean; selected_model?: string; always_on_microphone?: boolean; selected_microphone?: string | null; clamshell_microphone?: string | null; selected_output_device?: string | null; translate_to_english?: boolean; selected_language?: string; overlay_position?: OverlayPosition; debug_mode?: boolean; log_level?: LogLevel; custom_words?: string[]; model_unload_timeout?: ModelUnloadTimeout; word_correction_threshold?: number; history_limit?: string; recording_retention_period?: RecordingRetentionPeriod; paste_method?: PasteMethod; clipboard_handling?: ClipboardHandling; post_process_enabled?: boolean; post_process_provider_id?: string; post_process_providers?: PostProcessProvider[]; post_process_api_keys?: Partial<{ [key in string]: string }>; post_process_models?: Partial<{ [key in string]: string }>; post_process_prompts?: LLMPrompt[]; post_process_selected_prompt_id?: string | null; mute_while_recording?: boolean; append_trailing_space?: boolean }
|
||||||
export type AudioDevice = { index: string; name: string; is_default: boolean }
|
export type AudioDevice = { index: string; name: string; is_default: boolean }
|
||||||
export type BindingResponse = { success: boolean; binding: ShortcutBinding | null; error: string | null }
|
export type BindingResponse = { success: boolean; binding: ShortcutBinding | null; error: string | null }
|
||||||
export type ClipboardHandling = "dont_modify" | "copy_to_clipboard"
|
export type ClipboardHandling = "dont_modify" | "copy_to_clipboard"
|
||||||
|
|
|
||||||
27
src/components/settings/AppendTrailingSpace.tsx
Normal file
27
src/components/settings/AppendTrailingSpace.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import React from "react";
|
||||||
|
import { ToggleSwitch } from "../ui/ToggleSwitch";
|
||||||
|
import { useSettings } from "../../hooks/useSettings";
|
||||||
|
|
||||||
|
interface AppendTrailingSpaceProps {
|
||||||
|
descriptionMode?: "inline" | "tooltip";
|
||||||
|
grouped?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppendTrailingSpace: React.FC<AppendTrailingSpaceProps> =
|
||||||
|
React.memo(({ descriptionMode = "tooltip", grouped = false }) => {
|
||||||
|
const { getSetting, updateSetting, isUpdating } = useSettings();
|
||||||
|
|
||||||
|
const enabled = getSetting("append_trailing_space") ?? false;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ToggleSwitch
|
||||||
|
checked={enabled}
|
||||||
|
onChange={(enabled) => updateSetting("append_trailing_space", enabled)}
|
||||||
|
isUpdating={isUpdating("append_trailing_space")}
|
||||||
|
label="Append Trailing Space"
|
||||||
|
description="Automatically add a space at the end of transcribed text, making it easier to dictate multiple sentences in a row."
|
||||||
|
descriptionMode={descriptionMode}
|
||||||
|
grouped={grouped}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
@ -9,6 +9,7 @@ import { AlwaysOnMicrophone } from "../AlwaysOnMicrophone";
|
||||||
import { SoundPicker } from "../SoundPicker";
|
import { SoundPicker } from "../SoundPicker";
|
||||||
import { PostProcessingToggle } from "../PostProcessingToggle";
|
import { PostProcessingToggle } from "../PostProcessingToggle";
|
||||||
import { MuteWhileRecording } from "../MuteWhileRecording";
|
import { MuteWhileRecording } from "../MuteWhileRecording";
|
||||||
|
import { AppendTrailingSpace } from "../AppendTrailingSpace";
|
||||||
import { RecordingRetentionPeriodSelector } from "../RecordingRetentionPeriod";
|
import { RecordingRetentionPeriodSelector } from "../RecordingRetentionPeriod";
|
||||||
import { ClamshellMicrophoneSelector } from "../ClamshellMicrophoneSelector";
|
import { ClamshellMicrophoneSelector } from "../ClamshellMicrophoneSelector";
|
||||||
import { HandyShortcut } from "../HandyShortcut";
|
import { HandyShortcut } from "../HandyShortcut";
|
||||||
|
|
@ -40,6 +41,7 @@ export const DebugSettings: React.FC = () => {
|
||||||
<ClamshellMicrophoneSelector descriptionMode="tooltip" grouped={true} />
|
<ClamshellMicrophoneSelector descriptionMode="tooltip" grouped={true} />
|
||||||
<PostProcessingToggle descriptionMode="tooltip" grouped={true} />
|
<PostProcessingToggle descriptionMode="tooltip" grouped={true} />
|
||||||
<MuteWhileRecording descriptionMode="tooltip" grouped={true} />
|
<MuteWhileRecording descriptionMode="tooltip" grouped={true} />
|
||||||
|
<AppendTrailingSpace descriptionMode="tooltip" grouped={true} />
|
||||||
{/* Cancel shortcut is disabled on Linux due to instability with dynamic shortcut registration */}
|
{/* Cancel shortcut is disabled on Linux due to instability with dynamic shortcut registration */}
|
||||||
{!isLinux && (
|
{!isLinux && (
|
||||||
<HandyShortcut
|
<HandyShortcut
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,8 @@ const settingUpdaters: {
|
||||||
commands.setPostProcessSelectedPrompt(value as string),
|
commands.setPostProcessSelectedPrompt(value as string),
|
||||||
mute_while_recording: (value) =>
|
mute_while_recording: (value) =>
|
||||||
commands.changeMuteWhileRecordingSetting(value as boolean),
|
commands.changeMuteWhileRecordingSetting(value as boolean),
|
||||||
|
append_trailing_space: (value) =>
|
||||||
|
commands.changeAppendTrailingSpaceSetting(value as boolean),
|
||||||
log_level: (value) => commands.setLogLevel(value as any),
|
log_level: (value) => commands.setLogLevel(value as any),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue