feat(settings): respect settings from server (#1013)

This commit is contained in:
三咲智子 Kevin Deng 2023-01-13 01:52:52 +08:00 committed by GitHub
parent 32aa47e701
commit 9a41b9b7d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 230 additions and 167 deletions

View file

@ -1,26 +1,46 @@
import { COOKIE_KEY_LOCALE, COOKIE_MAX_AGE } from '~/constants'
import type { VueI18n } from 'vue-i18n'
import type { LocaleObject } from 'vue-i18n-routing'
import { COOKIE_KEY_LOCALE, COOKIE_MAX_AGE, DEFAULT_LANGUAGE } from '~/constants'
export default defineNuxtPlugin(async (nuxt) => {
const i18n = nuxt.vueApp.config.globalProperties.$i18n
const { setLocale, locales } = nuxt.vueApp.config.globalProperties.$i18n
const i18n = nuxt.vueApp.config.globalProperties.$i18n as VueI18n
const { setLocale, locales } = i18n
const supportLanguages = (locales as LocaleObject[]).map(locale => locale.code)
const cookieLocale = useCookie(COOKIE_KEY_LOCALE, { maxAge: COOKIE_MAX_AGE })
const isFirstVisit = cookieLocale.value == null
const userSettings = useUserSettings()
if (process.client && isFirstVisit) {
const userLang = (navigator.language || 'en-US').toLowerCase()
// cause vue-i18n not explicit export LocaleObject type
const supportLocales = unref(locales) as { code: string }[]
const lang = supportLocales.find(locale => userLang.startsWith(locale.code.toLowerCase()))?.code
|| supportLocales.find(locale => userLang.startsWith(locale.code.split('-')[0]))?.code
cookieLocale.value = lang || 'en-US'
if (process.server) {
const headers = useRequestHeaders()
let lang = cookieLocale.value
if (!lang || !supportLanguages.includes(lang)) {
// first visit
if (headers['accept-language']) {
// detect language from header
const userLanguages = headers['accept-language'].split(',').map(lang => lang.split(';')[0].toLowerCase())
lang = matchLanguages(supportLanguages, userLanguages) || DEFAULT_LANGUAGE
}
else {
lang = DEFAULT_LANGUAGE
}
}
userSettings.value.language = cookieLocale.value = lang
if (lang !== i18n.locale)
await setLocale(cookieLocale.value)
return
}
if (cookieLocale.value && cookieLocale.value !== i18n.locale)
await setLocale(cookieLocale.value)
// could be null if browser don't accept cookie
if (!cookieLocale.value || !supportLanguages.includes(cookieLocale.value))
cookieLocale.value = DEFAULT_LANGUAGE
userSettings.value.language = cookieLocale.value
if (process.client) {
watchEffect(() => {
cookieLocale.value = i18n.locale
})
}
watch(() => userSettings.value.language, (lang) => {
if (lang !== cookieLocale.value)
cookieLocale.value = lang
if (lang !== i18n.locale)
setLocale(lang)
}, { immediate: true })
})