Localization & stuff

This commit is contained in:
2022-11-30 16:42:24 +01:00
parent 25ef07b0b7
commit 1ba27e4f40
54 changed files with 856 additions and 494 deletions

View File

@@ -1,3 +1,5 @@
import {Locale} from "./locale";
export default class API {
constructor() {
this.loggedIn = false;
@@ -136,11 +138,69 @@ export default class API {
return this.apiCall("language/get");
}
async setLanguage(params) {
let res = await this.apiCall("language/set", params);
if (res.success) {
Locale.getInstance().setLocale(res.language.code);
}
return res;
}
async setLanguageByCode(code) {
return this.apiCall("language/set", { code: code });
return this.setLanguage({ code: code });
}
async setLanguageByName(name) {
return this.apiCall("language/set", { name: name });
return this.setLanguage({ name: name });
}
async getLanguageEntries(modules, code=null, useCache=true) {
if (!Array.isArray(modules)) {
modules = [modules];
}
let locale = Locale.getInstance();
if (code === null) {
code = locale.currentLocale;
if (code === null && this.loggedIn) {
code = this.user.language.code;
}
}
if (code === null) {
return { success: false, msg: "No locale selected currently" };
}
let languageEntries = {};
if (useCache) {
// remove cached modules from request array
for (const module of [...modules]) {
let moduleEntries = locale.getModule(code, module);
if (moduleEntries) {
modules.splice(modules.indexOf(module), 1);
languageEntries = {...languageEntries, [module]: moduleEntries};
}
}
}
if (modules.length > 0) {
let data = await this.apiCall("language/getEntries", { code: code, modules: modules });
if (useCache) {
if (data && data.success) {
// insert into cache
for (const [module, entries] of Object.entries(data.entries)) {
locale.loadModule(code, module, entries);
}
data.entries = {...data.entries, ...languageEntries};
data.cached = false;
}
}
return data;
} else {
return { success: true, msg: "", entries: languageEntries, code: code, cached: true };
}
}
};

67
react/shared/locale.js Normal file
View File

@@ -0,0 +1,67 @@
// application-wide global variables // translation cache
class Locale {
constructor() {
this.entries = {};
this.currentLocale = "en_US";
}
translate(key) {
if (this.currentLocale) {
if (this.entries.hasOwnProperty(this.currentLocale)) {
let [module, variable] = key.split(".");
if (module && variable && this.entries[this.currentLocale].hasOwnProperty(module)) {
let translation = this.entries[this.currentLocale][module][variable];
if (translation) {
return translation;
}
}
}
}
return "[" + key + "]";
}
setLocale(code) {
this.currentLocale = code;
if (!this.entries.hasOwnProperty(code)) {
this.entries[code] = {};
}
}
loadModule(code, module, newEntries) {
if (!this.entries.hasOwnProperty(code)) {
this.entries[code] = {};
}
if (this.entries[code].hasOwnProperty(module)) {
this.entries[code][module] = {...this.entries[code][module], ...newEntries};
} else {
this.entries[code][module] = newEntries;
}
}
hasModule(code, module) {
return this.entries.hasOwnProperty(code) && !!this.entries[code][module];
}
getModule(code, module) {
if (this.hasModule(code, module)) {
return this.entries[code][module];
} else {
return null;
}
}
static getInstance() {
return INSTANCE;
}
}
let INSTANCE = new Locale();
function L(key) {
return Locale.getInstance().translate(key);
}
export { L, Locale };

View File

@@ -1,14 +0,0 @@
import React from "react";
import { enUS as dateFnsEN } from "date-fns/locale/index.js";
export default class LocaleEnglish {
constructor() {
this.code = "en_US";
this.name = "American English";
this.entries = {};
}
toDateFns() {
return dateFnsEN;
}
};

View File

@@ -1,14 +0,0 @@
import React from "react";
import { de as dateFnsDE } from "date-fns/locale/index.js";
export default class LocaleGerman {
constructor() {
this.code = "de_DE";
this.name = "Deutsch Standard";
this.entries = {};
}
toDateFns() {
return dateFnsDE;
}
}

View File

@@ -1,35 +0,0 @@
import LocaleGerman from "./german";
import LocaleEnglish from "./english";
let INSTANCE = new LocaleEnglish();
function initLocale(code) {
if (!INSTANCE || INSTANCE.code !== code) {
const constructors = {
"de_DE": LocaleGerman,
"en_US": LocaleEnglish,
}
if (constructors.hasOwnProperty(code)) {
INSTANCE = new (constructors[code])();
} else {
INSTANCE = { code: code, entries: { } };
}
}
return INSTANCE;
}
function translate(key) {
return (INSTANCE.entries[key] || key);
}
function useLanguageModule(module) {
if (module[INSTANCE.code]) {
for (const [key, value] of Object.entries(module[INSTANCE.code])) {
INSTANCE.entries[key] = value;
}
}
}
export { translate as L, initLocale, useLanguageModule, INSTANCE as currentLocale };