feat: add Russian localization and independent STT languages
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
"use client";
|
||||
import { useI18n } from "@/components/i18n";
|
||||
|
||||
/**
|
||||
* The Keyboard section (thin settings wave): view / rebind / reset over
|
||||
* core/keyboard.ts's registry. The overrides persist in localStorage
|
||||
@@ -48,6 +50,7 @@ export function nextOverrides(
|
||||
}
|
||||
|
||||
export function KeyboardSection() {
|
||||
const { t } = useI18n();
|
||||
const [overrides, setOverrides] = useState<Partial<Record<KeyAction, string>>>({});
|
||||
const [rebinding, setRebinding] = useState<KeyAction | null>(null);
|
||||
const [nonce, setNonce] = useState(0);
|
||||
@@ -101,20 +104,20 @@ export function KeyboardSection() {
|
||||
if (!actions.length) return null;
|
||||
return (
|
||||
<div key={scope} data-testid={`kbd-scope-${scope}`}>
|
||||
<p className="mb-1 text-xs uppercase tracking-widest text-muted-foreground/70">{label}</p>
|
||||
<p className="mb-1 text-xs uppercase tracking-widest text-muted-foreground/70">{t(label)}</p>
|
||||
<div className="flex flex-col gap-2">
|
||||
{actions.map((def) => {
|
||||
const effective = overrides[def.id] ?? def.binding;
|
||||
return (
|
||||
<SettingsRow
|
||||
key={def.id}
|
||||
label={def.label}
|
||||
hint={def.displayOnly ? "Fixed — part of this screen" : undefined}
|
||||
label={t(def.label)}
|
||||
hint={def.displayOnly ? t("Fixed — part of this screen") : undefined}
|
||||
testid={`kbd-row-${def.id}`}
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
<kbd className="rounded-sm border border-border bg-muted px-1.5 py-0.5 font-ui text-xs">
|
||||
{rebinding === def.id ? "Press keys…" : formatBinding(effective)}
|
||||
{rebinding === def.id ? t("Press keys…") : t(formatBinding(effective))}
|
||||
</kbd>
|
||||
{def.displayOnly ? null : rebinding === def.id ? (
|
||||
<button
|
||||
@@ -122,8 +125,7 @@ export function KeyboardSection() {
|
||||
onClick={() => setRebinding(null)}
|
||||
className="text-xs text-muted-foreground/70 underline-offset-2 hover:text-foreground hover:underline"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
{t("Cancel")}</button>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
@@ -132,8 +134,7 @@ export function KeyboardSection() {
|
||||
data-testid={`kbd-rebind-${def.id}`}
|
||||
className="text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline"
|
||||
>
|
||||
Rebind
|
||||
</button>
|
||||
{t("Rebind")}</button>
|
||||
{overridden(def.id) && (
|
||||
<button
|
||||
type="button"
|
||||
@@ -141,8 +142,7 @@ export function KeyboardSection() {
|
||||
data-testid={`kbd-reset-${def.id}`}
|
||||
className="text-xs text-muted-foreground/70 underline-offset-2 hover:text-foreground hover:underline"
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
{t("Reset")}</button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
@@ -155,15 +155,14 @@ export function KeyboardSection() {
|
||||
);
|
||||
})}
|
||||
<div className="mt-1 flex items-center justify-between">
|
||||
<span className="text-xs text-muted-foreground/70">Stored on this device (lh:keymap) — overrides only.</span>
|
||||
<span className="text-xs text-muted-foreground/70">{t("Stored on this device (lh:keymap) — overrides only.")}</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={resetAll}
|
||||
data-testid="kbd-reset-all"
|
||||
className="text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline"
|
||||
>
|
||||
Reset all to defaults
|
||||
</button>
|
||||
{t("Reset all to defaults")}</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user