From ba68246e0d6fb10f36563b6cb9e37115685a8680 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Wed, 19 Dec 2018 21:45:12 +0100
Subject: [PATCH] Load translations separately to reduce bandwidth usage

---
 .gitignore                      |  1 +
 front/package.json              |  5 +++--
 front/scripts/i18n-compile.sh   |  8 ++++++--
 front/src/App.vue               |  5 ++---
 front/src/components/Footer.vue | 11 ++++++++++-
 front/src/main.js               |  3 +--
 front/vue.config.js             |  6 ++++++
 front/yarn.lock                 | 21 ++++++++++++++++++++-
 8 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/.gitignore b/.gitignore
index 44459f0f8a..e62b1ce620 100644
--- a/.gitignore
+++ b/.gitignore
@@ -93,5 +93,6 @@ po/*.po
 docs/swagger
 _build
 front/src/translations.json
+front/src/translations/*.json
 front/locales/en_US/LC_MESSAGES/app.po
 *.prof
diff --git a/front/package.json b/front/package.json
index 23894600e8..61a80bee84 100644
--- a/front/package.json
+++ b/front/package.json
@@ -3,7 +3,7 @@
   "version": "0.1.0",
   "private": true,
   "scripts": {
-    "serve": "scripts/i18n-compile.sh && vue-cli-service serve --port ${VUE_PORT:-8000} --host ${VUE_HOST:-0.0.0.0}",
+    "serve": "vue-cli-service serve --port ${VUE_PORT:-8000} --host ${VUE_HOST:-0.0.0.0}",
     "build": "scripts/i18n-compile.sh && vue-cli-service build",
     "lint": "vue-cli-service lint",
     "i18n-extract": "scripts/i18n-extract.sh",
@@ -49,7 +49,8 @@
     "node-sass": "^4.9.3",
     "sass-loader": "^7.1.0",
     "sinon": "^6.1.5",
-    "vue-template-compiler": "^2.5.17"
+    "vue-template-compiler": "^2.5.17",
+    "webpack-bundle-size-analyzer": "^3.0.0"
   },
   "eslintConfig": {
     "root": true,
diff --git a/front/scripts/i18n-compile.sh b/front/scripts/i18n-compile.sh
index 955913393f..a5713df833 100755
--- a/front/scripts/i18n-compile.sh
+++ b/front/scripts/i18n-compile.sh
@@ -1,3 +1,7 @@
 #!/bin/bash -eux
-locales=$(tail -n +2 src/locales.js | sed -e 's/export default //' | jq '.locales[].code' | xargs echo)
-find locales -name '*.po' | xargs $(yarn bin)/gettext-compile --output src/translations.json
+locales=$(tail -n +2 src/locales.js | sed -e 's/export default //' | jq '.locales[].code' | grep -v 'en_US' | xargs echo)
+for locale in $locales; do
+    find "locales/$locale" -name '*.po' | $(yarn bin)/gettext-compile locales/$locale/LC_MESSAGES/app.po --output src/translations/$locale.json
+done
+
+# find locales -name '*.po' | xargs $(yarn bin)/gettext-compile --output src/translations.json
diff --git a/front/src/App.vue b/front/src/App.vue
index 6e6f45ff62..39e80f7846 100644
--- a/front/src/App.vue
+++ b/front/src/App.vue
@@ -61,13 +61,12 @@ import {mapState} from 'vuex'
 import { WebSocketBridge } from 'django-channels'
 import GlobalEvents from '@/components/utils/global-events'
 
-import translations from '@/translations'
-
 import Sidebar from '@/components/Sidebar'
 import AppFooter from '@/components/Footer'
 import Raven from '@/components/Raven'
 import ServiceMessages from '@/components/ServiceMessages'
 
+import locales from './locales'
 import PlaylistModal from '@/components/playlists/PlaylistModal'
 import ShortcutsModal from '@/components/ShortcutsModal'
 
@@ -139,7 +138,7 @@ export default {
     },
     autodetectLanguage () {
       let userLanguage = navigator.language || navigator.userLanguage
-      let available = _.keys(translations)
+      let available = locales.locales.map(e => { return e.code })
       let matching = available.filter((a) => {
         return userLanguage.replace('-', '_') === a
       })
diff --git a/front/src/components/Footer.vue b/front/src/components/Footer.vue
index e0fa2d4bb7..a0543e1e34 100644
--- a/front/src/components/Footer.vue
+++ b/front/src/components/Footer.vue
@@ -20,7 +20,7 @@
           <div class="ui form">
             <div class="ui field">
               <label><translate>Change language</translate></label>
-              <select class="ui dropdown" v-model="$language.current">
+              <select class="ui dropdown" :value="$language.current" @change="updateLanguage($event.target.value)">
                 <option v-for="(language, key) in $language.available" :key="key" :value="key">{{ language }}</option>
               </select>
             </div>
@@ -60,7 +60,9 @@
 </template>
 
 <script>
+import Vue from "vue"
 import { mapState } from "vuex"
+import axios from 'axios'
 
 export default {
   props: ["version"],
@@ -74,6 +76,13 @@ export default {
       if (confirm) {
         this.$store.commit("instance/instanceUrl", null)
       }
+    },
+    updateLanguage(value) {
+      let self = this
+      import(`../translations/${value}.json`).then((response) =>{
+        Vue.$translations[value] = response.default[value]
+        self.$language.current = value
+      })
     }
   },
   computed: {
diff --git a/front/src/main.js b/front/src/main.js
index eca2e62054..7390a69987 100644
--- a/front/src/main.js
+++ b/front/src/main.js
@@ -14,7 +14,6 @@ import VueLazyload from 'vue-lazyload'
 import store from './store'
 import GetTextPlugin from 'vue-gettext'
 import { sync } from 'vuex-router-sync'
-import translations from './translations.json'
 import locales from '@/locales'
 
 import filters from '@/filters' // eslint-disable-line
@@ -54,7 +53,7 @@ Vue.use(GetTextPlugin, {
       }
     }
   },
-  translations: translations,
+  translations: {},
   silent: true
 })
 
diff --git a/front/vue.config.js b/front/vue.config.js
index c689342465..69bfdc34ea 100644
--- a/front/vue.config.js
+++ b/front/vue.config.js
@@ -1,4 +1,9 @@
 
+const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
+let plugins = []
+if (process.env.BUNDLE_ANALYZE === '1') {
+  plugins.push(new BundleAnalyzerPlugin())
+}
 module.exports = {
   baseUrl: '/front/',
   pages: {
@@ -17,6 +22,7 @@ module.exports = {
     config.optimization.delete('splitChunks')
   },
   configureWebpack: {
+    plugins: plugins,
     resolve: {
       alias: {
         'vue$': 'vue/dist/vue.esm.js'
diff --git a/front/yarn.lock b/front/yarn.lock
index e1b637c732..7377b3816b 100644
--- a/front/yarn.lock
+++ b/front/yarn.lock
@@ -2040,6 +2040,11 @@ commander@^2.13.0:
   version "2.17.1"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
 
+commander@^2.19.0:
+  version "2.19.0"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
+  integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
+
 commander@~2.13.0:
   version "2.13.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
@@ -3274,7 +3279,7 @@ filename-regex@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
 
-filesize@^3.5.11:
+filesize@^3.5.11, filesize@^3.6.1:
   version "3.6.1"
   resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317"
 
@@ -3900,6 +3905,11 @@ https-browserify@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
 
+humanize@0.0.9:
+  version "0.0.9"
+  resolved "https://registry.yarnpkg.com/humanize/-/humanize-0.0.9.tgz#1994ffaecdfe9c441ed2bdac7452b7bb4c9e41a4"
+  integrity sha1-GZT/rs3+nEQe0r2sdFK3u0yeQaQ=
+
 iconv-lite@0.4.19:
   version "0.4.19"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
@@ -7823,6 +7833,15 @@ webpack-bundle-analyzer@^2.13.1:
     opener "^1.4.3"
     ws "^4.0.0"
 
+webpack-bundle-size-analyzer@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/webpack-bundle-size-analyzer/-/webpack-bundle-size-analyzer-3.0.0.tgz#c0657e9787cf644a0b91d891ae15553ba61bbc71"
+  integrity sha512-GfQ/Mch1o2MGonGPIMawwlxXOmYp/F8EXiT9txDO6qASo7G5hODngWMNW1KkJxeYRvgMUuPgbSsmdsXEsBNEeg==
+  dependencies:
+    commander "^2.19.0"
+    filesize "^3.6.1"
+    humanize "0.0.9"
+
 webpack-chain@^4.8.0:
   version "4.8.0"
   resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-4.8.0.tgz#06fc3dbb9f2707d4c9e899fc6250fbcf2afe6fd1"
-- 
GitLab