Fix fallback locale

This commit is contained in:
wvffle 2022-11-24 21:45:24 +00:00 committed by Kasper Seweryn
parent a218e11de1
commit 5847a23ac3
6 changed files with 53 additions and 22 deletions

View File

@ -47,6 +47,7 @@
"universal-cookie": "4.0.4", "universal-cookie": "4.0.4",
"vue": "3.2.45", "vue": "3.2.45",
"vue-gettext": "2.1.12", "vue-gettext": "2.1.12",
"vue-i18n": "9",
"vue-router": "4.1.6", "vue-router": "4.1.6",
"vue-upload-component": "3.1.6", "vue-upload-component": "3.1.6",
"vue-virtual-scroller": "2.0.0-beta.3", "vue-virtual-scroller": "2.0.0-beta.3",
@ -59,7 +60,7 @@
}, },
"devDependencies": { "devDependencies": {
"@intlify/eslint-plugin-vue-i18n": "^2.0.0", "@intlify/eslint-plugin-vue-i18n": "^2.0.0",
"@intlify/vite-plugin-vue-i18n": "^6.0.1", "@intlify/vite-plugin-vue-i18n": "^6.0.3",
"@types/diff": "5.0.2", "@types/diff": "5.0.2",
"@types/dompurify": "2.4.0", "@types/dompurify": "2.4.0",
"@types/howler": "2.2.7", "@types/howler": "2.2.7",

View File

@ -2,7 +2,7 @@
import type { RouteRecordName } from 'vue-router' import type { RouteRecordName } from 'vue-router'
import { computed, ref, watch, watchEffect, onMounted } from 'vue' import { computed, ref, watch, watchEffect, onMounted } from 'vue'
import { SUPPORTED_LOCALES } from '~/init/locale' import { setI18nLanguage, SUPPORTED_LOCALES } from '~/init/locale'
import { useCurrentElement } from '@vueuse/core' import { useCurrentElement } from '@vueuse/core'
import { setupDropdown } from '~/utils/fomantic' import { setupDropdown } from '~/utils/fomantic'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
@ -32,7 +32,7 @@ defineProps<Props>()
const store = useStore() const store = useStore()
const { theme } = useTheme() const { theme } = useTheme()
const themes = useThemeList() const themes = useThemeList()
const { t } = useI18n() const { t, locale: i18nLocale } = useI18n()
const route = useRoute() const route = useRoute()
const isCollapsed = ref(true) const isCollapsed = ref(true)
@ -101,9 +101,14 @@ const moderationNotifications = computed(() =>
+ store.state.ui.notifications.pendingReviewRequests + store.state.ui.notifications.pendingReviewRequests
) )
const showLanguageModal = ref(false)
const locale = ref(i18nLocale.value)
watch(locale, (locale) => {
// setI18nLanguage(locale)
})
const isProduction = import.meta.env.PROD const isProduction = import.meta.env.PROD
const showUserModal = ref(false) const showUserModal = ref(false)
const showLanguageModal = ref(false)
const showThemeModal = ref(false) const showThemeModal = ref(false)
const el = useCurrentElement() const el = useCurrentElement()
@ -291,7 +296,7 @@ onMounted(() => {
> >
<input <input
:id="`${key}`" :id="`${key}`"
v-model="$i18n.locale" v-model="locale"
type="radio" type="radio"
name="language" name="language"
:value="key" :value="key"

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { SUPPORTED_LOCALES } from '~/init/locale' import { SUPPORTED_LOCALES, setI18nLanguage } from '~/init/locale'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { computed } from 'vue' import { computed } from 'vue'
@ -50,7 +50,7 @@ const labels = computed(() => ({
:key="key" :key="key"
:class="[{'active': $i18n.locale === key},'item']" :class="[{'active': $i18n.locale === key},'item']"
:value="key" :value="key"
@click="$i18n.locale = key" @click="setI18nLanguage(key)"
>{{ language }}</a> >{{ language }}</a>
</div> </div>
</div> </div>

View File

@ -9,9 +9,13 @@ import store from '~/store'
import useLogger from '~/composables/useLogger' import useLogger from '~/composables/useLogger'
import en from '../locales/en.json'
const localeFactory = import.meta.glob('../locales/*.json')
const logger = useLogger() const logger = useLogger()
const defaultLanguage = store.state.ui.currentLanguage ?? 'en_US' const defaultLanguage = store.state.ui.currentLanguage ?? 'en'
export const SUPPORTED_LOCALES = locales.reduce((map: Record<string, string>, locale) => { export const SUPPORTED_LOCALES = locales.reduce((map: Record<string, string>, locale) => {
map[locale.code] = locale.label map[locale.code] = locale.label
return map return map
@ -22,22 +26,32 @@ export const i18n = createI18n<false>({
globalInjection: true, globalInjection: true,
fallbackLocale: 'en', fallbackLocale: 'en',
legacy: false, legacy: false,
locale: 'en' locale: 'en',
messages: { en }
}) })
export const setI18nLanguage = async (locale: string) => { export const setI18nLanguage = async (locale: string) => {
console.debug(0)
if (locale === 'en') {
return
}
console.debug(1)
if (!Object.keys(SUPPORTED_LOCALES).includes(locale)) { if (!Object.keys(SUPPORTED_LOCALES).includes(locale)) {
throw new Error(`Unsupported locale: ${locale}`) throw new Error(`Unsupported locale: ${locale}`)
} }
console.debug(2)
// load locale messages // load locale messages
if (!i18n.global.availableLocales.includes(locale)) { if (!i18n.global.availableLocales.includes(locale)) {
try { try {
const { default: messages } = await import(`./locales/${locale}.json`) console.debug(3)
const { default: messages } = await localeFactory[`../locales/${locale}.json`]()
i18n.global.setLocaleMessage(locale, messages) i18n.global.setLocaleMessage(locale, messages)
await nextTick() await nextTick()
} catch (error) { } catch (error) {
logger.warn(`Unsupported locale: ${locale}`) logger.warn(`Unsupported locale: ${locale}`)
logger.debug(error)
} }
} }
@ -72,6 +86,7 @@ export const install: InitModule = async ({ store, app }) => {
// Handle language change // Handle language change
watch(() => store.state.ui.currentLanguage, async (locale) => { watch(() => store.state.ui.currentLanguage, async (locale) => {
console.debug(locale)
await store.dispatch('ui/currentLanguage', locale) await store.dispatch('ui/currentLanguage', locale)
await setI18nLanguage(locale) await setI18nLanguage(locale)
// TODO (wvffle): Set moment locale // TODO (wvffle): Set moment locale

View File

@ -196,7 +196,7 @@
"fediverse": { "fediverse": {
"title": "Fediverse object", "title": "Fediverse object",
"fieldLabel": "Fediverse object", "fieldLabel": "Fediverse object",
"fieldPlaceholder": "@username@example.com" "fieldPlaceholder": "{'@'}username{'@'}example.com"
} }
}, },
"header": { "header": {

View File

@ -1068,7 +1068,7 @@
resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.3.0-beta.10.tgz#e1e6c99b0f0a039e8fadc319b93314056f8e992e" resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.3.0-beta.10.tgz#e1e6c99b0f0a039e8fadc319b93314056f8e992e"
integrity sha512-h93uAanbAt/XgjDHclrVB7xix6r7Uz11wx0iGNOCdHP7aA2LCJjUT3uNbekJjjbo+Fl5jzTSJZdm2SexzoqhRA== integrity sha512-h93uAanbAt/XgjDHclrVB7xix6r7Uz11wx0iGNOCdHP7aA2LCJjUT3uNbekJjjbo+Fl5jzTSJZdm2SexzoqhRA==
"@intlify/vite-plugin-vue-i18n@^6.0.1": "@intlify/vite-plugin-vue-i18n@^6.0.3":
version "6.0.3" version "6.0.3"
resolved "https://registry.yarnpkg.com/@intlify/vite-plugin-vue-i18n/-/vite-plugin-vue-i18n-6.0.3.tgz#57a6900de02a9829e52b16bf072768534c7664ef" resolved "https://registry.yarnpkg.com/@intlify/vite-plugin-vue-i18n/-/vite-plugin-vue-i18n-6.0.3.tgz#57a6900de02a9829e52b16bf072768534c7664ef"
integrity sha512-6SgNzPAOCR90wvt368lKzi7f/5ZEWJn22UCGvhFsP3XvKqlF3cVzojahgQ6o+LTdCkExeM6wPgd+haFf28E9VQ== integrity sha512-6SgNzPAOCR90wvt368lKzi7f/5ZEWJn22UCGvhFsP3XvKqlF3cVzojahgQ6o+LTdCkExeM6wPgd+haFf28E9VQ==
@ -1849,7 +1849,7 @@
"@vue/compiler-dom" "3.2.45" "@vue/compiler-dom" "3.2.45"
"@vue/shared" "3.2.45" "@vue/shared" "3.2.45"
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.4.5": "@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.2.1", "@vue/devtools-api@^6.4.5":
version "6.4.5" version "6.4.5"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.4.5.tgz#d54e844c1adbb1e677c81c665ecef1a2b4bb8380" resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.4.5.tgz#d54e844c1adbb1e677c81c665ecef1a2b4bb8380"
integrity sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ== integrity sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==
@ -5223,6 +5223,16 @@ vue-gettext@2.1.12:
resolved "https://registry.yarnpkg.com/vue-gettext/-/vue-gettext-2.1.12.tgz#444d3220149b17fa4c7caeded3f12d439b698f33" resolved "https://registry.yarnpkg.com/vue-gettext/-/vue-gettext-2.1.12.tgz#444d3220149b17fa4c7caeded3f12d439b698f33"
integrity sha512-7Kw36xtKvARp8ZafQGPK9WR6EM+dhFUikR5f0+etSkiHuvUM3yf1HsRDLYoLLdJ0AMaXxKwgekumzvCk6KX8rA== integrity sha512-7Kw36xtKvARp8ZafQGPK9WR6EM+dhFUikR5f0+etSkiHuvUM3yf1HsRDLYoLLdJ0AMaXxKwgekumzvCk6KX8rA==
vue-i18n@9:
version "9.2.2"
resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.2.2.tgz#aeb49d9424923c77e0d6441e3f21dafcecd0e666"
integrity sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==
dependencies:
"@intlify/core-base" "9.2.2"
"@intlify/shared" "9.2.2"
"@intlify/vue-devtools" "9.2.2"
"@vue/devtools-api" "^6.2.1"
vue-observe-visibility@^2.0.0-alpha.1: vue-observe-visibility@^2.0.0-alpha.1:
version "2.0.0-alpha.1" version "2.0.0-alpha.1"
resolved "https://registry.yarnpkg.com/vue-observe-visibility/-/vue-observe-visibility-2.0.0-alpha.1.tgz#1e4eda7b12562161d58984b7e0dea676d83bdb13" resolved "https://registry.yarnpkg.com/vue-observe-visibility/-/vue-observe-visibility-2.0.0-alpha.1.tgz#1e4eda7b12562161d58984b7e0dea676d83bdb13"