Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src-tauri/src/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,13 @@ pub fn paste(text: String, app_handle: AppHandle) -> Result<(), String> {
let settings = get_settings(&app_handle);
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);

// Perform the paste operation
Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ pub fn run() {
shortcut::suspend_binding,
shortcut::resume_binding,
shortcut::change_mute_while_recording_setting,
shortcut::change_append_trailing_space_setting,
shortcut::change_update_checks_setting,
trigger_update_check,
commands::cancel_operation,
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ pub struct AppSettings {
pub post_process_selected_prompt_id: Option<String>,
#[serde(default)]
pub mute_while_recording: bool,
#[serde(default)]
pub append_trailing_space: bool,
}

fn default_model() -> String {
Expand Down Expand Up @@ -483,6 +485,7 @@ pub fn get_default_settings() -> AppSettings {
post_process_prompts: default_post_process_prompts(),
post_process_selected_prompt_id: None,
mute_while_recording: false,
append_trailing_space: false,
}
}

Expand Down
10 changes: 10 additions & 0 deletions src-tauri/src/shortcut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,16 @@ pub fn change_mute_while_recording_setting(app: AppHandle, enabled: bool) -> Res
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.
/// We allow single non-modifier keys (e.g. "f5" or "space") but disallow
/// modifier-only combos (e.g. "ctrl" or "ctrl+shift").
Expand Down
10 changes: 9 additions & 1 deletion src/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,14 @@ async changeMuteWhileRecordingSetting(enabled: boolean) : Promise<Result<null, s
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>> {
try {
return { status: "ok", data: await TAURI_INVOKE("change_update_checks_setting", { enabled }) };
Expand Down Expand Up @@ -602,7 +610,7 @@ async isLaptop() : Promise<Result<boolean, string>> {

/** 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 BindingResponse = { success: boolean; binding: ShortcutBinding | null; error: string | null }
export type ClipboardHandling = "dont_modify" | "copy_to_clipboard"
Expand Down
27 changes: 27 additions & 0 deletions src/components/settings/AppendTrailingSpace.tsx
Original file line number Diff line number Diff line change
@@ -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}
/>
);
});
2 changes: 2 additions & 0 deletions src/components/settings/debug/DebugSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { AlwaysOnMicrophone } from "../AlwaysOnMicrophone";
import { SoundPicker } from "../SoundPicker";
import { PostProcessingToggle } from "../PostProcessingToggle";
import { MuteWhileRecording } from "../MuteWhileRecording";
import { AppendTrailingSpace } from "../AppendTrailingSpace";
import { RecordingRetentionPeriodSelector } from "../RecordingRetentionPeriod";
import { ClamshellMicrophoneSelector } from "../ClamshellMicrophoneSelector";
import { HandyShortcut } from "../HandyShortcut";
Expand Down Expand Up @@ -40,6 +41,7 @@ export const DebugSettings: React.FC = () => {
<ClamshellMicrophoneSelector descriptionMode="tooltip" grouped={true} />
<PostProcessingToggle 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 */}
{!isLinux && (
<HandyShortcut
Expand Down
2 changes: 2 additions & 0 deletions src/stores/settingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ const settingUpdaters: {
commands.setPostProcessSelectedPrompt(value as string),
mute_while_recording: (value) =>
commands.changeMuteWhileRecordingSetting(value as boolean),
append_trailing_space: (value) =>
commands.changeAppendTrailingSpaceSetting(value as boolean),
log_level: (value) => commands.setLogLevel(value as any),
};

Expand Down