122 lines
3.6 KiB
TypeScript
122 lines
3.6 KiB
TypeScript
'use client'
|
|
|
|
import i18nConfig from '@/i18nConfig'
|
|
import { usePathname, useRouter } from 'next/navigation'
|
|
import { useEffect, useTransition } from 'react'
|
|
import { Globe } from 'lucide-react'
|
|
import { useTranslation } from 'react-i18next'
|
|
|
|
export function LanguageSwitcher() {
|
|
const router = useRouter()
|
|
const pathname = usePathname()
|
|
const [isPending, startTransition] = useTransition()
|
|
|
|
const { i18n } = useTranslation() // 获取 i18n 实例
|
|
|
|
console.log('[LanguageSwitcher]====>Current url:', pathname)
|
|
|
|
const currentLocale = pathname.split('/')[1] || i18nConfig.defaultLocale
|
|
|
|
useEffect(() => {
|
|
// 只在加载时检查,避免多次保存 cookie
|
|
if (typeof window !== 'undefined') {
|
|
const saved = localStorage.getItem('preferred-language')
|
|
|
|
// console.log('[LanguageSwitcher]=> Read from localstorage preferred-language=', saved)
|
|
|
|
const isLocaleInPath = i18nConfig.locales.includes(currentLocale as any)
|
|
|
|
}
|
|
else{
|
|
console.log('[LanguageSwitcher] language switcher cannt running in server.')
|
|
}
|
|
}, [currentLocale])
|
|
|
|
// const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
// const newLocale = e.target.value
|
|
// // 仅在用户选择语言后保存 cookie
|
|
// // console.log('[LanguageSwitcher] Write Cookie newLocale value:', newLocale)
|
|
// // document.cookie = `preferred-language=${newLocale}; path=/; max-age=31536000`
|
|
|
|
// // 同时更新 localStorage
|
|
// localStorage.setItem('preferred-language', newLocale)
|
|
|
|
// // 验证 cookie 是否成功写入
|
|
// // const cookieValue = document.cookie
|
|
|
|
// // 更新 i18n 的语言
|
|
// i18n.changeLanguage(newLocale) // 修改 TranslationProvider 中的 locale
|
|
|
|
// let segments = pathname === '/' ? [] : pathname.split('/').filter(Boolean)
|
|
// const isLocaleInPath = i18nConfig.locales.includes(segments[0] as any)
|
|
|
|
// if (isLocaleInPath) {
|
|
// segments[0] = newLocale
|
|
// } else {
|
|
// segments.unshift(newLocale)
|
|
// }
|
|
|
|
// const newPath = '/' + segments.join('/')
|
|
|
|
// // 延迟跳转,确保 cookie 写入完成
|
|
// setTimeout(() => {
|
|
// startTransition(() => {
|
|
// if (pathname !== newPath) {
|
|
// router.push(newPath)
|
|
// } else {
|
|
// router.refresh()
|
|
// }
|
|
// })
|
|
// }, 0)
|
|
// }
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
const newLocale = e.target.value
|
|
|
|
// 更新 localStorage
|
|
localStorage.setItem('preferred-language', newLocale)
|
|
|
|
// 更新 i18n 的语言
|
|
i18n.changeLanguage(newLocale)
|
|
|
|
let segments = pathname === '/' ? [] : pathname.split('/').filter(Boolean)
|
|
const isLocaleInPath = i18nConfig.locales.includes(segments[0] as any)
|
|
|
|
if (isLocaleInPath) {
|
|
segments[0] = newLocale
|
|
} else {
|
|
segments.unshift(newLocale)
|
|
}
|
|
|
|
const newPath = '/' + segments.join('/')
|
|
|
|
startTransition(() => {
|
|
if (pathname !== newPath) {
|
|
console.log("...........[language-switcher]...]")
|
|
router.push(newPath)
|
|
} else {
|
|
router.refresh()
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
return (
|
|
<div className="absolute top-4 right-4 z-50 flex items-center gap-2">
|
|
<Globe size={18} className="text-muted-foreground" />
|
|
<select
|
|
className="rounded-md border px-2 py-1 text-sm bg-background text-foreground"
|
|
value={currentLocale}
|
|
onChange={handleChange}
|
|
disabled={isPending}
|
|
>
|
|
{i18nConfig.locales.map(locale => (
|
|
<option key={locale} value={locale}>
|
|
{i18nConfig.languageNames[locale] || locale.toUpperCase()}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
)
|
|
}
|