Allow to pick language unlogged and format fallback messages
Closes #479 Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
2141f92a30
commit
005fb90556
|
@ -2,6 +2,17 @@
|
||||||
<footer class="footer" ref="footer">
|
<footer class="footer" ref="footer">
|
||||||
<img :src="`/img/pics/footer_${random}.jpg`" alt="" />
|
<img :src="`/img/pics/footer_${random}.jpg`" alt="" />
|
||||||
<ul>
|
<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>
|
<li>
|
||||||
<router-link :to="{ name: RouteName.ABOUT }">{{
|
<router-link :to="{ name: RouteName.ABOUT }">{{
|
||||||
$t("About")
|
$t("About")
|
||||||
|
@ -38,17 +49,40 @@
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<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 RouteName from "../router/name";
|
||||||
|
import langs from "../i18n/langs.json";
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class Footer extends Vue {
|
export default class Footer extends Vue {
|
||||||
RouteName = RouteName;
|
RouteName = RouteName;
|
||||||
|
|
||||||
|
locale: string | null = this.$i18n.locale;
|
||||||
|
|
||||||
|
langs: Record<string, string> = langs;
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
get random(): number {
|
get random(): number {
|
||||||
return Math.floor(Math.random() * 4) + 1;
|
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>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -92,5 +126,10 @@ footer.footer {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
text-decoration-color: $secondary;
|
text-decoration-color: $secondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::v-deep span.select select {
|
||||||
|
background: $background-color;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -32,6 +32,10 @@ export function saveLocaleData(locale: string): void {
|
||||||
localStorage.setItem(USER_LOCALE, locale);
|
localStorage.setItem(USER_LOCALE, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLocaleData(): string | null {
|
||||||
|
return localStorage.getItem(USER_LOCALE);
|
||||||
|
}
|
||||||
|
|
||||||
export function saveActorData(obj: IPerson): void {
|
export function saveActorData(obj: IPerson): void {
|
||||||
localStorage.setItem(AUTH_USER_ACTOR_ID, `${obj.id}`);
|
localStorage.setItem(AUTH_USER_ACTOR_ID, `${obj.id}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,30 @@
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import VueI18n from "vue-i18n";
|
import VueI18n from "vue-i18n";
|
||||||
import { DateFnsPlugin } from "@/plugins/dateFns";
|
import { DateFnsPlugin } from "@/plugins/dateFns";
|
||||||
import { USER_LOCALE } from "@/constants";
|
|
||||||
import en from "../i18n/en_US.json";
|
import en from "../i18n/en_US.json";
|
||||||
import langs from "../i18n/langs.json";
|
import langs from "../i18n/langs.json";
|
||||||
|
import { getLocaleData } from "./auth";
|
||||||
|
|
||||||
const DEFAULT_LOCALE = "en_US";
|
const DEFAULT_LOCALE = "en_US";
|
||||||
|
|
||||||
let language =
|
let language =
|
||||||
localStorage.getItem(USER_LOCALE) ||
|
getLocaleData() || (document.documentElement.getAttribute("lang") as string);
|
||||||
(document.documentElement.getAttribute("lang") as string);
|
console.log("lang1", language);
|
||||||
|
|
||||||
language =
|
language =
|
||||||
language ||
|
language ||
|
||||||
((window.navigator as any).userLanguage || window.navigator.language).replace(
|
((window.navigator as any).userLanguage || window.navigator.language).replace(
|
||||||
/-/,
|
/-/,
|
||||||
"_"
|
"_"
|
||||||
);
|
);
|
||||||
|
console.log("language2", language);
|
||||||
|
|
||||||
export const locale =
|
export const locale =
|
||||||
language && Object.prototype.hasOwnProperty.call(langs, language)
|
language && Object.prototype.hasOwnProperty.call(langs, language)
|
||||||
? language
|
? language
|
||||||
: language.split("-")[0];
|
: language.split("-")[0];
|
||||||
|
|
||||||
|
console.log("lang3", locale);
|
||||||
Vue.use(VueI18n);
|
Vue.use(VueI18n);
|
||||||
|
|
||||||
export const i18n = new VueI18n({
|
export const i18n = new VueI18n({
|
||||||
|
@ -29,6 +33,7 @@ export const i18n = new VueI18n({
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
messages: en, // set locale messages
|
messages: en, // set locale messages
|
||||||
fallbackLocale: DEFAULT_LOCALE,
|
fallbackLocale: DEFAULT_LOCALE,
|
||||||
|
formatFallbackMessages: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadedLanguages = [DEFAULT_LOCALE];
|
const loadedLanguages = [DEFAULT_LOCALE];
|
||||||
|
|
Loading…
Reference in a new issue