feat: add Russian localization and independent STT languages
This commit is contained in:
+13
-10
@@ -1,4 +1,6 @@
|
||||
"use client";
|
||||
import { useI18n } from "@/components/i18n";
|
||||
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import type { ChatSettings, ModelCatalogEntry, ModelCatalogResponse, ModelsSettings, UserSettings } from "@/src/core";
|
||||
@@ -82,6 +84,7 @@ export function catalogLimits(catalog: Pick<ModelCatalogResponse, "models">): Ma
|
||||
* no-factory-fallback language: the UI never presents a default model).
|
||||
*/
|
||||
export function ModelControl({ chatId, onModelChange }: { chatId?: string; onModelChange?: (model: string | undefined) => void }) {
|
||||
const { t } = useI18n();
|
||||
const { catalog, refresh } = useModelCatalog();
|
||||
const [models, setModels] = useState<ModelsSettings | undefined>();
|
||||
const [session, setSession] = useState<ChatSettings | undefined>();
|
||||
@@ -318,7 +321,7 @@ export function ModelControl({ chatId, onModelChange }: { chatId?: string; onMod
|
||||
// Trimmed (owner, subtlety round 2026-09-25): "Model selector"
|
||||
// — the long sentence was way too much. ⌘K opens this same
|
||||
// menu (registry, override-aware).
|
||||
label="Model selector"
|
||||
label={t("Model selector")}
|
||||
action="open-model-picker"
|
||||
side="bottom"
|
||||
>
|
||||
@@ -341,7 +344,7 @@ export function ModelControl({ chatId, onModelChange }: { chatId?: string; onMod
|
||||
// "Thinking" + its real shortcut via the registry (owner interlude
|
||||
// 2026-09-25): ⇧⇥ cycles the level, so "Thinking (⇧⇥)" —
|
||||
// rebind-live like every Hint suffix.
|
||||
label="Thinking"
|
||||
label={t("Thinking")}
|
||||
action="cycle-thinking"
|
||||
side="bottom"
|
||||
>
|
||||
@@ -364,7 +367,7 @@ export function ModelControl({ chatId, onModelChange }: { chatId?: string; onMod
|
||||
{/* Just the level — the button reads like the model button reads
|
||||
the model name (owner, stats-control round 1). */}
|
||||
<span className="text-card-foreground">
|
||||
{effectiveLevel === undefined ? "—" : (THINKING_LABEL[effectiveLevel] ?? effectiveLevel)}
|
||||
{effectiveLevel === undefined ? "—" : t(THINKING_LABEL[effectiveLevel] ?? effectiveLevel)}
|
||||
</span>
|
||||
<span aria-hidden className="text-xs text-muted-foreground">▾</span>
|
||||
</button>
|
||||
@@ -380,7 +383,7 @@ export function ModelControl({ chatId, onModelChange }: { chatId?: string; onMod
|
||||
preferredSide="up"
|
||||
menuClass="flex w-[22rem] flex-col rounded-xl border bg-card p-2 text-xs shadow-xl"
|
||||
>
|
||||
{error && <div className="mb-1.5 text-destructive">{error}</div>}
|
||||
{error && <div className="mb-1.5 text-destructive">{t(error)}</div>}
|
||||
<ModelMenuList
|
||||
models={catalog?.models}
|
||||
effectiveId={effectiveId}
|
||||
@@ -388,10 +391,10 @@ export function ModelControl({ chatId, onModelChange }: { chatId?: string; onMod
|
||||
onPick={pickModel}
|
||||
footer={
|
||||
catalog && catalog.models.length === 0
|
||||
? "No models — add a provider key in Keys"
|
||||
? t("No models — add a provider key in Keys")
|
||||
: chatId
|
||||
? "This session's model"
|
||||
: "Strong tier — the default for new sessions"
|
||||
? t("This session's model")
|
||||
: t("Strong tier — the default for new sessions")
|
||||
}
|
||||
/>
|
||||
</MenuShell>
|
||||
@@ -408,10 +411,10 @@ export function ModelControl({ chatId, onModelChange }: { chatId?: string; onMod
|
||||
levels={catalog ? levels : []}
|
||||
effectiveLevel={effectiveLevel}
|
||||
onPick={(level) => apply(effectiveProvider ?? "", effectiveId ?? "", level as ThinkingLevel)}
|
||||
empty={catalog ? (effectiveId ? `${prettyModel(effectiveId)} has no thinking levels.` : "Pick a model first.") : "Loading…"}
|
||||
footer="Levels this model actually supports"
|
||||
empty={catalog ? (effectiveId ? t("{v0} has no thinking levels.", { v0: prettyModel(effectiveId) }) : t("Pick a model first.")) : t("Loading…")}
|
||||
footer={t("Levels this model actually supports")}
|
||||
/>
|
||||
{error && <div className="mt-1 text-destructive">{error}</div>}
|
||||
{error && <div className="mt-1 text-destructive">{t(error)}</div>}
|
||||
</MenuShell>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user