optimizing i18n and language setting

This commit is contained in:
wj-xiao
2024-08-26 14:15:35 +08:00
parent b017338f05
commit 9c336dbda4
10 changed files with 60 additions and 39 deletions

View File

@@ -11,6 +11,7 @@ importOrder:
- ^types$
- ^@/assets(.*)$
- ^@/api/(.*)$
- ^@/i18n/(.*)$
- ^@/types$
- ^@/lib/(.*)$
- ^@/jotai/(.*)$

4
web/src/i18n/README.md Normal file
View File

@@ -0,0 +1,4 @@
# How to add a language
1. Add a language file in i18n/locales folder (for example: en.ts).
2. Add language key and name in i18n/languages.ts (for example: { key: 'en', name: 'English' }).

View File

@@ -1,14 +1,23 @@
import i18n from 'i18next';
import type { Resource } from 'i18next';
import { initReactI18next } from 'react-i18next';
import { getLanguage } from '@/lib/localstorage.ts';
import { en } from './en';
import { fr } from './fr';
import { zh } from './zh';
import { ru } from './ru';
function getResources(): Resource {
const resources: Resource = {};
const resources = { en, fr, ru, zh };
const modules: Record<string, Resource> = import.meta.glob('./locales/*.ts', { eager: true });
for (const path in modules) {
const moduleName = path.split('/').pop()?.replace('.ts', '');
if (moduleName) {
resources[moduleName] = modules[path].default;
}
}
return resources;
}
function getCurrentLanguage(): string {
const languages = Object.keys(resources);
@@ -26,11 +35,14 @@ function getCurrentLanguage(): string {
return 'en';
}
const resources = getResources();
const lng = getCurrentLanguage();
i18n
.use(initReactI18next)
.init({
resources: resources,
lng: getCurrentLanguage(),
resources,
lng,
fallbackLng: 'en',
interpolation: {
escapeValue: false

View File

@@ -0,0 +1,6 @@
export const languages = [
{ key: 'en', name: 'English' },
{ key: 'fr', name: 'Français' },
{ key: 'ru', name: 'Русский' },
{ key: 'zh', name: '中文' }
];

View File

@@ -1,4 +1,4 @@
export const en = {
const en = {
translation: {
language: 'Language',
changePassword: 'Change Password',
@@ -159,3 +159,5 @@ export const en = {
}
}
};
export default en;

View File

@@ -1,4 +1,4 @@
export const fr = {
const fr = {
translation: {
language: 'Langue',
changePassword: 'Changer le mot de passe',
@@ -163,3 +163,5 @@ export const fr = {
}
}
};
export default fr;

View File

@@ -1,4 +1,4 @@
export const ru = {
const ru = {
translation: {
language: 'Язык',
changePassword: 'Изменить пароль',
@@ -17,7 +17,8 @@ export const ru = {
hddLed: 'Индикатор активности хранилища',
checkLibFailed: 'Не удалось проверить библиотеку среды выполнения, попробуйте еще раз',
updateLibFailed: 'Не удалось обновить библиотеку среды выполнения, попробуйте еще раз',
updatingLib: 'Обновление библиотеки среды выполнения. Пожалуйста, обновите страницу после обновления.',
updatingLib:
'Обновление библиотеки среды выполнения. Пожалуйста, обновите страницу после обновления.',
checkForUpdate: 'Проверить обновления',
head: {
desktop: 'Удаленный рабочий стол',
@@ -32,7 +33,8 @@ export const ru = {
placeholderPassword2: 'Введите пароль снова',
noEmptyUsername: 'Имя пользователя не может быть пустым',
noEmptyPassword: 'Пароль не может быть пустым',
noAccount: 'Не удалось получить информацию о пользователе, пожалуйста, обновите веб-страницу или сбросьте пароль',
noAccount:
'Не удалось получить информацию о пользователе, пожалуйста, обновите веб-страницу или сбросьте пароль',
invalidUser: 'Неверное имя пользователя или пароль',
error: 'Непредвиденная ошибка',
changePassword: 'Изменить пароль',
@@ -55,7 +57,7 @@ export const ru = {
quality: 'Качество',
frameDetect: 'Экономия трафика',
frameDetectTip:
"Вычисляет разницу между кадрами и прекращает передачу видеопотока, если на экране удаленного узла не обнаружено никаких изменений."
'Вычисляет разницу между кадрами и прекращает передачу видеопотока, если на экране удаленного узла не обнаружено никаких изменений.'
},
cursor: {
default: 'Курсор по умолчанию',
@@ -88,7 +90,7 @@ export const ru = {
tf3: 'Вставьте карту памяти в картридер и подключите его в свой компьютер.',
tf4: 'Скопируйте файл образа в директорию /data на карте памяти.',
tf5: 'Вставьте карту памяти в NanoKVM.'
},
}
},
script: {
title: 'Скрипты',
@@ -162,3 +164,5 @@ export const ru = {
}
}
};
export default ru;

View File

@@ -1,4 +1,4 @@
export const zh = {
const zh = {
translation: {
currentVersion: '版本',
latestVersion: '最新版本:',
@@ -158,3 +158,5 @@ export const zh = {
}
}
};
export default zh;

View File

@@ -3,6 +3,7 @@ import clsx from 'clsx';
import { LanguagesIcon } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { languages } from '@/i18n/languages.ts';
import { setLanguage } from '@/lib/localstorage.ts';
export const Language = () => {
@@ -15,25 +16,18 @@ export const Language = () => {
setLanguage(lng);
}
const languageItems = [
{ lng: 'en', name: 'English' },
{ lng: 'fr', name: 'Français' },
{ lng: 'ru', name: 'Русский' },
{ lng: 'zh', name: '中文' }
];
const content = (
<>
{languageItems.map((item) => (
{languages.map((lng) => (
<div
key={item.lng}
key={lng.key}
className={clsx(
'flex cursor-pointer select-none items-center space-x-1 rounded px-5 py-1',
i18n.language === item.lng ? 'text-blue-500' : 'text-white hover:bg-neutral-700'
i18n.language === lng.key ? 'text-blue-500' : 'text-white hover:bg-neutral-700'
)}
onClick={() => changeLanguage(item.lng)}
onClick={() => changeLanguage(lng.key)}
>
{item.name}
{lng.name}
</div>
))}
</>

View File

@@ -3,6 +3,7 @@ import clsx from 'clsx';
import { LanguagesIcon } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { languages } from '@/i18n/languages.ts';
import { setLanguage } from '@/lib/localstorage.ts';
export const Language = () => {
@@ -15,25 +16,18 @@ export const Language = () => {
setLanguage(lng);
}
const languageItems = [
{ lng: 'en', name: 'English' },
{ lng: 'fr', name: 'Français' },
{ lng: 'ru', name: 'Русский' },
{ lng: 'zh', name: '中文' }
];
const content = (
<>
{languageItems.map((item) => (
{languages.map((lng) => (
<div
key={item.lng}
key={lng.key}
className={clsx(
'flex cursor-pointer select-none items-center space-x-1 rounded px-5 py-1',
i18n.language === item.lng ? 'text-blue-500' : 'text-white hover:bg-neutral-700'
i18n.language === lng.key ? 'text-blue-500' : 'text-white hover:bg-neutral-700'
)}
onClick={() => changeLanguage(item.lng)}
onClick={() => changeLanguage(lng.key)}
>
{item.name}
{lng.name}
</div>
))}
</>