mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-05-23 22:37:41 +08:00
99 lines
2.5 KiB
TypeScript
99 lines
2.5 KiB
TypeScript
import { useState, useEffect, useCallback } from 'react'
|
|
import type { Messages, Message } from './index'
|
|
import { messages } from './index'
|
|
|
|
|
|
type TranslateValues = Record<string, string | number | boolean>
|
|
|
|
type Langs = keyof Messages
|
|
|
|
type Hook = (locale: Langs) => void
|
|
|
|
export declare interface I18n {
|
|
locale: Langs
|
|
fallbackLocale: Langs
|
|
availableLocales: Langs[]
|
|
messages: Messages
|
|
message: Message
|
|
setLanguage: (locale: Langs) => void
|
|
fillMessage: (message: string, val: TranslateValues) => string
|
|
getMessage: (key: keyof Message, val?: TranslateValues) => string
|
|
t: (key: keyof Message, val?: TranslateValues) => string
|
|
}
|
|
|
|
let locale: Langs = 'zh_cn'
|
|
|
|
let i18n: I18n
|
|
|
|
|
|
const hookTools = {
|
|
hooks: [] as Hook[],
|
|
add(hook: Hook) {
|
|
this.hooks.push(hook)
|
|
},
|
|
remove(hook: Hook) {
|
|
this.hooks.splice(this.hooks.indexOf(hook), 1)
|
|
},
|
|
update(locale: Parameters<Hook>[0]) {
|
|
for (const hook of this.hooks) hook(locale)
|
|
},
|
|
}
|
|
|
|
const useI18n = () => {
|
|
const [locale, updateLocale] = useState(i18n?.locale ?? 'en_us')
|
|
// console.log('hook run')
|
|
useEffect(() => {
|
|
const hook: Hook = (locale) => {
|
|
updateLocale(locale)
|
|
}
|
|
hookTools.add(hook)
|
|
return () => { hookTools.remove(hook) }
|
|
}, [])
|
|
|
|
return useCallback((key: keyof Message, val?: TranslateValues): string => {
|
|
return i18n?.getMessage(key, val) ?? ''
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [locale])
|
|
}
|
|
|
|
const setLanguage = (lang: Langs) => {
|
|
i18n.setLanguage(lang)
|
|
}
|
|
|
|
const createI18n = (_locale: Langs = locale): I18n => {
|
|
locale = _locale
|
|
|
|
return i18n = {
|
|
locale,
|
|
fallbackLocale: 'zh_cn',
|
|
availableLocales: Object.keys(messages) as Langs[],
|
|
messages,
|
|
message: messages[locale],
|
|
setLanguage(_locale: Langs) {
|
|
this.locale = _locale
|
|
this.message = messages[_locale]
|
|
hookTools.update(_locale)
|
|
},
|
|
fillMessage(message: string, vals: TranslateValues): string {
|
|
for (const [key, val] of Object.entries(vals)) {
|
|
message = message.replace(new RegExp('{' + key + '}', 'g'), String(val))
|
|
}
|
|
return message
|
|
},
|
|
getMessage(key: keyof Message, val?: TranslateValues): string {
|
|
let targetMessage = this.message[key] ?? this.messages[this.fallbackLocale][key] ?? ''
|
|
return val ? this.fillMessage(targetMessage, val) : targetMessage
|
|
},
|
|
t(key: keyof Message, val?: TranslateValues): string {
|
|
return this.getMessage(key, val)
|
|
},
|
|
}
|
|
}
|
|
|
|
|
|
export {
|
|
setLanguage,
|
|
useI18n,
|
|
createI18n,
|
|
}
|