mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
add 'settings' store with action to mutate locales & add lazy loading of translations
This commit is contained in:
parent
d3f112ac06
commit
179511be17
7 changed files with 182 additions and 4 deletions
|
@ -68,16 +68,19 @@ import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
data: () => {
|
|
||||||
|
data () {
|
||||||
return {
|
return {
|
||||||
// isReady blocks the rendering of the rooter-view until we have a true info
|
// isReady blocks the rendering of the rooter-view until we have a true info
|
||||||
// about the connected state of the user.
|
// about the connected state of the user.
|
||||||
isReady: false
|
isReady: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['connected', 'yunohost'])
|
...mapGetters(['connected', 'yunohost'])
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async logout () {
|
async logout () {
|
||||||
this.$store.dispatch('LOGOUT').then(() => {
|
this.$store.dispatch('LOGOUT').then(() => {
|
||||||
|
@ -85,9 +88,14 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// This hook is only triggered at page reload so the value of state.connected
|
|
||||||
// always come from the localStorage
|
// This hook is only triggered at page first load
|
||||||
async created () {
|
async created () {
|
||||||
|
// Save user locales in store
|
||||||
|
const { locale, fallbackLocale } = this.$i18n
|
||||||
|
this.$store.dispatch('INIT_LOCALES', { locale, fallbackLocale })
|
||||||
|
|
||||||
|
// From this hook the value of `connected` always come from the localStorage.
|
||||||
if (!this.connected) {
|
if (!this.connected) {
|
||||||
// user is not connected: allow the login view to be rendered.
|
// user is not connected: allow the login view to be rendered.
|
||||||
this.isReady = true
|
this.isReady = true
|
||||||
|
|
64
app/src/i18n/helpers.js
Normal file
64
app/src/i18n/helpers.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
import i18n from '@/i18n'
|
||||||
|
import supportedLocales from './supportedLocales'
|
||||||
|
|
||||||
|
const loadedLanguages = []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the first two supported locales that can be found in the `localStorage` or
|
||||||
|
* in the user browser settings.
|
||||||
|
*
|
||||||
|
* @return {string[]}
|
||||||
|
*/
|
||||||
|
function getDefaultLocales () {
|
||||||
|
const locale = localStorage.getItem('locale')
|
||||||
|
const fallbackLocale = localStorage.getItem('fallbackLocale')
|
||||||
|
|
||||||
|
if (locale && fallbackLocale) return [locale, fallbackLocale]
|
||||||
|
|
||||||
|
const navigatorLocales = navigator.languages || [navigator.language]
|
||||||
|
const defaultLocales = []
|
||||||
|
const supported = Object.keys(supportedLocales)
|
||||||
|
for (const locale of navigatorLocales) {
|
||||||
|
if (supported.includes(locale) && !defaultLocales.includes(locale)) {
|
||||||
|
defaultLocales.push(locale)
|
||||||
|
} else {
|
||||||
|
const lang = locale.split('-')[0]
|
||||||
|
if (supported.includes(lang) && !defaultLocales.includes(lang)) {
|
||||||
|
defaultLocales.push(lang)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (defaultLocales.length === 2) break
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultLocales
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDocumentLocale (locale) {
|
||||||
|
document.documentElement.lang = locale
|
||||||
|
// FIXME can't currently change document direction easily since bootstrap still doesn't handle rtl.
|
||||||
|
// document.dir = locale === 'ar' ? 'rtl' : 'ltr'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a translation file and adds its content to the i18n plugin `messages`.
|
||||||
|
*
|
||||||
|
* @return {Promise<string>} Promise that resolve the given locale string
|
||||||
|
*/
|
||||||
|
function loadLocaleMessages (locale) {
|
||||||
|
if (loadedLanguages.includes(locale)) {
|
||||||
|
return Promise.resolve(locale)
|
||||||
|
}
|
||||||
|
return import(
|
||||||
|
/* webpackChunkName: "lang-[request]" */ `@/locales/${locale}.json`
|
||||||
|
).then(messages => {
|
||||||
|
i18n.setLocaleMessage(locale, messages.default)
|
||||||
|
loadedLanguages.push(locale)
|
||||||
|
return locale
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getDefaultLocales,
|
||||||
|
updateDocumentLocale,
|
||||||
|
loadLocaleMessages
|
||||||
|
}
|
25
app/src/i18n/index.js
Normal file
25
app/src/i18n/index.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
* i18n plugin module.
|
||||||
|
* @module i18n
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Vue from 'vue'
|
||||||
|
import VueI18n from 'vue-i18n'
|
||||||
|
import { getDefaultLocales, loadLocaleMessages } from './helpers'
|
||||||
|
|
||||||
|
// Plugin Initialization
|
||||||
|
Vue.use(VueI18n)
|
||||||
|
|
||||||
|
// Get defined locales from `localStorage` or `navigator`
|
||||||
|
const [locale, fallbackLocale] = getDefaultLocales()
|
||||||
|
|
||||||
|
export default new VueI18n({
|
||||||
|
locale,
|
||||||
|
fallbackLocale: fallbackLocale ? [fallbackLocale, 'en'] : ['en'],
|
||||||
|
messages: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Load default locales translations files
|
||||||
|
loadLocaleMessages(locale)
|
||||||
|
loadLocaleMessages(fallbackLocale)
|
||||||
|
loadLocaleMessages('en')
|
26
app/src/i18n/supportedLocales.js
Normal file
26
app/src/i18n/supportedLocales.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
export default {
|
||||||
|
ar: 'عربي',
|
||||||
|
bn_BD: 'বাংলা',
|
||||||
|
br: 'Brezhoneg',
|
||||||
|
ca: 'Català',
|
||||||
|
de: 'Deutsch',
|
||||||
|
el: 'Eλληνικά',
|
||||||
|
en: 'English',
|
||||||
|
eo: 'Esperanto',
|
||||||
|
es: 'Español',
|
||||||
|
eu: 'Euskara',
|
||||||
|
fr: 'Français',
|
||||||
|
hi: 'हिन्दी',
|
||||||
|
hu: 'Magyar',
|
||||||
|
it: 'Italiano',
|
||||||
|
nb_NO: 'Norsk bokmål',
|
||||||
|
ne: 'नेपाली',
|
||||||
|
nl: 'Nederlands',
|
||||||
|
oc: 'Occitan',
|
||||||
|
pl: 'Polski',
|
||||||
|
pt: 'Português',
|
||||||
|
ru: 'Русский',
|
||||||
|
sv: 'Svenska',
|
||||||
|
tr: 'Türkçe',
|
||||||
|
zh_Hans: '简化字'
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import './plugins/bootstrap-vue'
|
import './plugins/bootstrap-vue'
|
||||||
import i18n from './plugins/i18n'
|
import i18n from './i18n'
|
||||||
import router from './plugins/router'
|
import router from './plugins/router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
import info from './info'
|
import info from './info'
|
||||||
|
import settings from './settings'
|
||||||
import data from './data'
|
import data from './data'
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
@ -9,6 +10,7 @@ Vue.use(Vuex)
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
modules: {
|
modules: {
|
||||||
info,
|
info,
|
||||||
|
settings,
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
53
app/src/store/settings.js
Normal file
53
app/src/store/settings.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* Settings module store.
|
||||||
|
* @module store/settings
|
||||||
|
*/
|
||||||
|
|
||||||
|
import i18n from '@/i18n'
|
||||||
|
import { loadLocaleMessages, updateDocumentLocale } from '@/i18n/helpers'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state: {
|
||||||
|
locale: undefined,
|
||||||
|
fallbackLocale: undefined
|
||||||
|
},
|
||||||
|
|
||||||
|
mutations: {
|
||||||
|
'SET_LOCALE' (state, locale) {
|
||||||
|
localStorage.setItem('locale', locale)
|
||||||
|
state.locale = locale
|
||||||
|
},
|
||||||
|
|
||||||
|
'SET_FALLBACK_LOCALE' (state, locale) {
|
||||||
|
localStorage.setItem('fallbackLocale', locale)
|
||||||
|
state.fallbackLocale = locale
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
'UPDATE_LOCALE' ({ commit }, locale) {
|
||||||
|
loadLocaleMessages(locale).then(() => {
|
||||||
|
i18n.locale = locale
|
||||||
|
updateDocumentLocale(locale)
|
||||||
|
commit('SET_LOCALE', locale)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
'UPDATE_FALLBACK_LOCALE' ({ commit }, locale) {
|
||||||
|
loadLocaleMessages(locale).then(() => {
|
||||||
|
i18n.fallbackLocale = [locale, 'en']
|
||||||
|
commit('SET_FALLBACK_LOCALE', locale)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
'INIT_LOCALES' ({ commit }, { locale, fallbackLocale }) {
|
||||||
|
commit('SET_LOCALE', locale)
|
||||||
|
commit('SET_FALLBACK_LOCALE', fallbackLocale[0])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getters: {
|
||||||
|
locale: state => (state.locale),
|
||||||
|
fallbackLocale: state => (state.fallbackLocale)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue