feat: add Russian localization and independent STT languages
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
"use client";
|
||||
import { useI18n } from "@/components/i18n";
|
||||
|
||||
|
||||
import { useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { DownloadIcon } from "lucide-react";
|
||||
@@ -100,12 +102,12 @@ export function DemoOutputCard({
|
||||
messageId?: string;
|
||||
initialInverted?: boolean;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
const result = output as DemoResult | undefined;
|
||||
if (!result || typeof result.html !== "string" || typeof result.title !== "string") {
|
||||
return (
|
||||
<div className="rounded-xl border bg-card p-4 text-sm text-muted-foreground">
|
||||
Demo completed, but the result could not be displayed.
|
||||
</div>
|
||||
{t("Demo completed, but the result could not be displayed.")}</div>
|
||||
);
|
||||
}
|
||||
const failed = result.html.length === 0;
|
||||
@@ -113,10 +115,9 @@ export function DemoOutputCard({
|
||||
return (
|
||||
<div className="rounded-xl border bg-card p-4 text-card-foreground" data-testid="demo-card-failed">
|
||||
<div className="flex items-center gap-2 text-xs font-medium uppercase tracking-wide text-muted-foreground">
|
||||
Interactive demo
|
||||
<span className="rounded bg-red-500/15 px-1.5 py-0.5 text-red-500">failed</span>
|
||||
{t("Interactive demo")}<span className="rounded bg-red-500/15 px-1.5 py-0.5 text-red-500">{t("failed")}</span>
|
||||
</div>
|
||||
<p className="mt-2 text-sm text-muted-foreground">{result.notes ?? "The demo could not be built."}</p>
|
||||
<p className="mt-2 text-sm text-muted-foreground">{result.notes ?? t("The demo could not be built.")}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -136,6 +137,7 @@ function DemoFrame({
|
||||
messageId?: string;
|
||||
initialInverted?: boolean;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
const actions = useContext(ChatActionsContext);
|
||||
const iframeRef = useRef<HTMLIFrameElement | null>(null);
|
||||
const [state, setState] = useState<DemoBridgeState>(INITIAL_DEMO_BRIDGE_STATE);
|
||||
@@ -177,22 +179,21 @@ function DemoFrame({
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<div className="flex min-w-0 items-baseline gap-2">
|
||||
<span className="shrink-0 text-xs font-medium uppercase tracking-wide text-muted-foreground">
|
||||
interactive demo
|
||||
</span>
|
||||
{t("interactive demo")}</span>
|
||||
<span className="truncate text-xs font-medium tracking-wide text-foreground">{title}</span>
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-1.5">
|
||||
<Toggle
|
||||
checked={inverted}
|
||||
onChange={toggleInverted}
|
||||
label="Invert demo brightness"
|
||||
title="Invert colors"
|
||||
label={t("Invert demo brightness")}
|
||||
title={t("Invert colors")}
|
||||
discIcon={<InvertDiscIcon className="size-3" />}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Download demo as HTML"
|
||||
title="Download as HTML"
|
||||
aria-label={t("Download demo as HTML")}
|
||||
title={t("Download as HTML")}
|
||||
onClick={() => downloadFile(`${slugFilename(title)}.html`, html, "text/html")}
|
||||
data-testid="demo-download"
|
||||
className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"
|
||||
@@ -205,7 +206,7 @@ function DemoFrame({
|
||||
<DemoErrorChip
|
||||
title={title}
|
||||
message={state.error}
|
||||
onSend={actions ? () => actions.sendText(`The demo "${title}" threw an error: ${state.error}`) : undefined}
|
||||
onSend={actions ? () => actions.sendText(t("The demo \"{v0}\" threw an error: {v1}", { v0: title, v1: state.error })) : undefined}
|
||||
/>
|
||||
)}
|
||||
<iframe
|
||||
@@ -245,12 +246,13 @@ export function DemoErrorChip({
|
||||
message: string;
|
||||
onSend?: () => void;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<div
|
||||
className="mt-2 flex flex-wrap items-center gap-2 rounded-lg bg-red-500/10 px-3 py-2 text-sm text-red-500"
|
||||
data-testid="demo-error-chip"
|
||||
>
|
||||
<span className="font-medium">This demo threw an error</span>
|
||||
<span className="font-medium">{t("This demo threw an error")}</span>
|
||||
<span className="min-w-0 flex-1 truncate font-mono text-xs" title={message}>
|
||||
{message}
|
||||
</span>
|
||||
@@ -261,8 +263,7 @@ export function DemoErrorChip({
|
||||
className="rounded-md border border-red-500/40 px-2 py-1 text-xs font-medium hover:bg-red-500/15"
|
||||
data-testid="demo-error-send"
|
||||
>
|
||||
Send to teacher
|
||||
</button>
|
||||
{t("Send to teacher")}</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user