Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/api/generate/scene-content/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ export async function POST(req: NextRequest) {
// Ensure outline has language from stageInfo (fallback for older outlines)
const outline: SceneOutline = {
...rawOutline,
language: rawOutline.language || (stageInfo?.language as 'zh-CN' | 'en-US') || 'zh-CN',
language:
rawOutline.language ||
(stageInfo?.language as import('@/lib/types/generation').CourseLanguage) ||
'zh-CN',
};

// ── Model resolution from request headers ──
Expand Down
18 changes: 15 additions & 3 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const RECENT_OPEN_STORAGE_KEY = 'recentClassroomsOpen';
interface FormState {
pdfFile: File | null;
requirement: string;
language: 'zh-CN' | 'en-US';
language: import('@/lib/types/generation').CourseLanguage;
webSearch: boolean;
}

Expand Down Expand Up @@ -101,10 +101,22 @@ function HomePage() {
const savedLanguage = localStorage.getItem(LANGUAGE_STORAGE_KEY);
const updates: Partial<FormState> = {};
if (savedWebSearch === 'true') updates.webSearch = true;
if (savedLanguage === 'zh-CN' || savedLanguage === 'en-US') {
if (
savedLanguage === 'zh-CN' ||
savedLanguage === 'en-US' ||
savedLanguage === 'ja-JP' ||
savedLanguage === 'ru-RU'
) {
updates.language = savedLanguage;
} else {
const detected = navigator.language?.startsWith('zh') ? 'zh-CN' : 'en-US';
const lang = navigator.language;
const detected = lang?.startsWith('zh')
? 'zh-CN'
: lang?.startsWith('ja')
? 'ja-JP'
: lang?.startsWith('ru')
? 'ru-RU'
: 'en-US';
updates.language = detected;
}
if (Object.keys(updates).length > 0) {
Expand Down
18 changes: 16 additions & 2 deletions components/agent/agent-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,14 @@ function AgentVoicePill({
const courseLanguage =
(typeof localStorage !== 'undefined' && localStorage.getItem('generationLanguage')) ||
'zh-CN';
const previewText = courseLanguage === 'en-US' ? 'Welcome to AI Classroom' : '欢迎来到AI课堂';
const previewText =
courseLanguage === 'en-US'
? 'Welcome to AI Classroom'
: courseLanguage === 'ja-JP'
? 'AIクラスルームへようこそ'
: courseLanguage === 'ru-RU'
? 'Добро пожаловать в AI-класс'
: '欢迎来到AI课堂';

if (providerId === 'browser-native-tts') {
const { promise, cancel } = playBrowserTTSPreview({ text: previewText, voice: voiceId });
Expand Down Expand Up @@ -308,7 +315,14 @@ function TeacherVoicePill({
const courseLanguage =
(typeof localStorage !== 'undefined' && localStorage.getItem('generationLanguage')) ||
'zh-CN';
const previewText = courseLanguage === 'en-US' ? 'Welcome to AI Classroom' : '欢迎来到AI课堂';
const previewText =
courseLanguage === 'en-US'
? 'Welcome to AI Classroom'
: courseLanguage === 'ja-JP'
? 'AIクラスルームへようこそ'
: courseLanguage === 'ru-RU'
? 'Добро пожаловать в AI-класс'
: '欢迎来到AI课堂';

if (providerId === 'browser-native-tts') {
const { promise, cancel } = playBrowserTTSPreview({ text: previewText, voice: voiceId });
Expand Down
25 changes: 21 additions & 4 deletions components/generation/generation-toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const MAX_PDF_SIZE_BYTES = MAX_PDF_SIZE_MB * 1024 * 1024;

// ─── Types ───────────────────────────────────────────────────
export interface GenerationToolbarProps {
language: 'zh-CN' | 'en-US';
onLanguageChange: (lang: 'zh-CN' | 'en-US') => void;
language: import('@/lib/types/generation').CourseLanguage;
onLanguageChange: (lang: import('@/lib/types/generation').CourseLanguage) => void;
webSearch: boolean;
onWebSearchChange: (v: boolean) => void;
onSettingsOpen: (section?: SettingsSection) => void;
Expand Down Expand Up @@ -361,11 +361,28 @@ export function GenerationToolbar({
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={() => onLanguageChange(language === 'zh-CN' ? 'en-US' : 'zh-CN')}
onClick={() => {
const langs: import('@/lib/types/generation').CourseLanguage[] = [
'zh-CN',
'en-US',
'ja-JP',
'ru-RU',
];
const idx = langs.indexOf(language);
onLanguageChange(langs[(idx + 1) % langs.length]);
}}
className={pillMuted}
>
<Globe className="size-3.5" />
<span>{language === 'zh-CN' ? '中文' : 'EN'}</span>
<span>
{language === 'zh-CN'
? '中文'
: language === 'en-US'
? 'EN'
: language === 'ja-JP'
? 'JA'
: 'RU'}
</span>
</button>
</TooltipTrigger>
<TooltipContent>{t('toolbar.languageHint')}</TooltipContent>
Expand Down
9 changes: 6 additions & 3 deletions lib/generation/scene-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ async function generateSlideContent(
const lang = outline.language || 'zh-CN';

// Build assigned images description for the prompt
let assignedImagesText = '无可用图片,禁止插入任何 image 元素';
let assignedImagesText = 'No images available. Do NOT insert any image elements.';
let visionImages: Array<{ id: string; src: string }> | undefined;

if (assignedImages && assignedImages.length > 0) {
Expand Down Expand Up @@ -521,7 +521,10 @@ async function generateSlideContent(

if (mediaParts.length > 0) {
const mediaText = mediaParts.join('\n\n');
if (assignedImagesText.includes('禁止插入') || assignedImagesText.includes('No images')) {
if (
assignedImagesText.includes('Do NOT insert') ||
assignedImagesText.includes('No images')
) {
assignedImagesText = mediaText;
} else {
assignedImagesText += `\n\n${mediaText}`;
Expand Down Expand Up @@ -735,7 +738,7 @@ function normalizeQuizAnswer(question: Record<string, unknown>): string[] | unde
async function generateInteractiveContent(
outline: SceneOutline,
aiCall: AICallFn,
language: 'zh-CN' | 'en-US' = 'zh-CN',
language: import('@/lib/types/generation').CourseLanguage = 'zh-CN',
): Promise<GeneratedInteractiveContent | null> {
const config = outline.interactiveConfig!;

Expand Down
1 change: 1 addition & 0 deletions lib/i18n/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ export const supportedLocales = [
{ code: 'zh-CN', label: '简体中文', shortLabel: 'CN' },
{ code: 'en-US', label: 'English', shortLabel: 'EN' },
{ code: 'ja-JP', label: '日本語', shortLabel: 'JA' },
{ code: 'ru-RU', label: 'Русский', shortLabel: 'RU' },
] as const satisfies readonly LocaleEntry[];
Loading
Loading