Skip to content

Commit 5df2a4d

Browse files
committed
Function: Add support of i18n
1 parent aa0bdd8 commit 5df2a4d

File tree

15 files changed

+507
-65
lines changed

15 files changed

+507
-65
lines changed

package-lock.json

Lines changed: 94 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,15 @@
2626
"axios": "^1.8.4",
2727
"dotenv": "^16.4.7",
2828
"electron-builder": "26.0.12",
29+
"i18next": "^24.2.3",
30+
"i18next-browser-languagedetector": "^8.0.4",
2931
"katex": "^0.16.21",
3032
"lucide-react": "^0.344.0",
3133
"prism-themes": "^1.9.0",
3234
"prismjs": "^1.30.0",
3335
"react": "^18.3.1",
3436
"react-dom": "^18.3.1",
37+
"react-i18next": "^15.4.1",
3538
"react-markdown": "^10.1.0",
3639
"rehype-katex": "^7.0.1",
3740
"rehype-prism-plus": "^2.0.0",

src/components/chat/ChatHistoryList.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Conversation, ConversationFolder } from '../../types/chat';
33
import { MessageSquare, MoreVertical, Edit, Trash2, ChevronLeft, ChevronRight, AlertTriangle, FolderPlus, Folder, ChevronDown, PlusCircle } from 'lucide-react';
44
import ContextMenu, { ContextMenuItem } from '../ui/ContextMenu';
55
import ConfirmDialog from '../ui/ConfirmDialog';
6+
import { useTranslation } from '../../hooks/useTranslation';
67

78
interface ChatHistoryListProps {
89
conversations: Conversation[];
@@ -36,6 +37,7 @@ export const ChatHistoryList: React.FC<ChatHistoryListProps> = ({
3637
onDeleteFolder,
3738
onMoveConversation,
3839
}) => {
40+
const { t } = useTranslation();
3941
const [openMenuId, setOpenMenuId] = useState<string | null>(null);
4042
const [editingId, setEditingId] = useState<string | null>(null);
4143
const [editingType, setEditingType] = useState<'conversation' | 'folder'>('conversation');
@@ -164,12 +166,12 @@ export const ChatHistoryList: React.FC<ChatHistoryListProps> = ({
164166
// Show confirmation dialog
165167
setConfirmDialog({
166168
isOpen: true,
167-
title: `Delete ${type === 'conversation' ? 'Conversation' : 'Folder'}`,
168-
message: `Are you sure you want to delete this ${type}? ${type === 'folder' ? 'All conversations will be moved to the root.' : 'This action cannot be undone.'}`,
169+
title: `${type === 'conversation' ? t('chat.deleteChat') : t('chat.deleteFolder')}`,
170+
message: `${type === 'conversation' ? t('chat.deleteChat_confirm_message') : t('chat.deleteFolder_confirm_message')}`,
169171
itemId: id,
170172
itemType: type,
171-
confirmText: 'Delete',
172-
cancelText: 'Cancel',
173+
confirmText: `${type === 'conversation' ? t('chat.deleteChat_delete') : t('chat.deleteFolder_delete')}`,
174+
cancelText: `${type === 'conversation' ? t('chat.deleteChat_cancel') : t('chat.deleteFolder_cancel')}`,
173175
confirmColor: 'red'
174176
});
175177
};
@@ -333,14 +335,14 @@ export const ChatHistoryList: React.FC<ChatHistoryListProps> = ({
333335
{
334336
id: 'rename',
335337
icon: Edit,
336-
label: 'Rename',
338+
label: t('chat.renameChat'),
337339
onClick: (e) => handleRenameClick(e, conversation, 'conversation'),
338340
color: 'text-gray-700'
339341
},
340342
{
341343
id: 'delete',
342344
icon: Trash2,
343-
label: 'Delete',
345+
label: t('chat.deleteChat'),
344346
onClick: (e) => handleDeleteClick(e, conversation.conversationId, 'conversation'),
345347
color: 'text-red-600'
346348
}
@@ -351,21 +353,21 @@ export const ChatHistoryList: React.FC<ChatHistoryListProps> = ({
351353
{
352354
id: 'new chat',
353355
icon: PlusCircle,
354-
label: 'New Chat',
356+
label: t('chat.newChat'),
355357
onClick: (e) => handleNewChatClick(e, folder.folderId),
356358
color: 'text-gray-700'
357359
},
358360
{
359361
id: 'rename',
360362
icon: Edit,
361-
label: 'Rename',
363+
label: t('chat.renameFolder'),
362364
onClick: (e) => handleRenameClick(e, folder, 'folder'),
363365
color: 'text-gray-700'
364366
},
365367
{
366368
id: 'delete',
367369
icon: Trash2,
368-
label: 'Delete',
370+
label: t('chat.deleteFolder'),
369371
onClick: (e) => handleDeleteClick(e, folder.folderId, 'folder'),
370372
color: 'text-red-600'
371373
}

src/components/chat/ChatMessageArea.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { SETTINGS_CHANGE_EVENT, SettingsService } from '../../services/settings-
99
import { ChatService } from '../../services/chat-service';
1010
import { AIServiceCapability } from '../../types/capabilities';
1111
import ProviderIcon from '../ui/ProviderIcon';
12+
import { useTranslation } from '../../hooks/useTranslation';
1213

1314
interface ChatMessageAreaProps {
1415
activeConversation: Conversation | null;
@@ -35,6 +36,7 @@ export const ChatMessageArea: React.FC<ChatMessageAreaProps> = ({
3536
selectedProvider,
3637
selectedModel,
3738
}) => {
39+
const { t } = useTranslation();
3840
const [inputValue, setInput] = useState('');
3941
const inputRef = useRef<HTMLTextAreaElement>(null);
4042
const messagesEndRef = useRef<HTMLDivElement>(null);
@@ -289,21 +291,21 @@ export const ChatMessageArea: React.FC<ChatMessageAreaProps> = ({
289291
{
290292
id: 'edit',
291293
icon: Pencil,
292-
label: 'Edit',
294+
label: t('chat.edit'),
293295
onClick: () => handleEditMessage(message.messageId, MessageHelper.MessageContentToText(message.content)),
294296
},
295297
{
296298
id: 'copy',
297299
icon: Copy,
298-
label: 'Copy',
300+
label: t('chat.copy'),
299301
onClick: () => handleCopyMessage(MessageHelper.MessageContentToText(message.content)),
300302
}
301303
]
302304
: [
303305
{
304306
id: 'copy',
305307
icon: Copy,
306-
label: 'Copy',
308+
label: t('chat.copy'),
307309
onClick: () => handleCopyMessage(MessageHelper.MessageContentToText(message.content)),
308310
},
309311
// {
@@ -315,7 +317,7 @@ export const ChatMessageArea: React.FC<ChatMessageAreaProps> = ({
315317
{
316318
id: 'regenerate',
317319
icon: RefreshCw,
318-
label: 'Regenerate',
320+
label: t('chat.regenerate'),
319321
onClick: () => handleRegenerateResponse(message.messageId),
320322
}
321323
];
@@ -455,7 +457,7 @@ export const ChatMessageArea: React.FC<ChatMessageAreaProps> = ({
455457
handleSubmit(e);
456458
}
457459
}}
458-
placeholder="Type your message..."
460+
placeholder={t('chat.typeMessage')}
459461
className="flex-1 w-[100%] px-2 pt-1 pb-2 resize-none focus:outline-none"
460462
disabled={isLoading}
461463
inputMode='text'
@@ -496,16 +498,16 @@ export const ChatMessageArea: React.FC<ChatMessageAreaProps> = ({
496498
}
497499

498500
<span className={`flex-1 hidden text-xs text-center pt-4 text-gray-300 md:block truncate ${isWebSearchPreviewEnabled ? 'pr-6 lg:pr-12' : ''}`}>
499-
{isWebSearchPreviewEnabled ? 'Press Shift+Enter to change lines' : ''}
501+
{isWebSearchPreviewEnabled ? t('chat.pressShiftEnterToChangeLines') : ''}
500502
</span>
501503

502504
{isCurrentlyStreaming || hasStreamingMessage ? (
503505
<button
504506
type="button"
505507
onClick={handleStopStreaming}
506508
className="flex items-center justify-center w-10 h-10 transition-all duration-200 rounded-full conversation-stop-button focus:outline-none"
507-
aria-label="Stop response"
508-
title="Stop response"
509+
aria-label={t('chat.stopResponse')}
510+
title={t('chat.stopResponse')}
509511
>
510512
<Square size={20} fill="currentColor" />
511513
</button>
@@ -514,8 +516,8 @@ export const ChatMessageArea: React.FC<ChatMessageAreaProps> = ({
514516
type="submit"
515517
disabled={isLoading || !inputValue.trim()}
516518
className="flex items-center justify-center w-10 h-10 transition-all duration-200 rounded-full conversation-send-button focus:outline-none disabled:cursor-not-allowed"
517-
aria-label={isLoading || !inputValue.trim() ? 'Cannot send message' : 'Send message'}
518-
title={isLoading || !inputValue.trim() ? 'Cannot send message' : 'Send message'}
519+
aria-label={isLoading || !inputValue.trim() ? t('chat.cannotSendMessage') : t('chat.sendMessage')}
520+
title={isLoading || !inputValue.trim() ? t('chat.cannotSendMessage') : t('chat.sendMessage')}
519521
>
520522
<Send className="translate-x-[0px] translate-y-[1px]" size={20} />
521523
</button>

0 commit comments

Comments
 (0)