main
import { useEffect, useState } from 'react'
export const LOCALES = ['zh-CN', 'en'] as const
export type Locale = (typeof LOCALES)[number]
export const defaultLocale: Locale = 'en'
export function parseLocale(raw: string): Locale | null {
const tag = raw.trim().toLowerCase().replace(/_/g, '-')
if (!tag) return null
if (tag === 'zh' || tag.startsWith('zh-')) {
const rest = tag.slice(2)
if (rest.includes('hant') || ['-tw', '-hk', '-mo'].some((region) => rest.includes(region))) return null
return 'zh-CN'
}
if (tag === 'en' || tag.startsWith('en-')) return 'en'
return null
}
function accepted(): readonly string[] {
if (typeof navigator === 'undefined') return []
if (navigator.languages?.length) return navigator.languages
return navigator.language ? [navigator.language] : []
}
export function detectLocale(): Locale {
for (const tag of accepted()) {
const locale = parseLocale(tag)
if (locale) return locale
}
return defaultLocale
}
let current = detectLocale()
const listeners = new Set<() => void>()
export function locale(): Locale {
return current
}
export function setLocale(next: Locale) {
if (next === current) return
current = next
listeners.forEach((listener) => {
listener()
})
}
export function useLocale(): Locale {
const [value, setValue] = useState(current)
useEffect(() => {
const listener = () => setValue(current)
listeners.add(listener)
return () => {
listeners.delete(listener)
}
}, [])
return value
}
if (typeof window !== 'undefined') {
window.addEventListener('languagechange', () => setLocale(detectLocale()))
}