Merge pull request #107 from H-Chris233/main

chore(i18n): 补齐剩余可见文案翻译
This commit is contained in:
Chris233 authored and GitHub committed 2026-05-01 00:15:57 +08:00
commit d8d341f781
6 files changed
+38 -20

No files matched your search

+2 -1
View File
@@ -119,11 +119,12 @@ interface CircleButtonProps {
}
function CircleButton({ variant, enabled, onClick }: CircleButtonProps) {
const { t } = useTranslation();
const isCancel = variant === 'cancel';
return (
<button
onClick={enabled ? onClick : undefined}
aria-label={isCancel ? 'cancel' : 'confirm'}
aria-label={isCancel ? t('common.cancel') : t('settings.shortcuts.confirm')}
disabled={!enabled}
style={{
width: 28,
+8
View File
@@ -24,6 +24,8 @@ export const en: typeof zhCN = {
copied: 'Copied',
operationFailed: 'Operation failed',
add: 'Add',
durationSeconds: '{{value}}s',
durationMinutes: '{{value}}m',
},
capsule: {
thinking: 'Thinking…',
@@ -193,6 +195,12 @@ export const en: typeof zhCN = {
},
fillDefault: 'Fill default value',
readFailed: 'Read failed',
apiKeyLabel: 'API Key',
baseUrlLabel: 'Base URL',
modelLabel: 'Model',
appKeyLabel: 'App Key',
accessKeyLabel: 'Access Key',
resourceIdLabel: 'Resource ID',
},
shortcuts: {
title: 'Shortcut reference',
+8
View File
@@ -22,6 +22,8 @@ export const zhCN = {
copied: '已复制',
operationFailed: '操作失败',
add: '添加',
durationSeconds: '{{value}} 秒',
durationMinutes: '{{value}} 分钟',
},
capsule: {
thinking: '正在思考中',
@@ -191,6 +193,12 @@ export const zhCN = {
},
fillDefault: '填入默认值',
readFailed: '读取失败',
apiKeyLabel: 'API 密钥',
baseUrlLabel: '接口地址',
modelLabel: '模型',
appKeyLabel: 'App Key(应用密钥)',
accessKeyLabel: 'Access Key(访问密钥)',
resourceIdLabel: '资源 ID',
},
shortcuts: {
title: '快捷键速查',
+5 -5
View File
@@ -151,7 +151,7 @@ export function History() {
{formatTime(s.createdAt)}
</span>
<span style={{ fontSize: 10, color: 'var(--ol-ink-4)', fontFamily: 'var(--ol-font-mono)' }}>
{formatDuration(s.durationMs)}
{formatDuration(s.durationMs, t)}
</span>
</div>
<div style={{ fontSize: 12, color: 'var(--ol-ink-2)', lineHeight: 1.45, display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>
@@ -170,7 +170,7 @@ export function History() {
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
<span style={{ fontSize: 13, fontFamily: 'var(--ol-font-mono)', color: 'var(--ol-ink-3)' }}>{formatTime(item.createdAt)}</span>
<Pill size="sm" tone="default">{MODE_LABEL[item.mode]}</Pill>
<span style={{ fontSize: 11, color: 'var(--ol-ink-4)' }}>{formatDuration(item.durationMs)}</span>
<span style={{ fontSize: 11, color: 'var(--ol-ink-4)' }}>{formatDuration(item.durationMs, t)}</span>
</div>
<div style={{ display: 'flex', gap: 6 }}>
<Btn icon="copy" variant="ghost" size="sm" onClick={onCopy}>{t('common.copy')}</Btn>
@@ -227,9 +227,9 @@ function formatTime(iso: string): string {
return `${d.getMonth() + 1}/${d.getDate()} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
}
function formatDuration(ms: number | null): string {
function formatDuration(ms: number | null, t: ReturnType<typeof useTranslation>['t']): string {
if (ms == null || ms <= 0) return '—';
const sec = ms / 1000;
if (sec < 60) return `${sec.toFixed(1)}s`;
return `${(sec / 60).toFixed(1)}m`;
if (sec < 60) return t('common.durationSeconds', { value: sec.toFixed(1) });
return t('common.durationMinutes', { value: (sec / 60).toFixed(1) });
}
+6 -5
View File
@@ -112,8 +112,8 @@ export function Overview({ onOpenHistory }: OverviewProps) {
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 18 }}>
<Metric icon="hash" label={t('overview.metricChars')} value={metrics.charsToday.toLocaleString()} trend={t('overview.metricSegments', { count: metrics.segmentsToday })} />
<Metric icon="mic" label={t('overview.metricDuration')} value={formatDuration(metrics.totalDurationMs)} trend="" />
<Metric icon="clock" label={t('overview.metricAvg')} value={formatDuration(metrics.avgLatencyMs)} trend={metrics.segmentsToday > 0 ? t('overview.metricAvgTrend') : t('overview.metricNoData')} />
<Metric icon="mic" label={t('overview.metricDuration')} value={formatDuration(metrics.totalDurationMs, t)} trend="" />
<Metric icon="clock" label={t('overview.metricAvg')} value={formatDuration(metrics.avgLatencyMs, t)} trend={metrics.segmentsToday > 0 ? t('overview.metricAvgTrend') : t('overview.metricNoData')} />
<Metric icon="bolt" label={t('overview.metricTotal')} value={String(history.length)} trend={t('overview.metricTotalTrend')} accent />
</div>
@@ -241,6 +241,7 @@ function WeekChart({ data }: { data: number[] }) {
}
function RecentRow({ session, modeLabel }: { session: DictationSession; modeLabel: Record<PolishMode, string> }) {
const { t } = useTranslation();
return (
<div style={{ padding: '12px 18px', borderBottom: '0.5px solid var(--ol-line-soft)', display: 'flex', gap: 12, alignItems: 'flex-start' }}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: 4, minWidth: 60 }}>
@@ -253,7 +254,7 @@ function RecentRow({ session, modeLabel }: { session: DictationSession; modeLabe
{session.finalText.split('\n')[0]}
</div>
<span style={{ fontSize: 10.5, color: 'var(--ol-ink-4)', fontFamily: 'var(--ol-font-mono)' }}>
{formatDuration(session.durationMs ?? 0)}
{formatDuration(session.durationMs ?? 0, t)}
</span>
</div>
);
@@ -269,10 +270,10 @@ function formatTime(iso: string): string {
return `${d.getMonth() + 1}/${d.getDate()}`;
}
function formatDuration(ms: number): string {
function formatDuration(ms: number, t: ReturnType<typeof useTranslation>['t']): string {
if (ms <= 0) return '—';
const sec = ms / 1000;
if (sec < 60) return `${sec.toFixed(1)}s`;
if (sec < 60) return t('common.durationSeconds', { value: sec.toFixed(1) });
return `${Math.floor(sec / 60)}:${String(Math.floor(sec % 60)).padStart(2, '0')}`;
}
+9 -9
View File
@@ -295,10 +295,10 @@ function ProvidersSection() {
))}
</select>
</SettingRow>
<CredentialField key={`${llmProvider}:api_key`} label="API Key" account="ark.api_key" mono mask />
<CredentialField key={`${llmProvider}:endpoint`} label="Base URL" account="ark.endpoint"
<CredentialField key={`${llmProvider}:api_key`} label={t('settings.providers.apiKeyLabel')} account="ark.api_key" mono mask />
<CredentialField key={`${llmProvider}:endpoint`} label={t('settings.providers.baseUrlLabel')} account="ark.endpoint"
placeholder={preset.baseUrl || 'https://your-endpoint/v1'} />
<CredentialField key={`${llmProvider}:model`} label="Model" account="ark.model_id"
<CredentialField key={`${llmProvider}:model`} label={t('settings.providers.modelLabel')} account="ark.model_id"
placeholder={preset.modelPlaceholder || 'model-name'} mono />
</Card>
@@ -320,17 +320,17 @@ function ProvidersSection() {
</SettingRow>
{asrProvider === 'volcengine' ? (
<>
<CredentialField key={`${asrProvider}:app_key`} label="App Key" account="volcengine.app_key" mono mask />
<CredentialField key={`${asrProvider}:access_key`} label="Access Key" account="volcengine.access_key" mono mask />
<CredentialField key={`${asrProvider}:resource_id`} label="Resource ID" account="volcengine.resource_id" mono
<CredentialField key={`${asrProvider}:app_key`} label={t('settings.providers.appKeyLabel')} account="volcengine.app_key" mono mask />
<CredentialField key={`${asrProvider}:access_key`} label={t('settings.providers.accessKeyLabel')} account="volcengine.access_key" mono mask />
<CredentialField key={`${asrProvider}:resource_id`} label={t('settings.providers.resourceIdLabel')} account="volcengine.resource_id" mono
placeholder={ASR_DEFAULT_RESOURCE_ID} defaultValue={ASR_DEFAULT_RESOURCE_ID} />
</>
) : (
<>
<CredentialField key={`${asrProvider}:api_key`} label="API Key" account="asr.api_key" mono mask />
<CredentialField key={`${asrProvider}:endpoint`} label="Base URL" account="asr.endpoint"
<CredentialField key={`${asrProvider}:api_key`} label={t('settings.providers.apiKeyLabel')} account="asr.api_key" mono mask />
<CredentialField key={`${asrProvider}:endpoint`} label={t('settings.providers.baseUrlLabel')} account="asr.endpoint"
placeholder="https://api.openai.com/v1" defaultValue="https://api.openai.com/v1" />
<CredentialField key={`${asrProvider}:model`} label="Model" account="asr.model"
<CredentialField key={`${asrProvider}:model`} label={t('settings.providers.modelLabel')} account="asr.model"
placeholder="whisper-1" />
</>
)}