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())) }