mirror of https://github.com/DJ2LS/FreeDATA.git
first attempt with multi language support
parent
1f346fdaa8
commit
3d9f14d136
|
@ -43,6 +43,7 @@
|
||||||
"uuid": "^11.0.2",
|
"uuid": "^11.0.2",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
"vue-chartjs": "^5.3.1",
|
"vue-chartjs": "^5.3.1",
|
||||||
|
"vue-i18n": "^11.1.1",
|
||||||
"vuemoji-picker": "^0.3.1"
|
"vuemoji-picker": "^0.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -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>.
|
<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>
|
</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 -->
|
<!-- Waterfall Theme Selection -->
|
||||||
<div class="input-group input-group-sm mb-1">
|
<div class="input-group input-group-sm mb-1">
|
||||||
<span class="input-group-text w-50 text-wrap">
|
<span class="input-group-text w-50 text-wrap">
|
||||||
|
@ -23,7 +45,7 @@
|
||||||
@change="saveSettings"
|
@change="saveSettings"
|
||||||
v-model="settings.local.wf_theme"
|
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="0">Turbo</option>
|
||||||
<option value="1">Fosphor</option>
|
<option value="1">Fosphor</option>
|
||||||
<option value="3">Inferno</option>
|
<option value="3">Inferno</option>
|
||||||
|
@ -55,7 +77,7 @@
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
v-model="settings.remote.GUI.auto_run_browser"
|
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>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -67,6 +89,8 @@ import { setColormap } from "../js/waterfallHandler";
|
||||||
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
|
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
|
||||||
import { setActivePinia } from "pinia";
|
import { setActivePinia } from "pinia";
|
||||||
import pinia from "../store/index";
|
import pinia from "../store/index";
|
||||||
|
import { availableLanguages } from '../js/i18n'
|
||||||
|
|
||||||
|
|
||||||
// Set the active Pinia store
|
// Set the active Pinia store
|
||||||
setActivePinia(pinia);
|
setActivePinia(pinia);
|
||||||
|
@ -79,9 +103,19 @@ function saveSettings() {
|
||||||
|
|
||||||
// Export methods for use in the template
|
// Export methods for use in the template
|
||||||
export default {
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
//currentLocale: this.$i18n.locale,
|
||||||
|
availableLanguages: availableLanguages
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
saveSettings,
|
saveSettings,
|
||||||
onChange,
|
onChange,
|
||||||
|
updateLanguage() {
|
||||||
|
saveSettings();
|
||||||
|
this.$i18n.locale = this.settings.local.language;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
settings() {
|
settings() {
|
||||||
|
@ -89,4 +123,6 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="container-fluid p-2" style="height: calc(-48px + 100vh);">
|
<div class="container-fluid p-2" style="height: calc(-48px + 100vh);">
|
||||||
<div class="card text-center h-100">
|
<div class="card text-center h-100">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
|
@ -214,6 +216,8 @@ import settings_web from "./settings_web.vue";
|
||||||
import settings_exp from "./settings_exp.vue";
|
import settings_exp from "./settings_exp.vue";
|
||||||
import settings_url from "./settings_url.vue";
|
import settings_url from "./settings_url.vue";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
settings_station,
|
settings_station,
|
||||||
|
@ -224,7 +228,9 @@ export default {
|
||||||
settings_web,
|
settings_web,
|
||||||
settings_exp,
|
settings_exp,
|
||||||
settings_url
|
settings_url
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"settings_select_language": "Sprache",
|
||||||
|
"settings_enable": "Aktivieren",
|
||||||
|
"settings_default": "standard"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"settings_select_language": "Select language",
|
||||||
|
"settings_enable": "Enable",
|
||||||
|
"settings_default": "default"
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
import { createApp } from "vue";
|
import { createApp } from "vue";
|
||||||
import { createPinia } from "pinia";
|
import { createPinia } from "pinia";
|
||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
|
import i18n from './js/i18n'
|
||||||
|
|
||||||
import { Chart, Filler } from "chart.js";
|
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 { initConnections } from "./js/event_sock.js";
|
||||||
import { getModemState } from "./js/api";
|
import { getModemState } from "./js/api";
|
||||||
|
|
||||||
|
@ -13,6 +14,9 @@ Chart.register(Filler);
|
||||||
// Create the Vue app
|
// Create the Vue app
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
|
// use i18n
|
||||||
|
app.use(i18n)
|
||||||
|
|
||||||
// Create and use Pinia store
|
// Create and use Pinia store
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
app.use(pinia);
|
app.use(pinia);
|
||||||
|
@ -24,4 +28,10 @@ app.mount("#app");
|
||||||
getRemote().then(() => {
|
getRemote().then(() => {
|
||||||
initConnections();
|
initConnections();
|
||||||
getModemState();
|
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;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,6 +12,7 @@ const defaultConfig = {
|
||||||
grid_layout: "[]",
|
grid_layout: "[]",
|
||||||
grid_preset: "[]",
|
grid_preset: "[]",
|
||||||
grid_enabled: true,
|
grid_enabled: true,
|
||||||
|
language:"en",
|
||||||
},
|
},
|
||||||
remote: {
|
remote: {
|
||||||
AUDIO: {
|
AUDIO: {
|
||||||
|
|
Loading…
Reference in New Issue