Skip to content

Commit feb8a70

Browse files
authored
Merge pull request #11 from weiruchenai1/experimental
Experimental
2 parents 8501bfd + 1b801cd commit feb8a70

File tree

12 files changed

+459
-374
lines changed

12 files changed

+459
-374
lines changed

src/components/features/PaidDetectionControl/index.jsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const PaidDetectionControl = () => {
3737
<div className="space-y-lg">
3838
<div className="space-y-sm">
3939
<label className="text-sm font-medium text-primary">
40-
Gemini付费检测
40+
{t('paidDetection')}
4141
</label>
4242
<div className="space-y-sm">
4343
<div className="flex items-center gap-sm">
@@ -55,25 +55,25 @@ const PaidDetectionControl = () => {
5555
</span>
5656
</div>
5757
<p className="text-xs text-tertiary">
58-
启用后将使用Cache API检测Gemini密钥的付费功能,会消耗额外配额
58+
{t('paidDetectionSettings.description')}
5959
</p>
6060
</div>
6161
</div>
6262

6363
{/* 弹窗设置重置 */}
6464
<div className="space-y-sm">
6565
<label className="text-sm font-medium text-primary">
66-
弹窗提示设置
66+
{t('paidDetectionSettings.popupSettings')}
6767
</label>
6868
<div className="space-y-sm">
6969
<button
7070
className="btn-base btn-sm btn-ghost"
7171
onClick={handleResetPrompt}
7272
>
73-
重置弹窗提示
73+
{t('paidDetectionSettings.resetPopup')}
7474
</button>
7575
<p className="text-xs text-tertiary">
76-
重置后,下次选择Gemini时将重新显示付费检测询问弹窗
76+
{t('paidDetectionSettings.resetDescription')}
7777
</p>
7878
</div>
7979
</div>
@@ -82,11 +82,11 @@ const PaidDetectionControl = () => {
8282
{state.apiType === 'gemini' && (
8383
<div className="card-base card-padding-sm bg-secondary">
8484
<div className="flex items-center justify-between mb-xs">
85-
<span className="text-xs text-tertiary">当前API类型:</span>
85+
<span className="text-xs text-tertiary">{t('paidDetectionSettings.currentApiType')}:</span>
8686
<span className="text-xs font-medium text-primary">Gemini</span>
8787
</div>
8888
<div className="flex items-center justify-between mb-xs">
89-
<span className="text-xs text-tertiary">付费检测状态:</span>
89+
<span className="text-xs text-tertiary">{t('paidDetectionSettings.detectionStatus')}:</span>
9090
{state.enablePaidDetection ? (
9191
<span className="text-xs text-success flex items-center gap-xs">
9292
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
@@ -108,7 +108,7 @@ const PaidDetectionControl = () => {
108108
</div>
109109
{state.enablePaidDetection && (
110110
<div className="flex items-center justify-between">
111-
<span className="text-xs text-tertiary">固定模型:</span>
111+
<span className="text-xs text-tertiary">{t('paidDetectionSettings.fixedModel')}:</span>
112112
<span className="text-xs font-medium text-primary">gemini-2.5-flash</span>
113113
</div>
114114
)}
@@ -119,10 +119,10 @@ const PaidDetectionControl = () => {
119119
isOpen={showResetModal}
120120
onClose={() => setShowResetModal(false)}
121121
onConfirm={confirmResetPrompt}
122-
title="重置弹窗提示设置"
123-
message="确定要重置弹窗提示设置吗?重置后,下次选择Gemini时将重新显示付费检测询问弹窗。"
124-
confirmText="确定"
125-
cancelText="取消"
122+
title={t('paidDetectionSettings.resetModalTitle')}
123+
message={t('paidDetectionSettings.resetModalMessage')}
124+
confirmText={t('paidDetectionSettings.confirm')}
125+
cancelText={t('paidDetectionSettings.cancel')}
126126
/>
127127
</div>
128128
);

src/components/features/PaidDetectionPrompt/index.jsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React, { useState } from 'react';
22
import { useUserConfig } from '../../../hooks/useLocalStorage';
3+
import { useLanguage } from '../../../hooks/useLanguage';
34
import styles from './PaidDetectionPrompt.module.css';
45

56
const PaidDetectionPrompt = ({ isOpen, onClose, onConfirm }) => {
67
const { setEnablePaidDetection } = useUserConfig();
8+
const { t } = useLanguage();
79
const [dontShowAgain, setDontShowAgain] = useState(false);
810

911
const handleConfirm = (enablePaidDetection) => {
@@ -26,7 +28,7 @@ const PaidDetectionPrompt = ({ isOpen, onClose, onConfirm }) => {
2628
<div className={styles.overlay} onClick={(e) => e.target === e.currentTarget && onClose()}>
2729
<div className={styles.modal}>
2830
<div className={styles.header}>
29-
<h3>测试Gemini付费Key</h3>
31+
<h3>{t('paidDetectionDialog.title')}</h3>
3032
<button className={styles.closeBtn} onClick={onClose}>×</button>
3133
</div>
3234

@@ -41,10 +43,10 @@ const PaidDetectionPrompt = ({ isOpen, onClose, onConfirm }) => {
4143

4244
<div className={styles.message}>
4345
<p className={styles.description}>
44-
如果要测试Gemini的付费Key,需要消耗一定的Token来检测Key是否有访问付费功能的能力。
46+
{t('paidDetectionDialog.description')}
4547
</p>
4648
<p className={styles.warning}>
47-
⚠️ 付费检测会使用Cache API,可能会消耗额外的API配额。
49+
{t('paidDetectionDialog.warning')}
4850
</p>
4951
</div>
5052

@@ -56,7 +58,7 @@ const PaidDetectionPrompt = ({ isOpen, onClose, onConfirm }) => {
5658
onChange={(e) => setDontShowAgain(e.target.checked)}
5759
className={styles.checkboxInput}
5860
/>
59-
<span className={styles.checkboxText}>不再提示此消息(可在高级设置中更改)</span>
61+
<span className={styles.checkboxText}>{t('paidDetectionDialog.dontShowAgain')}</span>
6062
</label>
6163
</div>
6264
</div>
@@ -66,13 +68,13 @@ const PaidDetectionPrompt = ({ isOpen, onClose, onConfirm }) => {
6668
className={styles.cancelBtn}
6769
onClick={() => handleConfirm(false)}
6870
>
69-
否,不检测付费功能
71+
{t('paidDetectionDialog.cancelButton')}
7072
</button>
7173
<button
7274
className={styles.confirmBtn}
7375
onClick={() => handleConfirm(true)}
7476
>
75-
是,启用付费检测
77+
{t('paidDetectionDialog.confirmButton')}
7678
</button>
7779
</div>
7880
</div>

src/components/features/Results/VirtualizedList.jsx

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const KeyItem = ({ index, style, data }) => {
1010
const keyData = data[index];
1111

1212
if (!keyData) {
13-
return <div style={style} className="key-item loading-item">Loading...</div>;
13+
return <div style={style} className="key-item loading-item">{t('ui.loading')}</div>;
1414
}
1515

1616
const getStatusClass = (status) => {
@@ -40,37 +40,30 @@ const KeyItem = ({ index, style, data }) => {
4040
const getLocalizedError = (error) => {
4141
if (!error) return '';
4242

43-
const errorMappings = {
44-
'Rate Limited': t('rateLimited') || '速率限制',
45-
'认证失败': t('authFailed') || '认证失败',
46-
'权限不足': t('permissionDenied') || '权限不足',
47-
'网络连接失败': t('networkFailed') || '网络连接失败'
48-
};
49-
50-
for (const [key, value] of Object.entries(errorMappings)) {
51-
if (error.includes(key)) {
52-
return error.replace(key, value);
53-
}
43+
// 如果错误是翻译键,直接使用翻译
44+
if (error.startsWith('errorMessages.')) {
45+
return t(error) || error;
5446
}
5547

48+
// 直接翻译显示
5649
return error;
5750
};
5851

5952
// 修复显示逻辑
6053
const getKeyStatusInfo = () => {
6154
// 如果是有效密钥且没有启用付费检测
6255
if (keyData.status === 'valid' && !state.enablePaidDetection) {
63-
return `有效密钥 (200)`;
56+
return `${t('keyStatus.validKey')} (200)`;
6457
}
6558

6659
// 如果是有效密钥且启用了付费检测但检测为免费密钥
6760
if (keyData.status === 'valid' && state.enablePaidDetection && keyData.isPaid === false) {
68-
return `免费密钥 (${keyData.cacheApiStatus || 429})`;
61+
return `${t('keyStatus.freeKey')} (${keyData.cacheApiStatus || 429})`;
6962
}
7063

7164
// 如果是付费密钥
7265
if (keyData.status === 'paid' && keyData.isPaid === true) {
73-
return `付费密钥 (${keyData.cacheApiStatus || 200})`;
66+
return `${t('keyStatus.paidKey')} (${keyData.cacheApiStatus || 200})`;
7467
}
7568

7669
// 其他情况返回null,不显示额外信息
@@ -83,7 +76,7 @@ const KeyItem = ({ index, style, data }) => {
8376
<div className="key-content">
8477
<div className="key-text">{keyData.key}</div>
8578
{keyData.model && (
86-
<div className="key-model">Model: {keyData.model}</div>
79+
<div className="key-model">{t('keyStatus.model')}: {keyData.model}</div>
8780
)}
8881
{keyData.error && (
8982
<div className={`key-error ${keyData.status === 'rate-limited' ? 'rate-limited-error' : ''}`}>
@@ -92,7 +85,7 @@ const KeyItem = ({ index, style, data }) => {
9285
)}
9386
{keyData.retryCount > 0 && (
9487
<div className="key-retry">
95-
重试: {keyData.retryCount}
88+
{t('ui.retry')}: {keyData.retryCount}
9689
</div>
9790
)}
9891
{/* 修复后的状态信息显示 */}

src/components/layout/NavBar/index.jsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ const NavBar = ({ onSidebarToggle, isSidebarCollapsed }) => {
4949
<button
5050
className={styles.sidebarToggle}
5151
onClick={handleSidebarToggle}
52-
aria-label={isSidebarCollapsed ? '展开侧边栏' : '折叠侧边栏'}
52+
aria-label={isSidebarCollapsed ? t('ui.expandSidebar') : t('ui.collapseSidebar')}
53+
title={isSidebarCollapsed ? t('ui.expandSidebar') : t('ui.collapseSidebar')}
5354
>
5455
<svg
5556
xmlns="http://www.w3.org/2000/svg"
@@ -109,7 +110,7 @@ const NavBar = ({ onSidebarToggle, isSidebarCollapsed }) => {
109110
<path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" />
110111
<path d="M2 12h20" />
111112
</svg>
112-
<span>{language === 'zh' ? '简体中文' : 'English'}</span>
113+
<span>{language === 'zh' ? t('ui.chineseName') : t('ui.englishName')}</span>
113114
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={styles.chevron}>
114115
<path d="m6 9 6 6 6-6" />
115116
</svg>
@@ -123,7 +124,7 @@ const NavBar = ({ onSidebarToggle, isSidebarCollapsed }) => {
123124
setShowLanguageMenu(false);
124125
}}
125126
>
126-
<span>English</span>
127+
<span>{t('ui.englishName')}</span>
127128
{language === 'en' && (
128129
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" className={styles.checkIcon}>
129130
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
@@ -137,7 +138,7 @@ const NavBar = ({ onSidebarToggle, isSidebarCollapsed }) => {
137138
setShowLanguageMenu(false);
138139
}}
139140
>
140-
<span>简体中文</span>
141+
<span>{t('ui.chineseName')}</span>
141142
{language === 'zh' && (
142143
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" className={styles.checkIcon}>
143144
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />

src/components/layout/ThemeToggle/index.jsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ const ThemeToggle = () => {
3434
target="_blank"
3535
rel="noopener noreferrer"
3636
className={styles.githubBtn}
37-
title="View on GitHub"
3837
>
3938
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
4039
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
@@ -51,7 +50,7 @@ const ThemeToggle = () => {
5150
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
5251
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.94-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/>
5352
</svg>
54-
<span>{language === 'zh' ? '简体中文' : 'English'}</span>
53+
<span>{language === 'zh' ? t('ui.chineseName') : t('ui.englishName')}</span>
5554
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" className={styles.chevron}>
5655
<path d="M7 10l5 5 5-5z"/>
5756
</svg>
@@ -72,7 +71,7 @@ const ThemeToggle = () => {
7271
) : (
7372
<div style={{ width: 16, height: 16 }} />
7473
)}
75-
English
74+
{t('ui.englishName')}
7675
</button>
7776
<button
7877
className={`${styles.dropdownItem} ${language === 'zh' ? styles.active : ''}`}
@@ -88,7 +87,7 @@ const ThemeToggle = () => {
8887
) : (
8988
<div style={{ width: 16, height: 16 }} />
9089
)}
91-
简体中文
90+
{t('ui.chineseName')}
9291
</button>
9392
</div>
9493
)}

0 commit comments

Comments
 (0)