localization
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
import {Locale} from "./locale";
|
||||
|
||||
export default class API {
|
||||
constructor() {
|
||||
this.loggedIn = false;
|
||||
@@ -139,68 +137,18 @@ export default class API {
|
||||
}
|
||||
|
||||
async setLanguage(params) {
|
||||
let res = await this.apiCall("language/set", params);
|
||||
if (res.success) {
|
||||
Locale.getInstance().setLocale(res.language.code);
|
||||
}
|
||||
|
||||
return res;
|
||||
return await this.apiCall("language/set", params);
|
||||
}
|
||||
|
||||
async setLanguageByCode(code) {
|
||||
return this.setLanguage({ code: code });
|
||||
}
|
||||
|
||||
async setLanguageByName(name) {
|
||||
return this.setLanguage({ name: name });
|
||||
}
|
||||
|
||||
async getLanguageEntries(modules, code=null, useCache=true) {
|
||||
async getLanguageEntries(modules, code=null, useCache=false) {
|
||||
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 };
|
||||
}
|
||||
return this.apiCall("language/getEntries", {code: code, modules: modules});
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
} */
|
||||
};
|
||||
@@ -1,18 +1,19 @@
|
||||
// application-wide global variables // translation cache
|
||||
class Locale {
|
||||
import React from 'react';
|
||||
import {createContext, useCallback, useState} from "react";
|
||||
|
||||
constructor() {
|
||||
this.entries = {};
|
||||
this.currentLocale = "en_US";
|
||||
}
|
||||
const LocaleContext = React.createContext(null);
|
||||
|
||||
translate(key) {
|
||||
function LocaleProvider(props) {
|
||||
|
||||
if (this.currentLocale) {
|
||||
if (this.entries.hasOwnProperty(this.currentLocale)) {
|
||||
const [entries, setEntries] = useState(window.languageEntries || {});
|
||||
const [currentLocale, setCurrentLocale] = useState(window.languageCode || "en_US");
|
||||
|
||||
const translate = useCallback((key) => {
|
||||
if (currentLocale) {
|
||||
if (entries.hasOwnProperty(currentLocale)) {
|
||||
let [module, variable] = key.split(".");
|
||||
if (module && variable && this.entries[this.currentLocale].hasOwnProperty(module)) {
|
||||
let translation = this.entries[this.currentLocale][module][variable];
|
||||
if (module && variable && entries[currentLocale].hasOwnProperty(module)) {
|
||||
let translation = entries[currentLocale][module][variable];
|
||||
if (translation) {
|
||||
return translation;
|
||||
}
|
||||
@@ -21,47 +22,112 @@ class Locale {
|
||||
}
|
||||
|
||||
return "[" + key + "]";
|
||||
}
|
||||
}, [currentLocale, entries]);
|
||||
|
||||
setLocale(code) {
|
||||
this.currentLocale = code;
|
||||
if (!this.entries.hasOwnProperty(code)) {
|
||||
this.entries[code] = {};
|
||||
const loadModule = useCallback((code, module, newEntries) => {
|
||||
let _entries = {...entries};
|
||||
if (!_entries.hasOwnProperty(code)) {
|
||||
_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};
|
||||
if (_entries[code].hasOwnProperty(module)) {
|
||||
_entries[code][module] = {..._entries[code][module], ...newEntries};
|
||||
} else {
|
||||
this.entries[code][module] = newEntries;
|
||||
_entries[code][module] = newEntries;
|
||||
}
|
||||
}
|
||||
setEntries(_entries);
|
||||
}, [entries]);
|
||||
|
||||
hasModule(code, module) {
|
||||
return this.entries.hasOwnProperty(code) && !!this.entries[code][module];
|
||||
}
|
||||
const loadModules = useCallback((code, modules) => {
|
||||
setEntries({...entries, [code]: { ...entries[code], ...modules }});
|
||||
}, [entries]);
|
||||
|
||||
getModule(code, module) {
|
||||
if (this.hasModule(code, module)) {
|
||||
return this.entries[code][module];
|
||||
const hasModule = useCallback((code, module) => {
|
||||
return entries.hasOwnProperty(code) && !!entries[code][module];
|
||||
}, [entries]);
|
||||
|
||||
const getModule = useCallback((code, module) => {
|
||||
if (hasModule(code, module)) {
|
||||
return entries[code][module];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}, [entries]);
|
||||
|
||||
static getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
/** API HOOKS **/
|
||||
const setLanguage = useCallback(async (api, params) => {
|
||||
let res = await api.setLanguage(params);
|
||||
if (res.success) {
|
||||
setCurrentLocale(res.language.code)
|
||||
}
|
||||
return res;
|
||||
}, []);
|
||||
|
||||
const setLanguageByName = useCallback((api, name) => {
|
||||
return setLanguage(api, {name: name});
|
||||
}, [setLanguage]);
|
||||
|
||||
const setLanguageByCode = useCallback((api, code) => {
|
||||
return setLanguage(api, {code: code});
|
||||
}, [setLanguage]);
|
||||
|
||||
const requestModules = useCallback(async (api, modules, code=null, useCache=true) => {
|
||||
if (!Array.isArray(modules)) {
|
||||
modules = [modules];
|
||||
}
|
||||
|
||||
if (code === null) {
|
||||
code = currentLocale;
|
||||
if (code === null && api.loggedIn) {
|
||||
code = api.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 = getModule(code, module);
|
||||
if (moduleEntries) {
|
||||
modules.splice(modules.indexOf(module), 1);
|
||||
languageEntries = {...languageEntries, [module]: moduleEntries};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modules.length > 0) {
|
||||
let data = await api.apiCall("language/getEntries", { code: code, modules: modules });
|
||||
|
||||
if (useCache) {
|
||||
if (data && data.success) {
|
||||
// insert into cache
|
||||
loadModules(code, data.entries);
|
||||
data.entries = {...data.entries, ...languageEntries};
|
||||
data.cached = false;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
} else {
|
||||
return { success: true, msg: "", entries: languageEntries, code: code, cached: true };
|
||||
}
|
||||
}, [currentLocale, getModule, loadModules]);
|
||||
|
||||
const ctx = {
|
||||
currentLocale: currentLocale,
|
||||
translate: translate,
|
||||
requestModules: requestModules,
|
||||
setLanguageByCode: setLanguageByCode,
|
||||
};
|
||||
|
||||
return (
|
||||
<LocaleContext.Provider value={ctx}>
|
||||
{props.children}
|
||||
</LocaleContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
let INSTANCE = new Locale();
|
||||
|
||||
function L(key) {
|
||||
return Locale.getInstance().translate(key);
|
||||
}
|
||||
|
||||
export { L, Locale };
|
||||
export {LocaleContext, LocaleProvider};
|
||||
Reference in New Issue
Block a user