From 005fb9055634c493460c203faddde067f5533c93 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Mon, 30 Nov 2020 17:57:08 +0100
Subject: [PATCH] Allow to pick language unlogged and format fallback messages

Closes #479

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 js/src/components/Footer.vue | 41 +++++++++++++++++++++++++++++++++++-
 js/src/utils/auth.ts         |  4 ++++
 js/src/utils/i18n.ts         | 11 +++++++---
 3 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/js/src/components/Footer.vue b/js/src/components/Footer.vue
index 657b4cae2..50d4eaf7f 100644
--- a/js/src/components/Footer.vue
+++ b/js/src/components/Footer.vue
@@ -2,6 +2,17 @@
   <footer class="footer" ref="footer">
     <img :src="`/img/pics/footer_${random}.jpg`" alt="" />
     <ul>
+      <li>
+        <b-select
+          v-if="$i18n"
+          v-model="locale"
+          :placeholder="$t('Select a language')"
+        >
+          <option v-for="(language, lang) in langs" :value="lang" :key="lang">
+            {{ language }}
+          </option>
+        </b-select>
+      </li>
       <li>
         <router-link :to="{ name: RouteName.ABOUT }">{{
           $t("About")
@@ -38,17 +49,40 @@
   </footer>
 </template>
 <script lang="ts">
-import { Component, Vue } from "vue-property-decorator";
+import { Component, Vue, Watch } from "vue-property-decorator";
+import { saveLocaleData } from "@/utils/auth";
+import { loadLanguageAsync } from "@/utils/i18n";
 import RouteName from "../router/name";
+import langs from "../i18n/langs.json";
 
 @Component
 export default class Footer extends Vue {
   RouteName = RouteName;
 
+  locale: string | null = this.$i18n.locale;
+
+  langs: Record<string, string> = langs;
+
   // eslint-disable-next-line class-methods-use-this
   get random(): number {
     return Math.floor(Math.random() * 4) + 1;
   }
+
+  @Watch("locale")
+  // eslint-disable-next-line class-methods-use-this
+  async updateLocale(locale: string): Promise<void> {
+    if (locale) {
+      await loadLanguageAsync(locale);
+      saveLocaleData(locale);
+    }
+  }
+
+  @Watch("$i18n.locale", { deep: true })
+  updateLocaleFromI18n(locale: string): void {
+    if (locale) {
+      this.locale = locale;
+    }
+  }
 }
 </script>
 <style lang="scss" scoped>
@@ -92,5 +126,10 @@ footer.footer {
     text-decoration: underline;
     text-decoration-color: $secondary;
   }
+
+  ::v-deep span.select select {
+    background: $background-color;
+    color: $white;
+  }
 }
 </style>
diff --git a/js/src/utils/auth.ts b/js/src/utils/auth.ts
index 4af15e4d5..52354432a 100644
--- a/js/src/utils/auth.ts
+++ b/js/src/utils/auth.ts
@@ -32,6 +32,10 @@ export function saveLocaleData(locale: string): void {
   localStorage.setItem(USER_LOCALE, locale);
 }
 
+export function getLocaleData(): string | null {
+  return localStorage.getItem(USER_LOCALE);
+}
+
 export function saveActorData(obj: IPerson): void {
   localStorage.setItem(AUTH_USER_ACTOR_ID, `${obj.id}`);
 }
diff --git a/js/src/utils/i18n.ts b/js/src/utils/i18n.ts
index e9a1c9f01..06f722087 100644
--- a/js/src/utils/i18n.ts
+++ b/js/src/utils/i18n.ts
@@ -1,26 +1,30 @@
 import Vue from "vue";
 import VueI18n from "vue-i18n";
 import { DateFnsPlugin } from "@/plugins/dateFns";
-import { USER_LOCALE } from "@/constants";
 import en from "../i18n/en_US.json";
 import langs from "../i18n/langs.json";
+import { getLocaleData } from "./auth";
 
 const DEFAULT_LOCALE = "en_US";
 
 let language =
-  localStorage.getItem(USER_LOCALE) ||
-  (document.documentElement.getAttribute("lang") as string);
+  getLocaleData() || (document.documentElement.getAttribute("lang") as string);
+console.log("lang1", language);
+
 language =
   language ||
   ((window.navigator as any).userLanguage || window.navigator.language).replace(
     /-/,
     "_"
   );
+console.log("language2", language);
+
 export const locale =
   language && Object.prototype.hasOwnProperty.call(langs, language)
     ? language
     : language.split("-")[0];
 
+console.log("lang3", locale);
 Vue.use(VueI18n);
 
 export const i18n = new VueI18n({
@@ -29,6 +33,7 @@ export const i18n = new VueI18n({
   // @ts-ignore
   messages: en, // set locale messages
   fallbackLocale: DEFAULT_LOCALE,
+  formatFallbackMessages: true,
 });
 
 const loadedLanguages = [DEFAULT_LOCALE];