From c1e4bfa90ffa26e203ca61717b4fb99209ad0d99 Mon Sep 17 00:00:00 2001 From: Ekaterina Vaartis Date: Sat, 25 Aug 2018 13:12:33 +0300 Subject: [PATCH] Make interface language configurable from settings The locale can now be configured in settings and is stored in Vuex. The changes are applied immidiately after selection. The list of languages is taken from the messages file, which contains all the available locales (and a new value, `interfaceLanguage`, to control the translation of this option in the options menu) Closes #36 --- package.json | 1 + src/App.js | 4 ++ .../interface_language_switcher.vue | 38 +++++++++++++++++++ src/components/settings/settings.js | 4 +- src/components/settings/settings.vue | 4 ++ src/i18n/messages.js | 6 ++- src/main.js | 3 +- src/modules/config.js | 5 ++- yarn.lock | 4 ++ 9 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 src/components/interface_language_switcher/interface_language_switcher.vue diff --git a/package.json b/package.json index 5718d24ddb..652557150f 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "html-webpack-plugin": "^2.8.1", "http-proxy-middleware": "^0.17.2", "inject-loader": "^2.0.1", + "iso-639-1": "^2.0.3", "isparta-loader": "^2.0.0", "json-loader": "^0.5.4", "karma": "^1.3.0", diff --git a/src/App.js b/src/App.js index 39c97a80d0..a9a46fadbb 100644 --- a/src/App.js +++ b/src/App.js @@ -20,6 +20,10 @@ export default { data: () => ({ mobileActivePanel: 'timeline' }), + created () { + // Load the locale from the storage + this.$i18n.locale = this.$store.state.config.interfaceLanguage + }, computed: { currentUser () { return this.$store.state.users.currentUser }, background () { diff --git a/src/components/interface_language_switcher/interface_language_switcher.vue b/src/components/interface_language_switcher/interface_language_switcher.vue new file mode 100644 index 0000000000..4b54188857 --- /dev/null +++ b/src/components/interface_language_switcher/interface_language_switcher.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js index d5ca33cc1d..f8eaad0051 100644 --- a/src/components/settings/settings.js +++ b/src/components/settings/settings.js @@ -1,5 +1,6 @@ /* eslint-env browser */ import StyleSwitcher from '../style_switcher/style_switcher.vue' +import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue' import { filter, trim } from 'lodash' const settings = { @@ -28,7 +29,8 @@ const settings = { } }, components: { - StyleSwitcher + StyleSwitcher, + InterfaceLanguageSwitcher }, computed: { user () { diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index 9612876e44..f500a1b0b9 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -84,6 +84,10 @@ +
+

{{ $t('settings.interfaceLanguage') }}

+ +
diff --git a/src/i18n/messages.js b/src/i18n/messages.js index a0b7f56295..48b1389abf 100644 --- a/src/i18n/messages.js +++ b/src/i18n/messages.js @@ -350,7 +350,8 @@ const en = { default_vis: 'Default visibility scope', profile_tab: 'Profile', security_tab: 'Security', - data_import_export_tab: 'Data Import / Export' + data_import_export_tab: 'Data Import / Export', + interfaceLanguage: 'Interface language' }, notifications: { notifications: 'Notifications', @@ -1689,7 +1690,8 @@ const ru = { profile_tab: 'Профиль', security_tab: 'Безопасность', data_import_export_tab: 'Импорт / Экспорт данных', - collapse_subject: 'Сворачивать посты с темой' + collapse_subject: 'Сворачивать посты с темой', + interfaceLanguage: 'Язык интерфейса' }, notifications: { notifications: 'Уведомления', diff --git a/src/main.js b/src/main.js index 87dc49dfd3..37ef49f7fd 100644 --- a/src/main.js +++ b/src/main.js @@ -60,6 +60,7 @@ const persistedStateOptions = { 'config.loopVideoSilentOnly', 'config.pauseOnUnfocused', 'config.stopGifs', + 'config.interfaceLanguage', 'users.lastLoginName', 'statuses.notifications.maxSavedId' ] @@ -79,6 +80,7 @@ const store = new Vuex.Store({ }) const i18n = new VueI18n({ + // By default, use the browser locale, we will update it if neccessary locale: currentLocale, fallbackLocale: 'en', messages @@ -201,4 +203,3 @@ window.fetch('/nodeinfo/2.0.json') store.dispatch('setOption', { name: 'suggestionsEnabled', value: suggestions.enabled }) store.dispatch('setOption', { name: 'suggestionsWeb', value: suggestions.web }) }) - diff --git a/src/modules/config.js b/src/modules/config.js index 45bb1465c0..ac163316e1 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -1,6 +1,8 @@ import { set, delete as del } from 'vue' import StyleSetter from '../services/style_setter/style_setter.js' +const browserLocale = (window.navigator.language || 'en').split('-')[0] + const defaultState = { name: 'Pleroma FE', colors: {}, @@ -17,7 +19,8 @@ const defaultState = { stopGifs: false, replyVisibility: 'all', muteWords: [], - highlight: {} + highlight: {}, + interfaceLanguage: browserLocale } const config = { diff --git a/yarn.lock b/yarn.lock index 390ad70b3e..2be9efc87a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3081,6 +3081,10 @@ isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" +iso-639-1@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.0.3.tgz#72dd3448ac5629c271628c5ac566369428d6ccd0" + isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"