diff --git a/src/components/ai-edition/Modals.tsx b/src/components/ai-edition/Modals.tsx index 9ac9d1079..3be5687fd 100644 --- a/src/components/ai-edition/Modals.tsx +++ b/src/components/ai-edition/Modals.tsx @@ -17,51 +17,28 @@ import { type ReactNode, type PointerEvent as ReactPointerEvent, useEffect, + useMemo, useRef, useState, } from "react"; import { toFileUrl } from "@/components/video-editor/projectPersistence"; import type { CropRegion } from "@/components/video-editor/types"; -import { useScopedT } from "@/contexts/I18nContext"; +import { useI18n, useScopedT } from "@/contexts/I18nContext"; import { toAxcutTranscriptDsl } from "@/lib/ai-edition/document/transcribe"; -import type { AxcutClip, AxcutTranscript } from "@/lib/ai-edition/schema"; +import { + type AxcutClip, + type AxcutTranscript, + type TranscriptLanguageCode, + transcriptLanguageSchema, +} from "@/lib/ai-edition/schema"; import { formatSec, formatSeconds } from "@/lib/ai-edition/timeline/format"; +import { + languageLabel, + sortedLanguageOptions, +} from "@/lib/ai-edition/transcription/languageLabels"; import styles from "./NewEditorShell.module.css"; import type { VideoSource } from "./VirtualPreview"; -// ponytail: keep the UI's language list literal in one place. Mirrors -// `transcriptLanguageSchema` in schema/index.ts; if the schema gains a -// language, add it here too. -const REGEN_LANGUAGES = [ - "auto", - "en", - "fr", - "de", - "es", - "it", - "pt", - "nl", - "ja", - "ko", - "zh", -] as const; - -type TranscriptLanguage = (typeof REGEN_LANGUAGES)[number]; - -const LANGUAGE_LABELS: Record = { - auto: "Auto", - en: "EN", - fr: "FR", - de: "DE", - es: "ES", - it: "IT", - pt: "PT", - nl: "NL", - ja: "JA", - ko: "KO", - zh: "ZH", -}; - interface BaseModalProps { open: boolean; onClose: () => void; @@ -1539,6 +1516,17 @@ export function InsertSourceModal({ ); } +/** + * `AxcutTranscript.language` is `z.string().min(1)`, not validated against + * the known code list, so a stored transcript can hold a value no + * `