Skip to content

feat(i18n): Add frontend Chinese localization support#50

Open
vanch007 wants to merge 2 commits intoaudiohacking:mainfrom
vanch007:feature/chinese-localization
Open

feat(i18n): Add frontend Chinese localization support#50
vanch007 wants to merge 2 commits intoaudiohacking:mainfrom
vanch007:feature/chinese-localization

Conversation

@vanch007
Copy link

@vanch007 vanch007 commented Feb 8, 2026

  • Added i18n configuration and Chinese/English translation files (ui/i18n.ts, ui/locales/*.json)

  • Internationalized all core components:

  • App.tsx - Audio playback error messages

  • Sidebar.tsx - Sidebar navigation

  • CreatePanel.tsx - Creation panel

  • LibraryView.tsx - Library view

  • Player.tsx - Player

  • RightSidebar.tsx - Right sidebar

  • SettingsModal.tsx - Settings modal

  • SongList.tsx - Song list

  • SongProfile.tsx - Song details

  • UserProfile.tsx - User profile

  • TrainingPanel.tsx - Model training

  • StemSplittingPanel.tsx - Stem splitting

  • VoiceCloningPanel.tsx - Voice cloning

  • MidiPanel.tsx - MIDI tools

  • SearchPage.tsx - Search page

  • Added translation modules: training/stem_splitting/voice_cloning/midi/search/console/genres/create_extra/vocal_languages

  • Supported automatic browser language detection and localStorage persistence

  • Fixed the issue where backend messages were overriding frontend translations

- 新增 i18n 配置和中英文翻译文件 (ui/i18n.ts, ui/locales/*.json)
- 所有核心组件 i18n 化:
  - App.tsx - 音频播放错误消息
  - Sidebar.tsx - 侧边栏导航
  - CreatePanel.tsx - 创作面板
  - LibraryView.tsx - 曲库视图
  - Player.tsx - 播放器
  - RightSidebar.tsx - 右侧边栏
  - SettingsModal.tsx - 设置弹窗
  - SongList.tsx - 歌曲列表
  - SongProfile.tsx - 歌曲详情
  - UserProfile.tsx - 用户资料
  - TrainingPanel.tsx - 模型训练
  - StemSplittingPanel.tsx - 音轨分离
  - VoiceCloningPanel.tsx - 声音克隆
  - MidiPanel.tsx - MIDI 工具
  - SearchPage.tsx - 搜索页面
- 新增翻译模块: training/stem_splitting/voice_cloning/midi/search/console/genres/create_extra/vocal_languages
- 支持浏览器语言自动检测和 localStorage 持久化
- 修复后端消息覆盖前端翻译的问题
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds frontend internationalization (i18next/react-i18next) with English + Simplified Chinese resources, and wires core UI components to use translation keys with browser-language detection + localStorage persistence.

Changes:

  • Added i18n initialization and injected it at app bootstrap (ui/i18n.ts, ui/index.tsx).
  • Added EN/ZH locale JSON resource bundles (ui/locales/en.json, ui/locales/zh.json).
  • Replaced many hardcoded UI strings across core panels/components with t(...) calls.

Reviewed changes

Copilot reviewed 20 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
ui/package.json Adds i18next/react-i18next + browser language detector dependencies.
ui/package-lock.json Locks new dependency tree for i18n packages.
ui/i18n.ts Initializes i18next with EN/ZH resources + detection/persistence.
ui/index.tsx Imports i18n init module at app startup.
ui/locales/en.json English translation keys for UI text.
ui/locales/zh.json Simplified Chinese translation keys for UI text.
ui/App.tsx Localizes toast/error messages and a few UI labels.
ui/components/* Broad replacement of UI strings with translation keys across panels/views.
.gitignore Ignores checkpoints/ directory.
Files not reviewed (1)
  • ui/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)

ui/components/CreatePanel.tsx:1710

  • Several user-facing strings in this header are still hardcoded (the InfoTooltip text and the helper line “Genre, mood, instruments, vibe”). Since this PR is internationalizing the UI, these should be moved into translation keys (e.g. create.tooltips.* / create_extra.*) so the Custom mode matches the rest of the localized UI.
                    <span className="text-xs font-bold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide">{t('create.inputs.style_of_music')}</span>
                    <InfoTooltip text={(taskType === 'cover' || taskType === 'audio2audio') ? 'Target style for the cover (genre, mood, instruments). Lower Cover Strength gives this more influence over the source.' : 'Genre, mood, instruments, vibe. Same as Simple mode — switching tabs keeps this text.'} />
                  </span>
                  <p className="text-[11px] text-zinc-400 dark:text-zinc-500 mt-0.5">Genre, mood, instruments, vibe</p>
                </div>

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

value={lyrics}
onChange={(e) => setLyrics(e.target.value)}
placeholder={instrumental ? "Instrumental mode - no lyrics needed" : "[Verse]\nYour lyrics here...\n\n[Chorus]\nThe catchy part..."}
placeholder={instrumental ? "Instrumental mode - no lyrics needed" : t('create.inputs.lyrics_placeholder')}
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lyrics textarea placeholder uses a hardcoded English string when instrumental is true ("Instrumental mode - no lyrics needed"). This should be translated (or reused from an existing key) so placeholders are consistent with the selected locale.

Suggested change
placeholder={instrumental ? "Instrumental mode - no lyrics needed" : t('create.inputs.lyrics_placeholder')}
placeholder={t('create.inputs.lyrics_placeholder')}

Copilot uses AI. Check for mistakes.
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';

Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i18n.ts imports JSON translation files, but the current ui/tsconfig.json does not enable resolveJsonModule and there is no declare module '*.json' in the project. This will typically fail TypeScript type-checking with “Cannot find module '*.json'”. Add resolveJsonModule (and usually allowSyntheticDefaultImports) to tsconfig, or add a .d.ts module declaration for JSON imports.

Suggested change
declare module './locales/en.json' {
const value: any;
export default value;
}
declare module './locales/zh.json' {
const value: any;
export default value;
}

Copilot uses AI. Check for mistakes.
Comment on lines +275 to +277
<option value="auto">{t('stem_splitting.device_auto')}</option>
<option value="mps">{t('stem_splitting.device_mps')}</option>
<option value="cpu">{t('stem_splitting.device_cpu')}</option>
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The device option labels are pulled from stem_splitting.* translation keys. This creates cross-feature coupling and makes it harder to adjust wording for voice cloning independently. Prefer adding voice_cloning.device_auto/device_mps/device_cpu keys and referencing those here.

Suggested change
<option value="auto">{t('stem_splitting.device_auto')}</option>
<option value="mps">{t('stem_splitting.device_mps')}</option>
<option value="cpu">{t('stem_splitting.device_cpu')}</option>
<option value="auto">{t('voice_cloning.device_auto')}</option>
<option value="mps">{t('voice_cloning.device_mps')}</option>
<option value="cpu">{t('voice_cloning.device_cpu')}</option>

Copilot uses AI. Check for mistakes.
Comment on lines +1772 to 1776
<span className="text-xs font-bold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide">{t('create.inputs.lyrics')}</span>
<InfoTooltip text={(taskType === 'cover' || taskType === 'audio2audio') ? 'Target lyrics for the cover. Uncheck Instrumental to use them. Lower Cover Strength gives your lyrics more influence.' : 'Lyric content and structure. Use [Verse], [Chorus], etc. Leave empty or use Instrumental for no vocals.'} />
</span>
<p className="text-[11px] text-zinc-400 dark:text-zinc-500 mt-0.5">Leave empty for instrumental or switch to Instrumental below</p>
<p className="text-[11px] text-zinc-400 dark:text-zinc-400 mt-0.5">Leave empty for instrumental or switch to Instrumental below</p>
</div>
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lyrics section still contains hardcoded English strings (the InfoTooltip text and the hint “Leave empty for instrumental or switch to Instrumental below”). To avoid mixed-language UI after switching locales, move these to translation keys (there is already create_extra.lyrics_hint in the locale files).

Copilot uses AI. Check for mistakes.
@@ -1,9 +1,10 @@
import React, { useState, useEffect } from 'react';
import { X, User as UserIcon, Palette, Info, Edit3, ExternalLink, Github, FolderOpen, HardDrive, ZoomIn, Box } from 'lucide-react';
import { X, User as UserIcon, Palette, Info, Edit3, ExternalLink, Github, FolderOpen, HardDrive, ZoomIn, Box, Globe } from 'lucide-react';
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import FolderOpen.

Suggested change
import { X, User as UserIcon, Palette, Info, Edit3, ExternalLink, Github, FolderOpen, HardDrive, ZoomIn, Box, Globe } from 'lucide-react';
import { X, User as UserIcon, Palette, Info, Edit3, ExternalLink, Github, HardDrive, ZoomIn, Box, Globe } from 'lucide-react';

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants