Feature/i18n load resources from backend (#746)

* Load i18n resources from backend

* Move locales to public folder
This commit is contained in:
schroda
2024-04-14 17:32:25 +02:00
committed by GitHub
parent 43597e8428
commit 6276da42cf
22 changed files with 49 additions and 57 deletions

View File

@@ -43,6 +43,7 @@
"html-react-parser": "5.1.10",
"i18next": "23.11.1",
"i18next-browser-languagedetector": "7.2.1",
"i18next-http-backend": "^2.5.0",
"material-ui-popup-state": "5.1.0",
"p-limit": "5.0.0",
"react": "18.2.0",

View File

@@ -9,14 +9,42 @@
import { use } from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { resources } from '@/i18n/translations';
import HttpBackend from 'i18next-http-backend';
/**
* Keys have to match {@link ISOLanguages} codes, they're used for showing the language name in the dropdown in the {@link Settings}.<br/>
* In case there is no language code for the key in {@link ISOLanguages}, the corresponding language has to be added
*/
export const i18nResources = [
'ar',
'de',
'en',
'es',
'fr',
'id',
'it',
'ja',
'ko',
'nb_NO',
'pt',
'sv',
'uk',
'vi',
'zh_Hans',
'zh_Hant',
];
export const i18n = use(initReactI18next)
.use(HttpBackend)
.use(LanguageDetector)
.init({
resources,
fallbackLng: 'en',
backend: {
loadPath: '/locales/{{lng}}.json',
allowMultiLoading: true,
},
interpolation: {
escapeValue: false,
format: (value, format) => {
@@ -28,6 +56,7 @@ export const i18n = use(initReactI18next)
}
},
},
returnNull: false,
debug: process.env.NODE_ENV !== 'production',
});

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import ar from '@/i18n/locale/ar.json';
import de from '@/i18n/locale/de.json';
import en from '@/i18n/locale/en.json'; // default language
import es from '@/i18n/locale/es.json';
import fr from '@/i18n/locale/fr.json';
import id from '@/i18n/locale/id.json';
import it from '@/i18n/locale/it.json';
import ja from '@/i18n/locale/ja.json';
import ko from '@/i18n/locale/ko.json';
import nb_NO from '@/i18n/locale/nb-NO.json';
import pt from '@/i18n/locale/pt.json';
import sv from '@/i18n/locale/sv.json';
import tr from '@/i18n/locale/tr.json';
import uk from '@/i18n/locale/uk.json';
import vi from '@/i18n/locale/vi.json';
import zh_Hans from '@/i18n/locale/zh_Hans.json';
import zh_Hant from '@/i18n/locale/zh_Hant.json';
const translationHelper = <T>(lng: T) => ({
translation: lng,
});
/**
* Keys have to match {@link ISOLanguages} codes, they're used for showing the language name in the dropdown in the {@link Settings}.<br/>
* In case there is no language code for the key in {@link ISOLanguages}, the corresponding language has to be added
*/
export const resources = {
ar: translationHelper(ar),
de: translationHelper(de),
en: translationHelper(en), // default language
es: translationHelper(es),
fr: translationHelper(fr),
id: translationHelper(id),
it: translationHelper(it),
ja: translationHelper(ja),
ko: translationHelper(ko),
'nb-NO': translationHelper(nb_NO),
pt: translationHelper(pt),
sv: translationHelper(sv),
tr: translationHelper(tr),
uk: translationHelper(uk),
vi: translationHelper(vi),
'zh-Hans': translationHelper(zh_Hans),
'zh-Hant': translationHelper(zh_Hant),
} as const;

View File

@@ -40,6 +40,7 @@ import { NumberSetting } from '@/components/settings/NumberSetting.tsx';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { makeToast } from '@/components/util/Toast.tsx';
import { Select } from '@/components/atoms/Select.tsx';
import { i18nResources } from '@/i18n';
export function Settings() {
const { t, i18n } = useTranslation();
@@ -149,7 +150,7 @@ export function Settings() {
value={i18n.language}
onChange={({ target: { value: language } }) => i18n.changeLanguage(language)}
>
{Object.keys(i18n.services.resourceStore.data).map((language) => (
{i18nResources.map((language) => (
<MenuItem key={language} value={language}>
{langCodeToName(language)}
</MenuItem>

View File

@@ -3386,6 +3386,13 @@ create-require@^1.1.0:
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
cross-fetch@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983"
integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==
dependencies:
node-fetch "^2.6.12"
cross-fetch@^3.1.5:
version "3.1.8"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82"
@@ -4548,6 +4555,13 @@ i18next-browser-languagedetector@7.2.1:
dependencies:
"@babel/runtime" "^7.23.2"
i18next-http-backend@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/i18next-http-backend/-/i18next-http-backend-2.5.0.tgz#8396a7df30bfe722eff7a65f629df32a61720414"
integrity sha512-Z/aQsGZk1gSxt2/DztXk92DuDD20J+rNudT7ZCdTrNOiK8uQppfvdjq9+DFQfpAnFPn3VZS+KQIr1S/W1KxhpQ==
dependencies:
cross-fetch "4.0.0"
i18next@23.11.1:
version "23.11.1"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.11.1.tgz#8e384b6ad7d6ba70c40cb86e020438251a5ff8b1"