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
+12 -6
View File
@@ -1,4 +1,6 @@
"use client";
import { useI18n } from "@/components/i18n";
/**
* MARKDOWN BLOCKS, MELTED INTO THE MESSAGE (owner wave, 2026-09-19): the
@@ -139,6 +141,7 @@ export function codeSource(children: ReactNode): string {
* still streaming (the trailing open fence), a quiet skeleton instead of a
* doomed parse. */
function MermaidInline({ chart }: { chart: string }) {
const { t } = useI18n();
const [svg, setSvg] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const [attempt, setAttempt] = useState(0);
@@ -199,17 +202,17 @@ function MermaidInline({ chart }: { chart: string }) {
dangerouslySetInnerHTML={{ __html: svg ?? "" }}
/>
<div className="absolute top-0 right-0 flex items-start gap-0.5">
<CopyCorner getText={() => chart} label="Copy diagram source" />
<CopyCorner getText={() => chart} label={t("Copy diagram source")} />
{overlay && (
<Hint
// Full-screen overlay copy (tooltip wave) — "session view" was
// internal direction-speak for the same thing.
label="Open full-screen"
label={t("Open full-screen")}
side="bottom"
>
<button
type="button"
aria-label="Expand diagram"
aria-label={t("Expand diagram")}
data-testid="md-mermaid-expand"
className="flex size-6 items-center justify-center rounded-md text-muted-foreground/70 opacity-0 transition-opacity hover:bg-accent hover:text-foreground group-hover/md:opacity-100"
onClick={(e) => {
@@ -234,6 +237,7 @@ function MermaidInline({ chart }: { chart: string }) {
* mounts. The container/look is CSS-melted in globals.css
* (data-streamdown="code-block"…). */
export function MarkdownCode(props: ComponentProps<"code"> & ExtraProps) {
const { t } = useI18n();
const incomplete = useIsCodeFenceIncomplete();
const { children, className, node, ...rest } = props;
@@ -257,7 +261,7 @@ export function MarkdownCode(props: ComponentProps<"code"> & ExtraProps) {
const lineNumbers = !/\bnoLineNumbers\b/.test(meta);
return (
<div className="group/md relative" data-testid="md-code">
<CopyCorner className="absolute top-1.5 right-2 z-10" getText={() => source} label="Copy code" />
<CopyCorner className="absolute top-1.5 right-2 z-10" getText={() => source} label={t("Copy code")} />
<CodeBlock
code={source}
language={language}
@@ -374,6 +378,7 @@ export function MarkdownBlockquote(props: ComponentProps<"blockquote"> & ExtraPr
* horizontal-scroller for wide ones, with the corner copy. The copy
* serializes the REAL DOM table (the library's own extractor → Markdown). */
export function MarkdownTable(props: ComponentProps<"table"> & ExtraProps) {
const { t } = useI18n();
const { children, node, ...rest } = props;
const ref = useRef<HTMLTableElement>(null);
return (
@@ -385,7 +390,7 @@ export function MarkdownTable(props: ComponentProps<"table"> & ExtraProps) {
// cells it hovers over; the scroll container stays under it (the
// corner is fixed to the wrapper, not the scrolling table).
className="absolute top-1 right-1 z-10"
label="Copy table"
label={t("Copy table")}
getText={() => (ref.current ? tableDataToMarkdown(extractTableDataFromElement(ref.current)) : "")}
/>
<div className="overflow-x-auto">
@@ -414,6 +419,7 @@ export function MarkdownTable(props: ComponentProps<"table"> & ExtraProps) {
* in the MathML <annotation>; read from the DOM on click, no re-parse).
* Every other span passes through untouched. */
export function MathDisplay(props: ComponentProps<"span"> & ExtraProps) {
const { t } = useI18n();
const { children, className, node, ...rest } = props;
const ref = useRef<HTMLSpanElement>(null);
if (!className?.includes("katex-display")) {
@@ -434,7 +440,7 @@ export function MathDisplay(props: ComponentProps<"span"> & ExtraProps) {
<span className="group/md relative block z-0" data-testid="md-math">
<CopyCorner
className="absolute top-0 right-0 z-10"
label="Copy equation source"
label={t("Copy equation source")}
getText={() => ref.current?.querySelector("annotation")?.textContent ?? ""}
/>
<span ref={ref} className={className} {...rest}>