first attempt with multi language support

pull/903/head
DJ2LS 2025-02-25 14:00:02 +01:00
parent 1f346fdaa8
commit 3d9f14d136
8 changed files with 100 additions and 4 deletions

View File

@ -43,6 +43,7 @@
"uuid": "^11.0.2",
"vue": "^3.2.13",
"vue-chartjs": "^5.3.1",
"vue-i18n": "^11.1.1",
"vuemoji-picker": "^0.3.1"
},
"devDependencies": {

View File

@ -4,6 +4,28 @@
<strong><i class="bi bi-gear-wide-connected me-1"></i>GUI</strong> related settings, like customizing your <strong>waterfall theme</strong>, <strong>notifications</strong>, and <strong>browser behavior</strong>.
</div>
<!-- Language Selector -->
<div class="input-group input-group-sm mb-1">
<span class="input-group-text w-50 text-wrap">
{{ $t('settings_select_language') }}
<button
type="button"
class="btn btn-link p-0 ms-2"
data-bs-toggle="tooltip"
title="Select color theme for waterfall display"
>
<i class="bi bi-question-circle"></i>
</button>
</span>
<select class="form-select form-select-sm w-50" v-model="settings.local.language" @change="updateLanguage">
<option v-for="lang in availableLanguages" :key="lang.iso" :value="lang.iso">
{{ lang.iso.toUpperCase() }} - {{ lang.name }}
</option>
</select>
</div>
<!-- Waterfall Theme Selection -->
<div class="input-group input-group-sm mb-1">
<span class="input-group-text w-50 text-wrap">
@ -23,7 +45,7 @@
@change="saveSettings"
v-model="settings.local.wf_theme"
>
<option value="2">Default</option>
<option value="2">{{ $t('settings_default') }}</option>
<option value="0">Turbo</option>
<option value="1">Fosphor</option>
<option value="3">Inferno</option>
@ -55,7 +77,7 @@
@change="onChange"
v-model="settings.remote.GUI.auto_run_browser"
/>
<label class="form-check-label" for="autoLaunchBrowserSwitch">Enable</label>
<label class="form-check-label" for="autoLaunchBrowserSwitch">{{ $t('settings_enable') }}</label>
</div>
</label>
</div>
@ -67,6 +89,8 @@ import { setColormap } from "../js/waterfallHandler";
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
import { setActivePinia } from "pinia";
import pinia from "../store/index";
import { availableLanguages } from '../js/i18n'
// Set the active Pinia store
setActivePinia(pinia);
@ -79,9 +103,19 @@ function saveSettings() {
// Export methods for use in the template
export default {
data() {
return {
//currentLocale: this.$i18n.locale,
availableLanguages: availableLanguages
}
},
methods: {
saveSettings,
onChange,
updateLanguage() {
saveSettings();
this.$i18n.locale = this.settings.local.language;
},
},
computed: {
settings() {
@ -89,4 +123,6 @@ export default {
},
},
};
</script>

View File

@ -1,4 +1,6 @@
<template>
<div class="container-fluid p-2" style="height: calc(-48px + 100vh);">
<div class="card text-center h-100">
<div class="card-header">
@ -214,6 +216,8 @@ import settings_web from "./settings_web.vue";
import settings_exp from "./settings_exp.vue";
import settings_url from "./settings_url.vue";
export default {
components: {
settings_station,
@ -224,7 +228,9 @@ export default {
settings_web,
settings_exp,
settings_url
}
},
};
</script>

View File

@ -0,0 +1,32 @@
import { createI18n } from 'vue-i18n'
// Dynamically import all JSON files from the locales folder
function loadLocaleMessages() {
const locales = require.context('../locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
const messages = {}
const languages = [] // This will hold objects with iso and name properties
locales.keys().forEach(key => {
// Expecting file names like "./en_english.json" or "./de_deutsch.json"
const matched = key.match(/\.\/([^_]+)_([^.]+)\.json$/i)
if (matched && matched.length > 2) {
const iso = matched[1]
const name = matched[2]
messages[iso] = locales(key)
languages.push({ iso, name })
}
})
return { messages, languages }
}
const { messages, languages } = loadLocaleMessages()
const i18n = createI18n({
locale: 'de', // Default language (e.g., German)
fallbackLocale: 'en', // Fallback language (English)
messages,
})
export default i18n
// Export available languages for use in components as an array of objects
export const availableLanguages = languages

View File

@ -0,0 +1,5 @@
{
"settings_select_language": "Sprache",
"settings_enable": "Aktivieren",
"settings_default": "standard"
}

View File

@ -0,0 +1,5 @@
{
"settings_select_language": "Select language",
"settings_enable": "Enable",
"settings_default": "default"
}

View File

@ -1,9 +1,10 @@
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
import i18n from './js/i18n'
import { Chart, Filler } from "chart.js";
import { getRemote } from "./store/settingsStore";
import { getRemote, settingsStore as settings } from "./store/settingsStore";
import { initConnections } from "./js/event_sock.js";
import { getModemState } from "./js/api";
@ -13,6 +14,9 @@ Chart.register(Filler);
// Create the Vue app
const app = createApp(App);
// use i18n
app.use(i18n)
// Create and use Pinia store
const pinia = createPinia();
app.use(pinia);
@ -24,4 +28,10 @@ app.mount("#app");
getRemote().then(() => {
initConnections();
getModemState();
//console.log(settings.local)
//console.log(settings.local.language)
//let language = JSON.parse(settings.local.getItem("language")) || 'en';
i18n.global.locale = settings.local.language;
});

View File

@ -12,6 +12,7 @@ const defaultConfig = {
grid_layout: "[]",
grid_preset: "[]",
grid_enabled: true,
language:"en",
},
remote: {
AUDIO: {