feat(i18n): Add Internationalization Support for UI and LLM Output (#1058)

This commit is contained in:
pomelo
2025-11-21 15:44:37 +08:00
committed by GitHub
parent 640f30655d
commit 48b77541c3
98 changed files with 4740 additions and 636 deletions

View File

@@ -13,6 +13,7 @@ import {
} from '@qwen-code/qwen-code-core';
import { useTerminalSize } from '../hooks/useTerminalSize.js';
import { isNarrowWidth } from '../utils/isNarrowWidth.js';
import { t } from '../../i18n/index.js';
interface ContextSummaryDisplayProps {
geminiMdFileCount: number;
@@ -50,9 +51,11 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
if (openFileCount === 0) {
return '';
}
return `${openFileCount} open file${
openFileCount > 1 ? 's' : ''
} (ctrl+g to view)`;
const fileText =
openFileCount === 1
? t('{{count}} open file', { count: String(openFileCount) })
: t('{{count}} open files', { count: String(openFileCount) });
return `${fileText} ${t('(ctrl+g to view)')}`;
})();
const geminiMdText = (() => {
@@ -61,9 +64,15 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
}
const allNamesTheSame = new Set(contextFileNames).size < 2;
const name = allNamesTheSame ? contextFileNames[0] : 'context';
return `${geminiMdFileCount} ${name} file${
geminiMdFileCount > 1 ? 's' : ''
}`;
return geminiMdFileCount === 1
? t('{{count}} {{name}} file', {
count: String(geminiMdFileCount),
name,
})
: t('{{count}} {{name}} files', {
count: String(geminiMdFileCount),
name,
});
})();
const mcpText = (() => {
@@ -73,15 +82,27 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
const parts = [];
if (mcpServerCount > 0) {
parts.push(
`${mcpServerCount} MCP server${mcpServerCount > 1 ? 's' : ''}`,
);
const serverText =
mcpServerCount === 1
? t('{{count}} MCP server', { count: String(mcpServerCount) })
: t('{{count}} MCP servers', { count: String(mcpServerCount) });
parts.push(serverText);
}
if (blockedMcpServerCount > 0) {
let blockedText = `${blockedMcpServerCount} Blocked`;
let blockedText = t('{{count}} Blocked', {
count: String(blockedMcpServerCount),
});
if (mcpServerCount === 0) {
blockedText += ` MCP server${blockedMcpServerCount > 1 ? 's' : ''}`;
const serverText =
blockedMcpServerCount === 1
? t('{{count}} MCP server', {
count: String(blockedMcpServerCount),
})
: t('{{count}} MCP servers', {
count: String(blockedMcpServerCount),
});
blockedText += ` ${serverText}`;
}
parts.push(blockedText);
}
@@ -89,9 +110,9 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
// Add ctrl+t hint when MCP servers are available
if (mcpServers && Object.keys(mcpServers).length > 0) {
if (showToolDescriptions) {
text += ' (ctrl+t to toggle)';
text += ` ${t('(ctrl+t to toggle)')}`;
} else {
text += ' (ctrl+t to view)';
text += ` ${t('(ctrl+t to view)')}`;
}
}
return text;
@@ -102,7 +123,7 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
if (isNarrow) {
return (
<Box flexDirection="column">
<Text color={theme.text.secondary}>Using:</Text>
<Text color={theme.text.secondary}>{t('Using:')}</Text>
{summaryParts.map((part, index) => (
<Text key={index} color={theme.text.secondary}>
{' '}- {part}
@@ -115,7 +136,7 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
return (
<Box>
<Text color={theme.text.secondary}>
Using: {summaryParts.join(' | ')}
{t('Using:')} {summaryParts.join(' | ')}
</Text>
</Box>
);