mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-23 16:25:22 +03:00
Parse messages file and use i18next vue plugin
This commit is contained in:
parent
f87c0f5461
commit
dba61bc652
10 changed files with 89 additions and 65 deletions
|
@ -72,15 +72,15 @@
|
|||
<div class="logo">
|
||||
<div class="logo_text">
|
||||
<span>
|
||||
{{ $t("versionLabelConfigurator.message") }}: {{ configuratorVersion }}
|
||||
{{ $t("versionLabelConfigurator") }}: {{ configuratorVersion }}
|
||||
<br />
|
||||
<span v-if="firmwareVersion && firmwareId">
|
||||
{{ $t("versionLabelFirmware.message") }}: {{ firmwareVersion }}
|
||||
{{ $t("versionLabelFirmware") }}: {{ firmwareVersion }}
|
||||
{{ firmwareId }}
|
||||
</span>
|
||||
<br />
|
||||
<span v-if="hardwareId">
|
||||
{{ $t("versionLabelTarget.message") }}: {{ hardwareId }}
|
||||
{{ $t("versionLabelTarget") }}: {{ hardwareId }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -4,14 +4,6 @@ import BatteryLegend from "./quad-status/BatteryLegend.vue";
|
|||
import BetaflightLogo from "./betaflight-logo/BetaflightLogo.vue";
|
||||
import StatusBar from "./status-bar/StatusBar.vue";
|
||||
|
||||
// a bit of a hack here to get around the current translations.
|
||||
// vue i18n provides slightly different api for this. But
|
||||
// it's also possible to provide custom formatter
|
||||
Vue.filter(
|
||||
"stripEnd",
|
||||
(value) => value.replace(/\$1%/, "")
|
||||
);
|
||||
|
||||
// Most of the global objects can go here at first.
|
||||
// It's a bit of overkill for simple components,
|
||||
// but these instance would eventually have more children
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<span>{{ $t("statusbar_port_utilization.message") }}</span>
|
||||
<span>{{ $t("statusbar_port_utilization") }}</span>
|
||||
<ReadingStat
|
||||
message="statusbar_usage_download"
|
||||
:value="usageDown"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<span>
|
||||
<span>{{ $t(message + ".message") | stripEnd }}</span>
|
||||
<span>{{ $t(message) }}</span>
|
||||
<span>{{ value }}</span>
|
||||
<span v-if="unit">{{ unit }}</span>
|
||||
</span>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<div class="version">
|
||||
{{ $t("versionLabelConfigurator.message") }}: {{ configuratorVersion }}
|
||||
{{ $t("versionLabelConfigurator") }}: {{ configuratorVersion }}
|
||||
<span v-if="firmwareVersion && firmwareId">
|
||||
, {{ $t("versionLabelFirmware.message") }}: {{ firmwareVersion }}
|
||||
, {{ $t("versionLabelFirmware") }}: {{ firmwareVersion }}
|
||||
{{ firmwareId }}
|
||||
</span>
|
||||
<span v-if="hardwareId">
|
||||
, {{ $t("versionLabelTarget.message") }}: {{ hardwareId }}
|
||||
, {{ $t("versionLabelTarget") }}: {{ hardwareId }}
|
||||
</span>
|
||||
({{ gitChangesetId }})
|
||||
</div>
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
import Vue from "vue";
|
||||
import VueI18n from "vue-i18n";
|
||||
import VueI18Next from "@panter/vue-i18next";
|
||||
|
||||
Vue.use(VueI18n);
|
||||
Vue.use(VueI18Next);
|
||||
|
||||
const vueI18n = new VueI18n(i18next);
|
||||
|
||||
i18next.on("initialized", () => {
|
||||
vueI18n.setLocaleMessage("en", i18next.getDataByLanguage("en").messages);
|
||||
});
|
||||
|
||||
i18next.on("languageChanged", (lang) => {
|
||||
vueI18n.setLocaleMessage(lang, i18next.getDataByLanguage(lang).messages);
|
||||
vueI18n.locale = lang;
|
||||
document.querySelector("html").setAttribute("lang", lang);
|
||||
});
|
||||
const vueI18n = new VueI18Next(i18next);
|
||||
|
||||
export default vueI18n;
|
||||
|
|
|
@ -29,26 +29,53 @@ i18n.init = function(cb) {
|
|||
ns: ['messages'],
|
||||
defaultNS:['messages'],
|
||||
fallbackLng: languageFallback,
|
||||
backend: { loadPath: '/_locales/{{lng}}/{{ns}}.json' },
|
||||
}, function(err) {
|
||||
if (err !== undefined) {
|
||||
console.error(`Error loading i18n: ${err}`);
|
||||
} else {
|
||||
console.log('i18n system loaded');
|
||||
const detectedLanguage = i18n.getMessage(`language_${getValidLocale("DEFAULT")}`);
|
||||
i18n.addResources({"detectedLanguage": detectedLanguage });
|
||||
i18next.on('languageChanged', function () {
|
||||
i18n.localizePage(true);
|
||||
});
|
||||
}
|
||||
if (cb !== undefined) {
|
||||
cb();
|
||||
}
|
||||
backend: {
|
||||
loadPath: '/_locales/{{lng}}/{{ns}}.json',
|
||||
parse: i18n.parseInputFile,
|
||||
},
|
||||
},
|
||||
function(err) {
|
||||
if (err !== undefined) {
|
||||
console.error(`Error loading i18n: ${err}`);
|
||||
} else {
|
||||
console.log('i18n system loaded');
|
||||
const detectedLanguage = i18n.getMessage(`language_${getValidLocale("DEFAULT")}`);
|
||||
i18n.addResources({"detectedLanguage": detectedLanguage });
|
||||
i18next.on('languageChanged', function () {
|
||||
i18n.localizePage(true);
|
||||
});
|
||||
}
|
||||
if (cb !== undefined) {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* We have different interpolate methods in the input messages file,
|
||||
* we unify all of them here to the i18next style and simplify it
|
||||
*/
|
||||
i18n.parseInputFile = function(data) {
|
||||
|
||||
// Remove the $n interpolate of Chrome $1, $2, ... -> {{1}}, {{2}}, ...
|
||||
const REGEXP_CHROME = /\$([1-9])/g;
|
||||
const dataChrome = data.replace(REGEXP_CHROME, '{{$1}}');
|
||||
|
||||
// Remove the .message of the nesting $t(xxxxx.message) -> $t(xxxxx)
|
||||
const REGEXP_NESTING = /\$t\(([^\)]*).message\)/g;
|
||||
const dataNesting = dataChrome.replace(REGEXP_NESTING, '$t($1)');
|
||||
|
||||
// Move the .message of the json object to root xxxxx.message -> xxxxx
|
||||
const jsonData = JSON.parse(dataNesting);
|
||||
Object.entries(jsonData).forEach(([key, value]) => {
|
||||
jsonData[key] = value.message;
|
||||
});
|
||||
|
||||
return jsonData;
|
||||
};
|
||||
|
||||
i18n.changeLanguage = function(languageSelected) {
|
||||
if (typeof ConfigStorage !== 'undefined') {
|
||||
ConfigStorage.set({'userLanguageSelect': languageSelected});
|
||||
|
@ -60,28 +87,29 @@ i18n.changeLanguage = function(languageSelected) {
|
|||
|
||||
i18n.getMessage = function(messageID, parameters) {
|
||||
|
||||
let translatedString;
|
||||
let parametersObject;
|
||||
|
||||
// Option 1, no parameters or Object as parameters (i18Next type parameters)
|
||||
if ((parameters === undefined) || ((parameters.constructor !== Array) && (parameters instanceof Object))) {
|
||||
translatedString = i18next.t(`${messageID}.message`, parameters);
|
||||
parametersObject = parameters;
|
||||
|
||||
// Option 2: parameters as $1, $2, etc.
|
||||
// (deprecated, from the old Chrome i18n
|
||||
} else {
|
||||
|
||||
translatedString = i18next.t(`${messageID}.message`);
|
||||
|
||||
// Convert the input to an array
|
||||
let parametersArray = parameters;
|
||||
if (parametersArray.constructor !== Array) {
|
||||
parametersArray = [parameters];
|
||||
}
|
||||
parametersArray.forEach(function(element, index) {
|
||||
translatedString = translatedString.replace(`$${(index + 1)}`, element);
|
||||
|
||||
parametersObject = {};
|
||||
parametersArray.forEach(function(parameter, index) {
|
||||
parametersObject[index + 1] = parameter;
|
||||
});
|
||||
}
|
||||
|
||||
return translatedString;
|
||||
return i18next.t(messageID, parametersObject);
|
||||
};
|
||||
|
||||
i18n.getLanguagesAvailables = function() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue