mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-09-27 14:02:38 +02:00
119 lines
3.9 KiB
JavaScript
119 lines
3.9 KiB
JavaScript
import i18next from "i18next";
|
|
import I18NextChainedBackend from "i18next-chained-backend";
|
|
import I18NextLocalStorageBackend from "i18next-localstorage-backend";
|
|
import I18NextHttpBackend from 'i18next-http-backend';
|
|
import {initReactI18next} from 'react-i18next';
|
|
import {fetchAvailableLocales} from "./metadataService";
|
|
import {baseAddress, staticSite} from "./backendConfiguration";
|
|
|
|
/**
|
|
* A locale system for localizing the website.
|
|
*/
|
|
export const localeService = {
|
|
/**
|
|
* @function
|
|
* Localizes an element.
|
|
* @param {Element} element Element to localize
|
|
* @param {Object} [options] Options
|
|
*/
|
|
localize: {},
|
|
|
|
/**
|
|
* The current default language reported by the server.
|
|
* @type {string}
|
|
* @readonly
|
|
*/
|
|
defaultLanguage: "",
|
|
|
|
/**
|
|
* The current available languages reported by the server.
|
|
* @type {Object.<string, string>}
|
|
* @readonly
|
|
*/
|
|
availableLanguages: {},
|
|
clientLocale: "",
|
|
|
|
/**
|
|
* Initializes the locale system. Gets the default & available languages from `/v1/locale`, and initializes i18next.
|
|
*/
|
|
init: async function () {
|
|
try {
|
|
const {data} = await fetchAvailableLocales();
|
|
if (data !== undefined) {
|
|
this.defaultLanguage = data.defaultLanguage;
|
|
this.availableLanguages = data.languages;
|
|
this.languageVersions = data.languageVersions;
|
|
} else {
|
|
this.defaultLanguage = 'en'
|
|
this.availableLanguages = {};
|
|
this.languageVersions = [];
|
|
}
|
|
|
|
this.clientLocale = window.localStorage.getItem("locale");
|
|
if (!this.clientLocale) {
|
|
this.clientLocale = this.defaultLanguage;
|
|
}
|
|
|
|
let loadPath = baseAddress + '/v1/locale/{{lng}}';
|
|
if (staticSite) loadPath = baseAddress + '/locale/{{lng}}.json'
|
|
await i18next
|
|
.use(I18NextChainedBackend)
|
|
.use(initReactI18next)
|
|
.init({
|
|
debug: false,
|
|
lng: this.clientLocale,
|
|
fallbackLng: false,
|
|
supportedLngs: Object.keys(this.availableLanguages),
|
|
backend: {
|
|
backends: [
|
|
I18NextLocalStorageBackend,
|
|
I18NextHttpBackend
|
|
],
|
|
backendOptions: [{
|
|
expirationTime: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
versions: this.languageVersions
|
|
}, {
|
|
loadPath: loadPath
|
|
}]
|
|
},
|
|
}, () => {/* No need to initialize anything */
|
|
});
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Loads a locale and translates the page.
|
|
*
|
|
* @param {string} langCode The two-character code for the language to be loaded, e.g. EN
|
|
* @throws Error if an invalid langCode is given
|
|
* @see /v1/language endpoint for available language codes
|
|
*/
|
|
loadLocale: async function (langCode) {
|
|
if (i18next.language === langCode) {
|
|
return;
|
|
}
|
|
if (!(langCode in this.availableLanguages)) {
|
|
throw Error(`The locale ${langCode} isn't available!`);
|
|
}
|
|
|
|
window.localStorage.setItem("locale", langCode);
|
|
await i18next.changeLanguage(langCode)
|
|
},
|
|
|
|
getLanguages: function () {
|
|
let languages = Object.fromEntries(Object.entries(this.availableLanguages).sort());
|
|
if ('CUSTOM' in languages) {
|
|
// Move "Custom" to first in list
|
|
delete languages["CUSTOM"]
|
|
languages = Object.assign({"CUSTOM": "Custom"}, languages);
|
|
}
|
|
|
|
return Object.entries(languages)
|
|
.map(entry => {
|
|
return {name: entry[0], displayName: entry[1]}
|
|
});
|
|
}
|
|
}
|