From 99eaec85478f384ddb0ea45a9d9c95c4dce646f5 Mon Sep 17 00:00:00 2001
From: lain <lain@soykaf.club>
Date: Mon, 8 Jun 2020 17:22:07 +0200
Subject: [PATCH] Messages: Load languages asynchronously.

Reduces the size of the initial app bundle by about half.
---
 src/App.js                                    |  3 +-
 .../interface_language_switcher.vue           |  3 +-
 src/i18n/messages.js                          | 95 +++++++++++++------
 src/main.js                                   |  6 +-
 src/modules/config.js                         |  5 +
 5 files changed, 80 insertions(+), 32 deletions(-)

diff --git a/src/App.js b/src/App.js
index 6445335ad..040138c97 100644
--- a/src/App.js
+++ b/src/App.js
@@ -47,7 +47,8 @@ export default {
   }),
   created () {
     // Load the locale from the storage
-    this.$i18n.locale = this.$store.getters.mergedConfig.interfaceLanguage
+    const val = this.$store.getters.mergedConfig.interfaceLanguage
+    this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
     window.addEventListener('resize', this.updateMobileState)
   },
   destroyed () {
diff --git a/src/components/interface_language_switcher/interface_language_switcher.vue b/src/components/interface_language_switcher/interface_language_switcher.vue
index f5ace0cce..dd6800a30 100644
--- a/src/components/interface_language_switcher/interface_language_switcher.vue
+++ b/src/components/interface_language_switcher/interface_language_switcher.vue
@@ -32,7 +32,7 @@ import _ from 'lodash'
 export default {
   computed: {
     languageCodes () {
-      return Object.keys(languagesObject)
+      return languagesObject.languages
     },
 
     languageNames () {
@@ -43,7 +43,6 @@ export default {
       get: function () { return this.$store.getters.mergedConfig.interfaceLanguage },
       set: function (val) {
         this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
-        this.$i18n.locale = val
       }
     }
   },
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index c56ae205a..a257486f6 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -7,34 +7,75 @@
 // sed -i -e "s/'//gm" -e 's/"/\\"/gm' -re 's/^( +)(.+?): ((.+?))?(,?)(\{?)$/\1"\2": "\4"/gm' -e 's/\"\{\"/{/g' -e 's/,"$/",/g' file.json
 // There's only problem that apostrophe character ' gets replaced by \\ so you have to fix it manually, sorry.
 
+const loaders = {
+  ar: () => import('./ar.json'),
+  ca: () => import('./ca.json'),
+  cs: () => import('./cs.json'),
+  de: () => import('./de.json'),
+  eo: () => import('./eo.json'),
+  es: () => import('./es.json'),
+  et: () => import('./et.json'),
+  eu: () => import('./eu.json'),
+  fi: () => import('./fi.json'),
+  fr: () => import('./fr.json'),
+  ga: () => import('./ga.json'),
+  he: () => import('./he.json'),
+  hu: () => import('./hu.json'),
+  it: () => import('./it.json'),
+  ja: () => import('./ja_pedantic.json'),
+  ja_easy: () => import('./ja_easy.json'),
+  ko: () => import('./ko.json'),
+  nb: () => import('./nb.json'),
+  nl: () => import('./nl.json'),
+  oc: () => import('./oc.json'),
+  pl: () => import('./pl.json'),
+  pt: () => import('./pt.json'),
+  ro: () => import('./ro.json'),
+  ru: () => import('./ru.json'),
+  te: () => import('./te.json'),
+  zh: () => import('./zh.json')
+}
+
 const messages = {
-  ar: require('./ar.json'),
-  ca: require('./ca.json'),
-  cs: require('./cs.json'),
-  de: require('./de.json'),
-  en: require('./en.json'),
-  eo: require('./eo.json'),
-  es: require('./es.json'),
-  et: require('./et.json'),
-  eu: require('./eu.json'),
-  fi: require('./fi.json'),
-  fr: require('./fr.json'),
-  ga: require('./ga.json'),
-  he: require('./he.json'),
-  hu: require('./hu.json'),
-  it: require('./it.json'),
-  ja: require('./ja_pedantic.json'),
-  ja_easy: require('./ja_easy.json'),
-  ko: require('./ko.json'),
-  nb: require('./nb.json'),
-  nl: require('./nl.json'),
-  oc: require('./oc.json'),
-  pl: require('./pl.json'),
-  pt: require('./pt.json'),
-  ro: require('./ro.json'),
-  ru: require('./ru.json'),
-  te: require('./te.json'),
-  zh: require('./zh.json')
+  languages: [
+    'ar',
+    'ca',
+    'cs',
+    'de',
+    'en',
+    'eo',
+    'es',
+    'et',
+    'eu',
+    'fi',
+    'fr',
+    'ga',
+    'he',
+    'hu',
+    'it',
+    'ja',
+    'ja_easy',
+    'ko',
+    'nb',
+    'nl',
+    'oc',
+    'pl',
+    'pt',
+    'ro',
+    'ru',
+    'te',
+    'zh'
+  ],
+  default: {
+    en: require('./en.json')
+  },
+  setLanguage: async (i18n, language) => {
+    if (loaders[language]) {
+      let messages = await loaders[language]()
+      i18n.setLocaleMessage(language, messages)
+    }
+    i18n.locale = language
+  }
 }
 
 export default messages
diff --git a/src/main.js b/src/main.js
index be4213fa9..9a201e4fa 100644
--- a/src/main.js
+++ b/src/main.js
@@ -46,11 +46,13 @@ Vue.use(VBodyScrollLock)
 
 const i18n = new VueI18n({
   // By default, use the browser locale, we will update it if neccessary
-  locale: currentLocale,
+  locale: 'en',
   fallbackLocale: 'en',
-  messages
+  messages: messages.default
 })
 
+messages.setLanguage(i18n, currentLocale)
+
 const persistedStateOptions = {
   paths: [
     'config',
diff --git a/src/modules/config.js b/src/modules/config.js
index b6b1b2418..47b24d772 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -1,5 +1,6 @@
 import { set, delete as del } from 'vue'
 import { setPreset, applyTheme } from '../services/style_setter/style_setter.js'
+import messages from '../i18n/messages'
 
 const browserLocale = (window.navigator.language || 'en').split('-')[0]
 
@@ -115,6 +116,10 @@ const config = {
         case 'customTheme':
         case 'customThemeSource':
           applyTheme(value)
+          break
+        case 'interfaceLanguage':
+          messages.setLanguage(this.getters.i18n, value)
+          break
       }
     }
   }
-- 
GitLab