mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Replace i18n by a custom implementation (#638)
There are two problems with the current localization strategy: - We download the translations on-demand, which means that it does a serial roundtrip for nothing. - withTranslation helper actually renders the app 3 times on startup, instead of once (I haven't tried to debug it)
This commit is contained in:
parent
637276301a
commit
e4919e2e6c
21 changed files with 101 additions and 167 deletions
92
src/i18n.ts
92
src/i18n.ts
|
@ -1,36 +1,68 @@
|
|||
import i18n from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
|
||||
import Backend from "i18next-xhr-backend";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
|
||||
export const fallbackLng = "en";
|
||||
|
||||
export function parseDetectedLang(lng: string | undefined): string {
|
||||
if (lng) {
|
||||
const [lang] = i18n.language.split("-");
|
||||
return lang;
|
||||
}
|
||||
return fallbackLng;
|
||||
}
|
||||
|
||||
export const languages = [
|
||||
{ lng: "de", label: "Deutsch" },
|
||||
{ lng: "en", label: "English" },
|
||||
{ lng: "es", label: "Español" },
|
||||
{ lng: "fr", label: "Français" },
|
||||
{ lng: "pt", label: "Português" },
|
||||
{ lng: "ru", label: "Русский" },
|
||||
{ lng: "en", label: "English", data: require("./locales/en.json") },
|
||||
{ lng: "de", label: "Deutsch", data: require("./locales/de.json") },
|
||||
{ lng: "es", label: "Español", data: require("./locales/es.json") },
|
||||
{ lng: "fr", label: "Français", data: require("./locales/fr.json") },
|
||||
{ lng: "pt", label: "Português", data: require("./locales/pt.json") },
|
||||
{ lng: "ru", label: "Русский", data: require("./locales/ru.json") },
|
||||
];
|
||||
|
||||
i18n
|
||||
.use(Backend)
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
fallbackLng,
|
||||
react: { useSuspense: false },
|
||||
load: "languageOnly",
|
||||
});
|
||||
let currentLanguage = languages[0];
|
||||
const fallbackLanguage = languages[0];
|
||||
|
||||
export default i18n;
|
||||
export function setLanguage(newLng: string | undefined) {
|
||||
currentLanguage =
|
||||
languages.find(language => language.lng === newLng) || fallbackLanguage;
|
||||
|
||||
languageDetector.cacheUserLanguage(currentLanguage.lng);
|
||||
}
|
||||
|
||||
export function getLanguage() {
|
||||
return currentLanguage.lng;
|
||||
}
|
||||
|
||||
function findPartsForData(data: any, parts: string[]) {
|
||||
for (var i = 0; i < parts.length; ++i) {
|
||||
const part = parts[i];
|
||||
if (data[part] === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
data = data[part];
|
||||
}
|
||||
if (typeof data !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
export function t(path: string, replacement?: { [key: string]: string }) {
|
||||
const parts = path.split(".");
|
||||
let translation =
|
||||
findPartsForData(currentLanguage.data, parts) ||
|
||||
findPartsForData(fallbackLanguage.data, parts);
|
||||
if (translation === undefined) {
|
||||
throw new Error("Can't find translation for " + path);
|
||||
}
|
||||
|
||||
if (replacement) {
|
||||
for (var key in replacement) {
|
||||
translation = translation.replace("{{" + key + "}}", replacement[key]);
|
||||
}
|
||||
}
|
||||
return translation;
|
||||
}
|
||||
|
||||
const languageDetector = new LanguageDetector();
|
||||
languageDetector.init({
|
||||
languageUtils: {
|
||||
formatLanguageCode: function(lng: string) {
|
||||
return lng;
|
||||
},
|
||||
isWhitelisted: () => true,
|
||||
},
|
||||
checkWhitelist: false,
|
||||
});
|
||||
|
||||
setLanguage(languageDetector.detect());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue