diff --git a/bundles/org.openhab.ui/web/src/components/app.vue b/bundles/org.openhab.ui/web/src/components/app.vue index 9fe50bda2..025487b7c 100644 --- a/bundles/org.openhab.ui/web/src/components/app.vue +++ b/bundles/org.openhab.ui/web/src/components/app.vue @@ -407,17 +407,16 @@ export default { }) .then((rootResponse) => { // store the REST API services present on the system - this.$store.commit('setRootResource', { rootResponse }) + this.$store.dispatch('loadRootResource', { rootResponse }) this.updateLocale() if (!this.$store.getters.apiEndpoint('auth')) this.$store.commit('setNoAuth', true) return rootResponse }).then((rootResponse) => { - let locale = this.$store.state.locale + const locale = this.$store.getters.locale.toLocaleLowerCase() let dayjsLocalePromise = Promise.resolve(null) // try to resolve the dayjs file to load if it exists if (locale) { - let dayjsLocale = dayjsLocales.find((l) => l.key === locale.replace('_', '-').toLowerCase()) - if (!dayjsLocale) dayjsLocale = dayjsLocales.find((l) => l.key === locale.split('_')[0].toLowerCase()) + const dayjsLocale = dayjsLocales.find((l) => l.key === locale || l.key === locale.split('-')[0]) dayjsLocalePromise = (dayjsLocale) ? import('dayjs/locale/' + dayjsLocale.key + '.js').then(() => Promise.resolve(dayjsLocale)) : Promise.resolve(null) } // load the pages & widgets, only if the 'ui' endpoint exists (or empty arrays otherwise) diff --git a/bundles/org.openhab.ui/web/src/components/i18n-mixin.js b/bundles/org.openhab.ui/web/src/components/i18n-mixin.js index 779b6d6c9..26abd73bb 100644 --- a/bundles/org.openhab.ui/web/src/components/i18n-mixin.js +++ b/bundles/org.openhab.ui/web/src/components/i18n-mixin.js @@ -1,7 +1,7 @@ export default { methods: { updateLocale () { - this.$root.$i18n.locale = this.$store.state.locale.replace('_', '-') + this.$root.$i18n.locale = this.$store.getters.locale this.$f7.params.dialog.buttonOk = this.$t('dialogs.ok') this.$f7.params.dialog.buttonCancel = this.$t('dialogs.cancel') this.$f7.params.smartSelect.searchbarDisableText = this.$t('dialogs.cancel') diff --git a/bundles/org.openhab.ui/web/src/js/i18n.js b/bundles/org.openhab.ui/web/src/js/i18n.js index 37c46686b..d7f258965 100644 --- a/bundles/org.openhab.ui/web/src/js/i18n.js +++ b/bundles/org.openhab.ui/web/src/js/i18n.js @@ -22,3 +22,47 @@ export default new VueI18n({ fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en', messages: loadLocaleMessages(require.context('@/assets/i18n/common')) }) + +export function isLocaleSupported (locale) { + try { + new Date().toLocaleDateString(locale) + } catch (e) { + return false + } + return true +} + +export function convertJavaLocale (locale) { + if (!locale) { + return 'default' + } + + let language = '' + let script = '' + let region = '' + + // determine country, language and script + locale.split('_').forEach(segment => { + if (segment === segment.toLowerCase() && segment.length === 2) { + language = segment + } else if (segment === segment.toUpperCase() && segment.length === 2) { + region = segment + } else if (segment.charAt(0) === '#') { + script = segment.substring(1) + } + }) + + if (language && script && region) { + const jsLocale = `${language}-${script}-${region}` + if (isLocaleSupported(jsLocale)) { + return jsLocale + } + } else if (language && region) { + const jsLocale = `${language}-${region}` + if (isLocaleSupported(jsLocale)) { + return jsLocale + } + } + + return 'default' +} diff --git a/bundles/org.openhab.ui/web/src/js/store/index.js b/bundles/org.openhab.ui/web/src/js/store/index.js index 805570406..104daf156 100644 --- a/bundles/org.openhab.ui/web/src/js/store/index.js +++ b/bundles/org.openhab.ui/web/src/js/store/index.js @@ -4,6 +4,7 @@ import Vuex from 'vuex' import components from './modules/components' import states from './modules/states' import user from './modules/user' +import { convertJavaLocale } from '@/js/i18n' Vue.use(Vuex) @@ -23,12 +24,12 @@ const store = new Vuex.Store({ developerSidebar: false }, getters: { - apiEndpoint: (state) => (type) => (!state.apiEndpoints) ? null : state.apiEndpoints.find((e) => e.type === type) + apiEndpoint: (state) => (type) => (!state.apiEndpoints) ? null : state.apiEndpoints.find((e) => e.type === type), + locale: (state, getters) => state.locale ?? 'default' }, mutations: { setRootResource (state, { rootResponse }) { state.apiVersion = rootResponse.version - state.locale = rootResponse.locale state.runtimeInfo = rootResponse.runtimeInfo state.apiEndpoints = rootResponse.links }, @@ -39,6 +40,12 @@ const store = new Vuex.Store({ state.developerSidebar = value state.states.keepConnectionOpen = value } + }, + actions: { + loadRootResource ({ commit }, { rootResponse }) { + commit('setLocale', convertJavaLocale(rootResponse.locale)) + commit('setRootResource', { rootResponse }) + } } // strict: debug }) diff --git a/bundles/org.openhab.ui/web/src/pages/about.vue b/bundles/org.openhab.ui/web/src/pages/about.vue index 986f24e42..5cf53ff00 100644 --- a/bundles/org.openhab.ui/web/src/pages/about.vue +++ b/bundles/org.openhab.ui/web/src/pages/about.vue @@ -117,7 +117,7 @@ export default { if (!this.textualSystemInfoOpened) return '' return YAML.stringify({ runtimeInfo: this.$store.state.runtimeInfo, - locale: this.$store.state.locale, + locale: this.$store.getters.locale, systemInfo: this.systemInfo, bindings: this.bindings, clientInfo: { diff --git a/bundles/org.openhab.ui/web/src/pages/home.vue b/bundles/org.openhab.ui/web/src/pages/home.vue index 433ca6dc6..29799762c 100644 --- a/bundles/org.openhab.ui/web/src/pages/home.vue +++ b/bundles/org.openhab.ui/web/src/pages/home.vue @@ -5,7 +5,7 @@ - {{new Date().toLocaleString(($store.state.locale) ? $store.state.locale.replace('_', '-') : 'default', { weekday: 'long', day: 'numeric', month: 'long' }) }} + {{ new Date().toLocaleString($store.getters.locale, { weekday: 'long', day: 'numeric', month: 'long' }) }} {{title}} diff --git a/bundles/org.openhab.ui/web/src/pages/profile.vue b/bundles/org.openhab.ui/web/src/pages/profile.vue index f0fd467ad..5c762d964 100644 --- a/bundles/org.openhab.ui/web/src/pages/profile.vue +++ b/bundles/org.openhab.ui/web/src/pages/profile.vue @@ -37,8 +37,8 @@ v-for="session in sessions" :key="session.sessionId" :title="session.clientId" - :subtitle="$t('profile.sessions.created') + new Date(session.createdTime).toLocaleString($store.state.locale ? $store.state.locale.replace('_', '-') : 'default')" - :text="$t('profile.sessions.lastRefreshed') + new Date(session.lastRefreshTime).toLocaleString($store.state.locale ? $store.state.locale.replace('_', '-') : 'default')" + :subtitle="$t('profile.sessions.created') + new Date(session.createdTime).toLocaleString($store.getters.locale)" + :text="$t('profile.sessions.lastRefreshed') + new Date(session.lastRefreshTime).toLocaleString($store.getters.locale)" > @@ -63,7 +63,7 @@ v-for="apiToken in apiTokens" :key="apiToken.name" :title="apiToken.name" - :subtitle="$t('profile.apiTokens.created') + new Date(apiToken.createdTime).toLocaleString($store.state.locale ? $store.state.locale.replace('_', '-') : 'default')" + :subtitle="$t('profile.apiTokens.created') + new Date(apiToken.createdTime).toLocaleString($store.getters.locale)" :text="$t('profile.apiTokens.validForScope') + (apiToken.scope || 'N/A')" >