From 6276da42cfd392b8a3044960b4b4cfa19652cbe9 Mon Sep 17 00:00:00 2001
From: schroda <50052685+schroda@users.noreply.github.com>
Date: Sun, 14 Apr 2024 17:32:25 +0200
Subject: [PATCH] Feature/i18n load resources from backend (#746)
* Load i18n resources from backend
* Move locales to public folder
---
package.json | 1 +
{src/i18n/locale => public/locales}/ar.json | 0
{src/i18n/locale => public/locales}/de.json | 0
{src/i18n/locale => public/locales}/en.json | 0
{src/i18n/locale => public/locales}/es.json | 0
{src/i18n/locale => public/locales}/fr.json | 0
{src/i18n/locale => public/locales}/id.json | 0
{src/i18n/locale => public/locales}/it.json | 0
{src/i18n/locale => public/locales}/ja.json | 0
{src/i18n/locale => public/locales}/ko.json | 0
.../i18n/locale => public/locales}/nb-NO.json | 0
{src/i18n/locale => public/locales}/pt.json | 0
{src/i18n/locale => public/locales}/sv.json | 0
{src/i18n/locale => public/locales}/tr.json | 0
{src/i18n/locale => public/locales}/uk.json | 0
{src/i18n/locale => public/locales}/vi.json | 0
.../locale => public/locales}/zh_Hans.json | 0
.../locale => public/locales}/zh_Hant.json | 0
src/i18n/index.ts | 35 ++++++++++--
src/i18n/translations.ts | 53 -------------------
src/screens/Settings.tsx | 3 +-
yarn.lock | 14 +++++
22 files changed, 49 insertions(+), 57 deletions(-)
rename {src/i18n/locale => public/locales}/ar.json (100%)
rename {src/i18n/locale => public/locales}/de.json (100%)
rename {src/i18n/locale => public/locales}/en.json (100%)
rename {src/i18n/locale => public/locales}/es.json (100%)
rename {src/i18n/locale => public/locales}/fr.json (100%)
rename {src/i18n/locale => public/locales}/id.json (100%)
rename {src/i18n/locale => public/locales}/it.json (100%)
rename {src/i18n/locale => public/locales}/ja.json (100%)
rename {src/i18n/locale => public/locales}/ko.json (100%)
rename {src/i18n/locale => public/locales}/nb-NO.json (100%)
rename {src/i18n/locale => public/locales}/pt.json (100%)
rename {src/i18n/locale => public/locales}/sv.json (100%)
rename {src/i18n/locale => public/locales}/tr.json (100%)
rename {src/i18n/locale => public/locales}/uk.json (100%)
rename {src/i18n/locale => public/locales}/vi.json (100%)
rename {src/i18n/locale => public/locales}/zh_Hans.json (100%)
rename {src/i18n/locale => public/locales}/zh_Hant.json (100%)
delete mode 100644 src/i18n/translations.ts
diff --git a/package.json b/package.json
index 2381550567..4ba8d342ba 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/i18n/locale/ar.json b/public/locales/ar.json
similarity index 100%
rename from src/i18n/locale/ar.json
rename to public/locales/ar.json
diff --git a/src/i18n/locale/de.json b/public/locales/de.json
similarity index 100%
rename from src/i18n/locale/de.json
rename to public/locales/de.json
diff --git a/src/i18n/locale/en.json b/public/locales/en.json
similarity index 100%
rename from src/i18n/locale/en.json
rename to public/locales/en.json
diff --git a/src/i18n/locale/es.json b/public/locales/es.json
similarity index 100%
rename from src/i18n/locale/es.json
rename to public/locales/es.json
diff --git a/src/i18n/locale/fr.json b/public/locales/fr.json
similarity index 100%
rename from src/i18n/locale/fr.json
rename to public/locales/fr.json
diff --git a/src/i18n/locale/id.json b/public/locales/id.json
similarity index 100%
rename from src/i18n/locale/id.json
rename to public/locales/id.json
diff --git a/src/i18n/locale/it.json b/public/locales/it.json
similarity index 100%
rename from src/i18n/locale/it.json
rename to public/locales/it.json
diff --git a/src/i18n/locale/ja.json b/public/locales/ja.json
similarity index 100%
rename from src/i18n/locale/ja.json
rename to public/locales/ja.json
diff --git a/src/i18n/locale/ko.json b/public/locales/ko.json
similarity index 100%
rename from src/i18n/locale/ko.json
rename to public/locales/ko.json
diff --git a/src/i18n/locale/nb-NO.json b/public/locales/nb-NO.json
similarity index 100%
rename from src/i18n/locale/nb-NO.json
rename to public/locales/nb-NO.json
diff --git a/src/i18n/locale/pt.json b/public/locales/pt.json
similarity index 100%
rename from src/i18n/locale/pt.json
rename to public/locales/pt.json
diff --git a/src/i18n/locale/sv.json b/public/locales/sv.json
similarity index 100%
rename from src/i18n/locale/sv.json
rename to public/locales/sv.json
diff --git a/src/i18n/locale/tr.json b/public/locales/tr.json
similarity index 100%
rename from src/i18n/locale/tr.json
rename to public/locales/tr.json
diff --git a/src/i18n/locale/uk.json b/public/locales/uk.json
similarity index 100%
rename from src/i18n/locale/uk.json
rename to public/locales/uk.json
diff --git a/src/i18n/locale/vi.json b/public/locales/vi.json
similarity index 100%
rename from src/i18n/locale/vi.json
rename to public/locales/vi.json
diff --git a/src/i18n/locale/zh_Hans.json b/public/locales/zh_Hans.json
similarity index 100%
rename from src/i18n/locale/zh_Hans.json
rename to public/locales/zh_Hans.json
diff --git a/src/i18n/locale/zh_Hant.json b/public/locales/zh_Hant.json
similarity index 100%
rename from src/i18n/locale/zh_Hant.json
rename to public/locales/zh_Hant.json
diff --git a/src/i18n/index.ts b/src/i18n/index.ts
index 55adac1465..4f038ace96 100644
--- a/src/i18n/index.ts
+++ b/src/i18n/index.ts
@@ -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}.
+ * 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',
});
diff --git a/src/i18n/translations.ts b/src/i18n/translations.ts
deleted file mode 100644
index 0904db5d64..0000000000
--- a/src/i18n/translations.ts
+++ /dev/null
@@ -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 = (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}.
- * 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;
diff --git a/src/screens/Settings.tsx b/src/screens/Settings.tsx
index 65132716ee..7eed2f789a 100644
--- a/src/screens/Settings.tsx
+++ b/src/screens/Settings.tsx
@@ -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) => (
diff --git a/yarn.lock b/yarn.lock
index b27fcd6905..8dbfb0f14f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -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"