feat: add Russian localization and independent STT languages
CI / Typecheck, tests, lint (push) Canceled after 0s
CI / Standalone (mac-arm64) (push) Canceled after 0s
CI / Standalone (linux-x64) (push) Canceled after 0s
CI / Standalone (windows-x64) (push) Canceled after 0s

This commit is contained in:
2026-10-25 17:18:44 +03:00
parent b277ee3e0f
commit a50ca4b867
93 changed files with 3261 additions and 904 deletions
+9 -6
View File
@@ -1,4 +1,6 @@
"use client";
import { useI18n } from "@/components/i18n";
import { useCallback, useEffect, useRef, useState, type ReactNode } from "react";
import { useRouter } from "next/navigation";
@@ -110,6 +112,7 @@ export function DraftShell({
* Passed as a node so the pick state stays in NewSession. */
overlay?: ReactNode;
}) {
const { t } = useI18n();
// Voice dictation (STT wave, 2026-09-17): finals append at the end of the
// draft text (via the parent's onChange — the truth lives there); the
// strip lives in the stats bar's middle slot.
@@ -172,11 +175,11 @@ export function DraftShell({
<Conversation className="h-full min-w-0 flex-1" initial="instant">
<ConversationContent className="min-h-full gap-0 p-0">
<ConversationEmptyState
title={mode === "practice" ? "New practice session" : "New session"}
title={mode === "practice" ? t("New practice session") : t("New session")}
description={
mode === "practice"
? "Pick nodes from your knowledge graph, describe what you want to practice, or bring your own problem."
: "The teacher will open by probing what you already know."
? t("Pick nodes from your knowledge graph, describe what you want to practice, or bring your own problem.")
: t("The teacher will open by probing what you already know.")
}
/>
</ConversationContent>
@@ -205,7 +208,7 @@ export function DraftShell({
// input (owner refinement round, 2026-09-24) — no lesson has
// started yet, so the composer must not read like one is in
// flight.
placeholder={mode === "practice" ? "What do you want to practice?" : "What do you want to learn?"}
placeholder={mode === "practice" ? t("What do you want to practice?") : t("What do you want to learn?")}
/>
</div>
<StatsBar
@@ -231,6 +234,7 @@ export function DraftShell({
}
export function NewSession({ initialConfigured, mode = "teach" }: { initialConfigured: boolean; mode?: "teach" | "practice" }) {
const { t } = useI18n();
const router = useRouter();
const [text, setText] = useState("");
/* The draft MIRROR ("nothing gets lost" round, 2026-10-01): the shell's
@@ -357,8 +361,7 @@ export function NewSession({ initialConfigured, mode = "teach" }: { initialConfi
onClick={() => setSetupOpen(true)}
className="rounded-sm border border-border bg-card px-3 py-1.5 font-ui text-xs text-foreground transition-colors hover:border-muted-foreground/50 hover:bg-accent cursor-pointer"
>
Set up your models
</button>
{t("Set up your models")}</button>
)
)
}