feat: add preferred STT languages and fix model settings layout

This commit is contained in:
2026-10-26 02:14:27 +03:00
parent 70977bad84
commit ce28d95bcf
13 changed files with 195 additions and 50 deletions
+8 -7
View File
@@ -3,7 +3,7 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { Loader2Icon, MicIcon } from "lucide-react";
import { useSettingsDialog } from "@/components/settings/settings-dialog";
import { dictationUrl, type SttLanguage } from "@/src/core";
import { dictationUrl } from "@/src/core";
import { LanguageSelect, useI18n } from "@/components/i18n";
import { Hint } from "@/components/ui/hint";
@@ -279,10 +279,10 @@ export type Dictation = {
* question waits.
*/
export function useDictation({ append }: { append: (text: string) => void }): Dictation {
const { sttLanguage, setDictating } = useI18n();
const selectedLanguage = useRef(sttLanguage);
selectedLanguage.current = sttLanguage;
const recordingLanguage = useRef<SttLanguage>(sttLanguage);
const { sttLanguage, general, setDictating } = useI18n();
const selectedUrl = useRef("");
selectedUrl.current = dictationUrl(sttLanguage, general.sttPreferredLanguages);
const recordingUrl = useRef(selectedUrl.current);
const [phase, setPhase] = useState<DictationPhase>("idle");
const [error, setError] = useState<string | null>(null);
/** Latest RMS from the worklet — the meter samples this (dictate pattern). */
@@ -365,7 +365,7 @@ export function useDictation({ append }: { append: (text: string) => void }): Di
// Minted JWTs authenticate via the "bearer" subprotocol — ["token",
// jwt] is rejected at the handshake (verified live; "token" is for
// raw API keys only, as in the owner's pi dictate extension).
const ws = new WebSocket(dictationUrl(recordingLanguage.current), ["bearer", token]);
const ws = new WebSocket(recordingUrl.current, ["bearer", token]);
wsRef.current = ws;
ws.addEventListener("open", () => {
@@ -425,7 +425,8 @@ export function useDictation({ append }: { append: (text: string) => void }): Di
);
const start = useCallback(async () => {
recordingLanguage.current = selectedLanguage.current;
// Pin the complete configuration once; reconnects must retain both language and hints.
recordingUrl.current = selectedUrl.current;
setDictating(true);
dictationActiveFlag = true;
setError(null);