import {
|
initVueI18n,
|
isI18nStr
|
} from '@dcloudio/uni-i18n'
|
import {
|
isStr
|
} from 'uni-shared'
|
|
import {
|
UNI_STORAGE_LOCALE
|
} from '../constants'
|
|
import en from './en.json'
|
import es from './es.json'
|
import fr from './fr.json'
|
import zhHans from './zh-Hans.json'
|
import zhHant from './zh-Hant.json'
|
|
export const LOCALE_ZH_HANS = 'zh-Hans'
|
export const LOCALE_ZH_HANT = 'zh-Hant'
|
export const LOCALE_EN = 'en'
|
export const LOCALE_FR = 'fr'
|
export const LOCALE_ES = 'es'
|
|
const messages = {}
|
|
if (__PLATFORM__ === 'h5' || __PLATFORM__ === 'app-plus') {
|
Object.assign(messages, {
|
[LOCALE_EN]: en,
|
[LOCALE_ES]: es,
|
[LOCALE_FR]: fr,
|
[LOCALE_ZH_HANS]: zhHans,
|
[LOCALE_ZH_HANT]: zhHant
|
})
|
}
|
|
let locale
|
|
if (__PLATFORM__ === 'h5') {
|
locale = (navigator.cookieEnabled && window.localStorage && localStorage[UNI_STORAGE_LOCALE]) || __uniConfig.locale || navigator.language
|
} else if (__PLATFORM__ === 'app-plus') {
|
if (typeof weex === 'object') {
|
locale = weex.requireModule('plus').getLanguage()
|
} else {
|
locale = ''
|
}
|
} else {
|
locale = normalizeLocale(__GLOBAL__.getSystemInfoSync().language) || LOCALE_EN
|
}
|
|
function initI18nMessages () {
|
if (!isEnableLocale()) {
|
return
|
}
|
const localeKeys = Object.keys(__uniConfig.locales)
|
if (localeKeys.length) {
|
localeKeys.forEach((locale) => {
|
const curMessages = messages[locale]
|
const userMessages = __uniConfig.locales[locale]
|
if (curMessages) {
|
Object.assign(curMessages, userMessages)
|
} else {
|
messages[locale] = userMessages
|
}
|
})
|
}
|
}
|
|
initI18nMessages()
|
|
export const i18n = initVueI18n(
|
locale,
|
__PLATFORM__ === 'app-plus' || __PLATFORM__ === 'h5' ? messages : {}
|
)
|
export const t = i18n.t
|
export const i18nMixin = (i18n.mixin = {
|
beforeCreate () {
|
const unwatch = i18n.i18n.watchLocale(() => {
|
this.$forceUpdate()
|
})
|
this.$once('hook:beforeDestroy', function () {
|
unwatch()
|
})
|
},
|
methods: {
|
$$t (key, values) {
|
return t(key, values)
|
}
|
}
|
})
|
export const setLocale = i18n.setLocale
|
export const getLocale = i18n.getLocale
|
|
export function initAppLocale (Vue, appVm, locale) {
|
const state = Vue.observable({
|
locale: locale || i18n.getLocale()
|
})
|
const localeWatchers = []
|
appVm.$watchLocale = fn => {
|
localeWatchers.push(fn)
|
}
|
Object.defineProperty(appVm, '$locale', {
|
get () {
|
return state.locale
|
},
|
set (v) {
|
state.locale = v
|
localeWatchers.forEach(watch => watch(v))
|
}
|
})
|
}
|
|
export const I18N_JSON_DELIMITERS = ['%', '%']
|
|
function getLocaleMessage () {
|
const locale = uni.getLocale()
|
const locales = __uniConfig.locales
|
return (
|
locales[locale] || locales[__uniConfig.fallbackLocale] || locales[LOCALE_EN] || {}
|
)
|
}
|
|
export function formatI18n (message) {
|
if (isI18nStr(message, I18N_JSON_DELIMITERS)) {
|
return i18n.f(message, getLocaleMessage(), I18N_JSON_DELIMITERS)
|
}
|
return message
|
}
|
|
function resolveJsonObj (jsonObj, names) {
|
if (names.length === 1) {
|
if (jsonObj) {
|
const _isI18nStr = (value) => isStr(value) && isI18nStr(value, I18N_JSON_DELIMITERS)
|
const _name = names[0]
|
let filterJsonObj = []
|
if (Array.isArray(jsonObj) && (filterJsonObj = jsonObj.filter(item => _isI18nStr(item[_name]))).length) {
|
return filterJsonObj
|
}
|
const value = jsonObj[_name]
|
if (_isI18nStr(value)) {
|
return jsonObj
|
}
|
}
|
return
|
}
|
const name = names.shift()
|
return resolveJsonObj(jsonObj && jsonObj[name], names)
|
}
|
|
export function defineI18nProperties (obj, names) {
|
return names.map(name => defineI18nProperty(obj, name))
|
}
|
|
export function defineI18nProperty (obj, names) {
|
const jsonObj = resolveJsonObj(obj, names)
|
if (!jsonObj) {
|
return false
|
}
|
const prop = names[names.length - 1]
|
if (Array.isArray(jsonObj)) {
|
jsonObj
|
.forEach(item => defineI18nProperty(item, [prop]))
|
} else {
|
let value = jsonObj[prop]
|
Object.defineProperty(jsonObj, prop, {
|
get () {
|
return formatI18n(value)
|
},
|
set (v) {
|
value = v
|
}
|
})
|
}
|
return true
|
}
|
|
function isEnableLocale () {
|
return typeof __uniConfig !== 'undefined' && __uniConfig.locales && !!Object.keys(__uniConfig.locales).length
|
}
|
|
export function initNavigationBarI18n (navigationBar) {
|
if (isEnableLocale()) {
|
return defineI18nProperties(navigationBar, [
|
['titleText'],
|
['searchInput', 'placeholder'],
|
['buttons', 'text']
|
])
|
}
|
}
|
|
export function initPullToRefreshI18n (pullToRefresh) {
|
if (isEnableLocale()) {
|
const CAPTION = 'caption'
|
return defineI18nProperties(pullToRefresh, [
|
['contentdown', CAPTION],
|
['contentover', CAPTION],
|
['contentrefresh', CAPTION]
|
])
|
}
|
}
|
|
export function initTabBarI18n (tabBar) {
|
if (isEnableLocale() && tabBar.list) {
|
tabBar.list.forEach(item => {
|
defineI18nProperty(item, ['text'])
|
})
|
}
|
return tabBar
|
}
|
|
function include (str, parts) {
|
return !!parts.find((part) => str.indexOf(part) !== -1)
|
}
|
|
function startsWith (str, parts) {
|
return parts.find((part) => str.indexOf(part) === 0)
|
}
|
|
export function normalizeLocale (locale, messages) {
|
if (!locale) {
|
return
|
}
|
locale = locale.trim().replace(/_/g, '-')
|
if (messages && messages[locale]) {
|
return locale
|
}
|
locale = locale.toLowerCase()
|
if (locale === 'chinese') {
|
// 支付宝
|
return LOCALE_ZH_HANS
|
}
|
if (locale.indexOf('zh') === 0) {
|
if (locale.indexOf('-hans') > -1) {
|
return LOCALE_ZH_HANS
|
}
|
if (locale.indexOf('-hant') > -1) {
|
return LOCALE_ZH_HANT
|
}
|
if (include(locale, ['-tw', '-hk', '-mo', '-cht'])) {
|
return LOCALE_ZH_HANT
|
}
|
return LOCALE_ZH_HANS
|
}
|
const lang = startsWith(locale, [LOCALE_EN, LOCALE_FR, LOCALE_ES])
|
if (lang) {
|
return lang
|
}
|
}
|
// export function initI18n() {
|
// const localeKeys = Object.keys(__uniConfig.locales || {})
|
// if (localeKeys.length) {
|
// localeKeys.forEach((locale) =>
|
// i18n.add(locale, __uniConfig.locales[locale])
|
// )
|
// }
|
// }
|