add experimental features to ui + reorg everything (#620)

This commit is contained in:
CJ Pais 2026-01-19 10:33:04 +08:00 committed by GitHub
parent f9d2aa68c3
commit 28d1d814b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 311 additions and 84 deletions

View file

@ -252,6 +252,7 @@ pub fn run() {
shortcut::change_paste_method_setting,
shortcut::change_clipboard_handling_setting,
shortcut::change_post_process_enabled_setting,
shortcut::change_experimental_enabled_setting,
shortcut::change_post_process_base_url_setting,
shortcut::change_post_process_api_key_setting,
shortcut::change_post_process_model_setting,

View file

@ -293,6 +293,8 @@ pub struct AppSettings {
pub append_trailing_space: bool,
#[serde(default = "default_app_language")]
pub app_language: String,
#[serde(default)]
pub experimental_enabled: bool,
}
fn default_model() -> String {
@ -581,6 +583,7 @@ pub fn get_default_settings() -> AppSettings {
mute_while_recording: false,
append_trailing_space: false,
app_language: default_app_language(),
experimental_enabled: false,
}
}

View file

@ -373,6 +373,15 @@ pub fn change_post_process_enabled_setting(app: AppHandle, enabled: bool) -> Res
Ok(())
}
#[tauri::command]
#[specta::specta]
pub fn change_experimental_enabled_setting(app: AppHandle, enabled: bool) -> Result<(), String> {
let mut settings = settings::get_settings(&app);
settings.experimental_enabled = enabled;
settings::write_settings(&app, settings);
Ok(())
}
#[tauri::command]
#[specta::specta]
pub fn change_post_process_base_url_setting(

View file

@ -133,6 +133,14 @@ async changePostProcessEnabledSetting(enabled: boolean) : Promise<Result<null, s
else return { status: "error", error: e as any };
}
},
async changeExperimentalEnabledSetting(enabled: boolean) : Promise<Result<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("change_experimental_enabled_setting", { enabled }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async changePostProcessBaseUrlSetting(providerId: string, baseUrl: string) : Promise<Result<null, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("change_post_process_base_url_setting", { providerId, baseUrl }) };
@ -640,7 +648,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?: number; 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; app_language?: string }
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?: number; 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; app_language?: string; experimental_enabled?: 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"

View file

@ -0,0 +1,30 @@
import React from "react";
import { useTranslation } from "react-i18next";
import { ToggleSwitch } from "../ui/ToggleSwitch";
import { useSettings } from "../../hooks/useSettings";
interface ExperimentalToggleProps {
descriptionMode?: "inline" | "tooltip";
grouped?: boolean;
}
export const ExperimentalToggle: React.FC<ExperimentalToggleProps> = React.memo(
({ descriptionMode = "tooltip", grouped = false }) => {
const { t } = useTranslation();
const { getSetting, updateSetting, isUpdating } = useSettings();
const enabled = getSetting("experimental_enabled") || false;
return (
<ToggleSwitch
checked={enabled}
onChange={(enabled) => updateSetting("experimental_enabled", enabled)}
isUpdating={isUpdating("experimental_enabled")}
label={t("settings.advanced.experimentalToggle.label")}
description={t("settings.advanced.experimentalToggle.description")}
descriptionMode={descriptionMode}
grouped={grouped}
/>
);
},
);

View file

@ -7,6 +7,7 @@ import { SettingContainer } from "../../ui/SettingContainer";
import { Button } from "../../ui/Button";
import { AppDataDirectory } from "../AppDataDirectory";
import { AppLanguageSelector } from "../AppLanguageSelector";
import { LogDirectory } from "../debug";
export const AboutSettings: React.FC = () => {
const { t } = useTranslation();
@ -47,7 +48,15 @@ export const AboutSettings: React.FC = () => {
<span className="text-sm font-mono">v{version}</span>
</SettingContainer>
<AppDataDirectory descriptionMode="tooltip" grouped={true} />
<SettingContainer
title={t("settings.about.supportDevelopment.title")}
description={t("settings.about.supportDevelopment.description")}
grouped={true}
>
<Button variant="primary" size="md" onClick={handleDonateClick}>
{t("settings.about.supportDevelopment.button")}
</Button>
</SettingContainer>
<SettingContainer
title={t("settings.about.sourceCode.title")}
@ -63,15 +72,8 @@ export const AboutSettings: React.FC = () => {
</Button>
</SettingContainer>
<SettingContainer
title={t("settings.about.supportDevelopment.title")}
description={t("settings.about.supportDevelopment.description")}
grouped={true}
>
<Button variant="primary" size="md" onClick={handleDonateClick}>
{t("settings.about.supportDevelopment.button")}
</Button>
</SettingContainer>
<AppDataDirectory descriptionMode="tooltip" grouped={true} />
<LogDirectory grouped={true} />
</SettingsGroup>
<SettingsGroup title={t("settings.about.acknowledgments.title")}>

View file

@ -10,27 +10,58 @@ import { AutostartToggle } from "../AutostartToggle";
import { PasteMethodSetting } from "../PasteMethod";
import { ClipboardHandlingSetting } from "../ClipboardHandling";
import { useModelStore } from "../../../stores/modelStore";
import { PostProcessingToggle } from "../PostProcessingToggle";
import { AppendTrailingSpace } from "../AppendTrailingSpace";
import { HistoryLimit } from "../HistoryLimit";
import { RecordingRetentionPeriodSelector } from "../RecordingRetentionPeriod";
import { ExperimentalToggle } from "../ExperimentalToggle";
import { useSettings } from "../../../hooks/useSettings";
export const AdvancedSettings: React.FC = () => {
const { t } = useTranslation();
const { currentModel, getModelInfo } = useModelStore();
const { getSetting } = useSettings();
const currentModelInfo = getModelInfo(currentModel);
const showTranslateToEnglish =
currentModelInfo?.engine_type === "Whisper" && currentModel !== "turbo";
const experimentalEnabled = getSetting("experimental_enabled") || false;
return (
<div className="max-w-3xl w-full mx-auto space-y-6">
<SettingsGroup title={t("settings.advanced.title")}>
<SettingsGroup title={t("settings.advanced.groups.app")}>
<StartHidden descriptionMode="tooltip" grouped={true} />
<AutostartToggle descriptionMode="tooltip" grouped={true} />
<ShowOverlay descriptionMode="tooltip" grouped={true} />
<ModelUnloadTimeoutSetting descriptionMode="tooltip" grouped={true} />
<ExperimentalToggle descriptionMode="tooltip" grouped={true} />
</SettingsGroup>
<SettingsGroup title={t("settings.advanced.groups.output")}>
<PasteMethodSetting descriptionMode="tooltip" grouped={true} />
<ClipboardHandlingSetting descriptionMode="tooltip" grouped={true} />
</SettingsGroup>
<SettingsGroup title={t("settings.advanced.groups.transcription")}>
{showTranslateToEnglish && (
<TranslateToEnglish descriptionMode="tooltip" grouped={true} />
)}
<ModelUnloadTimeoutSetting descriptionMode="tooltip" grouped={true} />
<CustomWords descriptionMode="tooltip" grouped />
<AppendTrailingSpace descriptionMode="tooltip" grouped={true} />
</SettingsGroup>
<SettingsGroup title={t("settings.advanced.groups.history")}>
<HistoryLimit descriptionMode="tooltip" grouped={true} />
<RecordingRetentionPeriodSelector
descriptionMode="tooltip"
grouped={true}
/>
</SettingsGroup>
{experimentalEnabled && (
<SettingsGroup title={t("settings.advanced.groups.experimental")}>
<PostProcessingToggle descriptionMode="tooltip" grouped={true} />
</SettingsGroup>
)}
</div>
);
};

View file

@ -2,16 +2,10 @@ import React from "react";
import { useTranslation } from "react-i18next";
import { type } from "@tauri-apps/plugin-os";
import { WordCorrectionThreshold } from "./WordCorrectionThreshold";
import { LogDirectory } from "./LogDirectory";
import { LogLevelSelector } from "./LogLevelSelector";
import { SettingsGroup } from "../../ui/SettingsGroup";
import { HistoryLimit } from "../HistoryLimit";
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";
import { UpdateChecksToggle } from "../UpdateChecksToggle";
@ -26,7 +20,6 @@ export const DebugSettings: React.FC = () => {
return (
<div className="max-w-3xl w-full mx-auto space-y-6">
<SettingsGroup title={t("settings.debug.title")}>
<LogDirectory grouped={true} />
<LogLevelSelector grouped={true} />
<UpdateChecksToggle descriptionMode="tooltip" grouped={true} />
<SoundPicker
@ -34,16 +27,8 @@ export const DebugSettings: React.FC = () => {
description={t("settings.debug.soundTheme.description")}
/>
<WordCorrectionThreshold descriptionMode="tooltip" grouped={true} />
<HistoryLimit descriptionMode="tooltip" grouped={true} />
<RecordingRetentionPeriodSelector
descriptionMode="tooltip"
grouped={true}
/>
<AlwaysOnMicrophone descriptionMode="tooltip" grouped={true} />
<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

View file

@ -10,6 +10,7 @@ import { AudioFeedback } from "../AudioFeedback";
import { useSettings } from "../../../hooks/useSettings";
import { useModelStore } from "../../../stores/modelStore";
import { VolumeSlider } from "../VolumeSlider";
import { MuteWhileRecording } from "../MuteWhileRecording";
export const GeneralSettings: React.FC = () => {
const { t } = useTranslation();
@ -28,6 +29,7 @@ export const GeneralSettings: React.FC = () => {
</SettingsGroup>
<SettingsGroup title={t("settings.sound.title")}>
<MicrophoneSelector descriptionMode="tooltip" grouped={true} />
<MuteWhileRecording descriptionMode="tooltip" grouped={true} />
<AudioFeedback descriptionMode="tooltip" grouped={true} />
<OutputDeviceSelector
descriptionMode="tooltip"

View file

@ -93,12 +93,12 @@
"pressKeys": "Stiskněte klávesy...",
"bindings": {
"transcribe": {
"name": "Přepsat",
"description": "Převádí vaši řeč na text."
"name": "Zkratka přepisu",
"description": "Klávesová zkratka pro nahrávání a přepis vašeho hlasu."
},
"cancel": {
"name": "Zrušit",
"description": "Zruší aktuální nahrávání."
"name": "Zkratka zrušení",
"description": "Klávesová zkratka pro zrušení aktuálního nahrávání."
}
},
"errors": {
@ -145,6 +145,17 @@
},
"advanced": {
"title": "Pokročilé",
"groups": {
"app": "Aplikace",
"output": "Výstup",
"transcription": "Přepis",
"history": "Historie",
"experimental": "Experimentální"
},
"experimentalToggle": {
"label": "Experimentální funkce",
"description": "Povolit experimentální funkce, které jsou stále ve vývoji."
},
"startHidden": {
"label": "Spouštět skrytě",
"description": "Spustit do systémové lišty bez otevření okna."

View file

@ -109,12 +109,12 @@
"pressKeys": "Tasten drücken...",
"bindings": {
"transcribe": {
"name": "Transkribieren",
"description": "Wandelt Sprache in Text um."
"name": "Transkriptions-Tastenkürzel",
"description": "Das Tastenkürzel zum Aufnehmen und Transkribieren Ihrer Stimme."
},
"cancel": {
"name": "Abbrechen",
"description": "Bricht die aktuelle Aufnahme ab."
"name": "Abbrechen-Tastenkürzel",
"description": "Das Tastenkürzel zum Abbrechen der aktuellen Aufnahme."
}
},
"errors": {
@ -161,6 +161,17 @@
},
"advanced": {
"title": "Erweitert",
"groups": {
"app": "App",
"output": "Ausgabe",
"transcription": "Transkription",
"history": "Verlauf",
"experimental": "Experimentell"
},
"experimentalToggle": {
"label": "Experimentelle Funktionen",
"description": "Experimentelle Funktionen aktivieren, die sich noch in Entwicklung befinden."
},
"startHidden": {
"label": "Versteckt starten",
"description": "In den Systembereich starten, ohne das Fenster zu öffnen."

View file

@ -113,12 +113,12 @@
"pressKeys": "Press keys...",
"bindings": {
"transcribe": {
"name": "Transcribe",
"description": "Converts your speech into text."
"name": "Transcribe Shortcut",
"description": "The keyboard shortcut to record and transcribe your voice."
},
"cancel": {
"name": "Cancel",
"description": "Cancels the current recording."
"name": "Cancel Shortcut",
"description": "The keyboard shortcut to cancel the current recording."
}
},
"errors": {
@ -165,6 +165,17 @@
},
"advanced": {
"title": "Advanced",
"groups": {
"app": "App",
"output": "Output",
"transcription": "Transcription",
"history": "History",
"experimental": "Experimental"
},
"experimentalToggle": {
"label": "Experimental Features",
"description": "Enable experimental features that are still in development."
},
"startHidden": {
"label": "Start Hidden",
"description": "Launch to system tray without opening the window."

View file

@ -109,12 +109,12 @@
"pressKeys": "Presiona teclas...",
"bindings": {
"transcribe": {
"name": "Transcribir",
"description": "Convierte tu voz en texto."
"name": "Atajo de Transcripción",
"description": "El atajo de teclado para grabar y transcribir tu voz."
},
"cancel": {
"name": "Cancelar",
"description": "Cancela la grabación actual."
"name": "Atajo de Cancelar",
"description": "El atajo de teclado para cancelar la grabación actual."
}
},
"errors": {
@ -161,6 +161,17 @@
},
"advanced": {
"title": "Avanzado",
"groups": {
"app": "Aplicación",
"output": "Salida",
"transcription": "Transcripción",
"history": "Historial",
"experimental": "Experimental"
},
"experimentalToggle": {
"label": "Funciones Experimentales",
"description": "Habilitar funciones experimentales que aún están en desarrollo."
},
"startHidden": {
"label": "Iniciar Oculto",
"description": "Lanzar en la bandeja del sistema sin abrir la ventana."

View file

@ -110,12 +110,12 @@
"pressKeys": "Appuyez sur les touches...",
"bindings": {
"transcribe": {
"name": "Démarrer la transcription",
"description": "Convertir votre voix en texte."
"name": "Raccourci de Transcription",
"description": "Le raccourci clavier pour enregistrer et transcrire votre voix."
},
"cancel": {
"name": "Annuler",
"description": "Annule l'enregistrement en cours."
"name": "Raccourci d'Annulation",
"description": "Le raccourci clavier pour annuler l'enregistrement en cours."
}
},
"errors": {
@ -162,6 +162,17 @@
},
"advanced": {
"title": "Avancé",
"groups": {
"app": "Application",
"output": "Sortie",
"transcription": "Transcription",
"history": "Historique",
"experimental": "Expérimental"
},
"experimentalToggle": {
"label": "Fonctionnalités Expérimentales",
"description": "Activer les fonctionnalités expérimentales encore en développement."
},
"startHidden": {
"label": "Démarrer masqué",
"description": "Lancer dans la barre système sans ouvrir la fenêtre."

View file

@ -109,12 +109,12 @@
"pressKeys": "Premi i tasti...",
"bindings": {
"transcribe": {
"name": "Trascrivi",
"description": "Converti la tua voce in testo."
"name": "Scorciatoia Trascrizione",
"description": "La scorciatoia da tastiera per registrare e trascrivere la tua voce."
},
"cancel": {
"name": "Annulla",
"description": "Annulla la registrazione in corso."
"name": "Scorciatoia Annulla",
"description": "La scorciatoia da tastiera per annullare la registrazione in corso."
}
},
"errors": {
@ -161,6 +161,17 @@
},
"advanced": {
"title": "Avanzate",
"groups": {
"app": "App",
"output": "Output",
"transcription": "Trascrizione",
"history": "Cronologia",
"experimental": "Sperimentale"
},
"experimentalToggle": {
"label": "Funzionalità Sperimentali",
"description": "Abilita le funzionalità sperimentali ancora in fase di sviluppo."
},
"startHidden": {
"label": "Avvia in Background",
"description": "Avvia l'applicazione in background senza aprire la finestra."

View file

@ -109,12 +109,12 @@
"pressKeys": "キーを押してください...",
"bindings": {
"transcribe": {
"name": "文字起こし",
"description": "音声をテキストに変換します。"
"name": "文字起こしショートカット",
"description": "音声を録音して文字起こしするためのキーボードショートカット。"
},
"cancel": {
"name": "キャンセル",
"description": "現在の録音をキャンセルします。"
"name": "キャンセルショートカット",
"description": "現在の録音をキャンセルるためのキーボードショートカット。"
}
},
"errors": {
@ -161,6 +161,17 @@
},
"advanced": {
"title": "詳細設定",
"groups": {
"app": "アプリ",
"output": "出力",
"transcription": "文字起こし",
"history": "履歴",
"experimental": "実験的"
},
"experimentalToggle": {
"label": "実験的機能",
"description": "まだ開発中の実験的機能を有効にします。"
},
"startHidden": {
"label": "非表示で起動",
"description": "ウィンドウを開かずにシステムトレイに起動。"

View file

@ -109,12 +109,12 @@
"pressKeys": "Naciśnij klawisze...",
"bindings": {
"transcribe": {
"name": "Transkrybuj",
"description": "Konwertuje Twoją mowę na tekst."
"name": "Skrót transkrypcji",
"description": "Skrót klawiaturowy do nagrywania i transkrypcji głosu."
},
"cancel": {
"name": "Anuluj",
"description": "Anuluje bieżące nagrywanie."
"name": "Skrót anulowania",
"description": "Skrót klawiaturowy do anulowania bieżącego nagrywania."
}
},
"errors": {
@ -161,6 +161,17 @@
},
"advanced": {
"title": "Zaawansowane",
"groups": {
"app": "Aplikacja",
"output": "Wyjście",
"transcription": "Transkrypcja",
"history": "Historia",
"experimental": "Eksperymentalne"
},
"experimentalToggle": {
"label": "Funkcje Eksperymentalne",
"description": "Włącz funkcje eksperymentalne, które są jeszcze w fazie rozwoju."
},
"startHidden": {
"label": "Uruchom ukryty",
"description": "Uruchom w zasobniku systemowym bez otwierania okna."

View file

@ -109,12 +109,12 @@
"pressKeys": "Pressione as teclas...",
"bindings": {
"transcribe": {
"name": "Transcrever",
"description": "Converte sua fala em texto."
"name": "Atalho de Transcrição",
"description": "O atalho de teclado para gravar e transcrever sua voz."
},
"cancel": {
"name": "Cancelar",
"description": "Cancela a gravação atual."
"name": "Atalho de Cancelar",
"description": "O atalho de teclado para cancelar a gravação atual."
}
},
"errors": {
@ -161,6 +161,17 @@
},
"advanced": {
"title": "Avançado",
"groups": {
"app": "Aplicativo",
"output": "Saída",
"transcription": "Transcrição",
"history": "Histórico",
"experimental": "Experimental"
},
"experimentalToggle": {
"label": "Recursos Experimentais",
"description": "Ativar recursos experimentais que ainda estão em desenvolvimento."
},
"startHidden": {
"label": "Iniciar Oculto",
"description": "Iniciar na bandeja do sistema sem abrir a janela."

View file

@ -109,12 +109,12 @@
"pressKeys": "Нажимайте клавиши...",
"bindings": {
"transcribe": {
"name": "Расшифровать",
"description": "Преобразует вашу речь в текст."
"name": "Горячая клавиша транскрипции",
"description": "Сочетание клавиш для записи и транскрибирования вашего голоса."
},
"cancel": {
"name": "Отмена",
"description": "Отменяет текущую запись."
"name": "Горячая клавиша отмены",
"description": "Сочетание клавиш для отмены текущей записи."
}
},
"errors": {
@ -161,6 +161,17 @@
},
"advanced": {
"title": "Продвинутые",
"groups": {
"app": "Приложение",
"output": "Вывод",
"transcription": "Транскрипция",
"history": "История",
"experimental": "Экспериментальное"
},
"experimentalToggle": {
"label": "Экспериментальные функции",
"description": "Включить экспериментальные функции, которые находятся в разработке."
},
"startHidden": {
"label": "Запускать скрыто",
"description": "Запускать в системный трей, не открывая окно."

View file

@ -113,12 +113,12 @@
"pressKeys": "Tuşlara basın...",
"bindings": {
"transcribe": {
"name": "Transkribe Et",
"description": "Konuşmanızı metne dönüştürür."
"name": "Transkripsiyon Kısayolu",
"description": "Sesinizi kaydetmek ve metne dönüştürmek için klavye kısayolu."
},
"cancel": {
"name": "İptal",
"description": "Mevcut kaydı iptal eder."
"name": "İptal Kısayolu",
"description": "Mevcut kaydı iptal etmek için klavye kısayolu."
}
},
"errors": {
@ -165,6 +165,17 @@
},
"advanced": {
"title": "Gelişmiş",
"groups": {
"app": "Uygulama",
"output": ıktı",
"transcription": "Transkripsiyon",
"history": "Geçmiş",
"experimental": "Deneysel"
},
"experimentalToggle": {
"label": "Deneysel Özellikler",
"description": "Hala geliştirme aşamasında olan deneysel özellikleri etkinleştir."
},
"startHidden": {
"label": "Gizli Başlat",
"description": "Pencereyi açmadan sistem tepsisinde başlatır."

View file

@ -109,12 +109,12 @@
"pressKeys": "Натисніть клавіші...",
"bindings": {
"transcribe": {
"name": "Диктувати",
"description": "Перетворює ваше мовлення в текст"
"name": "Гаряча клавіша транскрипції",
"description": "Комбінація клавіш для запису та транскрибування вашого голосу."
},
"cancel": {
"name": "Скасувати",
"description": "Скасовує поточний запис"
"name": "Гаряча клавіша скасування",
"description": "Комбінація клавіш для скасування поточного запису."
}
},
"errors": {
@ -161,6 +161,17 @@
},
"advanced": {
"title": "Розширені",
"groups": {
"app": "Додаток",
"output": "Вивід",
"transcription": "Транскрипція",
"history": "Історія",
"experimental": "Експериментальне"
},
"experimentalToggle": {
"label": "Експериментальні функції",
"description": "Увімкнути експериментальні функції, які ще в розробці."
},
"startHidden": {
"label": "Запуск у фоні",
"description": "Запускати в системному треї без відкриття вікна"

View file

@ -110,12 +110,12 @@
"pressKeys": "Nhấn phím...",
"bindings": {
"transcribe": {
"name": "Chuyển đổi",
"description": "Chuyển đổi giọng nói của bạn thành văn bản."
"name": "Phím tắt chuyển đổi",
"description": "Phím tắt để ghi âm và chuyển đổi giọng nói của bạn."
},
"cancel": {
"name": "Hủy",
"description": "Hủy bản ghi hiện tại."
"name": "Phím tắt hủy",
"description": "Phím tắt để hủy bản ghi hiện tại."
}
},
"errors": {
@ -162,6 +162,17 @@
},
"advanced": {
"title": "Nâng cao",
"groups": {
"app": "Ứng dụng",
"output": "Đầu ra",
"transcription": "Chuyển đổi",
"history": "Lịch sử",
"experimental": "Thử nghiệm"
},
"experimentalToggle": {
"label": "Tính năng thử nghiệm",
"description": "Bật các tính năng thử nghiệm đang trong quá trình phát triển."
},
"startHidden": {
"label": "Khởi động ẩn",
"description": "Khởi động vào khay hệ thống mà không mở cửa sổ."

View file

@ -109,12 +109,12 @@
"pressKeys": "请按键...",
"bindings": {
"transcribe": {
"name": "转录",
"description": "将语音转换为文字。"
"name": "转录快捷键",
"description": "用于录制和转录语音的键盘快捷键。"
},
"cancel": {
"name": "取消",
"description": "取消当前录制。"
"name": "取消快捷键",
"description": "用于取消当前录制的键盘快捷键。"
}
},
"errors": {
@ -161,6 +161,17 @@
},
"advanced": {
"title": "高级",
"groups": {
"app": "应用",
"output": "输出",
"transcription": "转录",
"history": "历史",
"experimental": "实验性"
},
"experimentalToggle": {
"label": "实验性功能",
"description": "启用仍在开发中的实验性功能。"
},
"startHidden": {
"label": "隐藏启动",
"description": "启动到系统托盘而不打开窗口。"

View file

@ -125,6 +125,8 @@ const settingUpdaters: {
commands.changeAppendTrailingSpaceSetting(value as boolean),
log_level: (value) => commands.setLogLevel(value as any),
app_language: (value) => commands.changeAppLanguageSetting(value as string),
experimental_enabled: (value) =>
commands.changeExperimentalEnabledSetting(value as boolean),
};
export const useSettingsStore = create<SettingsStore>()(