136 lines
4.6 KiB
TypeScript
136 lines
4.6 KiB
TypeScript
// import {useEffect} from 'react'
|
|
import {lazy, Suspense, useEffect, useRef} from 'react'
|
|
import {useQueryClient} from '@tanstack/react-query'
|
|
import {useTranslation} from 'react-i18next'
|
|
import {BrowserRouter, Route, Routes} from 'react-router-dom'
|
|
import {AuthGuide} from '@/features/authGuide.tsx'
|
|
import {GlobalToast} from '@/features/notifications'
|
|
import i18n, {normalizeLanguage} from '@/lib/i18n'
|
|
import {useUserStore} from '@/store/user.ts'
|
|
// import type { HostContextMessage } from '@/types'
|
|
|
|
const HomePage = lazy(() => import('./views/home'))
|
|
const RecordPage = lazy(() => import('./views/record'))
|
|
const AccountPage = lazy(() => import('./views/account'))
|
|
const GoodsPage = lazy(() => import('./views/goods'))
|
|
|
|
function App() {
|
|
const {t} = useTranslation()
|
|
const queryClient = useQueryClient()
|
|
const language = useUserStore((state) => state.language)
|
|
const previousLanguageRef = useRef<string | null>(null)
|
|
|
|
useEffect(() => {
|
|
const normalizedLanguage = normalizeLanguage(language)
|
|
const previousLanguage = previousLanguageRef.current
|
|
|
|
void (async () => {
|
|
await i18n.changeLanguage(normalizedLanguage)
|
|
document.documentElement.lang = normalizedLanguage
|
|
|
|
if (previousLanguage && previousLanguage !== normalizedLanguage) {
|
|
await queryClient.cancelQueries()
|
|
await queryClient.invalidateQueries({refetchType: 'active'})
|
|
}
|
|
|
|
previousLanguageRef.current = normalizedLanguage
|
|
})()
|
|
}, [language, queryClient])
|
|
|
|
// 开发/测试阶段如需跳过 iframe 传参,可设置:
|
|
// VITE_BYPASS_IFRAME_CONTEXT=true
|
|
// 项目会直接使用测试数据初始化:
|
|
// username: +60777777777
|
|
// language: zh
|
|
|
|
// useEffect(() => {
|
|
// const handleMessage = (event: MessageEvent<HostContextMessage>) => {
|
|
// const message = event.data
|
|
//
|
|
// if (!message || message.type !== 'IFRAME_CONTEXT' || !message.payload) {
|
|
// return
|
|
// }
|
|
//
|
|
// const {language, username} = message.payload
|
|
//
|
|
// if (typeof username === 'string' && username.trim()) {
|
|
//
|
|
// }
|
|
//
|
|
// if (typeof language === 'string' && language.trim()) {
|
|
// // language 由 zustand 存储,供请求头直接读取
|
|
// }
|
|
// }
|
|
//
|
|
// window.addEventListener('message', handleMessage)
|
|
//
|
|
// return () => {
|
|
// window.removeEventListener('message', handleMessage)
|
|
// }
|
|
// }, [])
|
|
|
|
// 本机测试
|
|
// window.postMessage(
|
|
// {
|
|
// type: 'IFRAME_CONTEXT',
|
|
// payload: {
|
|
// username: '+60777777777',
|
|
// language: 'zh-CN',
|
|
// },
|
|
// },
|
|
// window.location.origin
|
|
// )
|
|
// 父页面推荐使用握手方式发送 iframe context
|
|
// <iframe
|
|
// id="palyx-frame"
|
|
// src="https://your-iframe-app.example.com"
|
|
// style="width: 100%; border: 0;"
|
|
// ></iframe>
|
|
//
|
|
// <script>
|
|
// const iframe = document.getElementById('palyx-frame')
|
|
// const IFRAME_ORIGIN = 'https://your-iframe-app.example.com'
|
|
//
|
|
// window.addEventListener('message', (event) => {
|
|
// if (event.source !== iframe.contentWindow || event.data?.type !== 'PLAYX_READY') {
|
|
// return
|
|
// }
|
|
//
|
|
// iframe.contentWindow.postMessage(
|
|
// {
|
|
// type: 'IFRAME_CONTEXT',
|
|
// payload: {
|
|
// username: '+60777777777',
|
|
// language: 'zh-CN',
|
|
// },
|
|
// },
|
|
// IFRAME_ORIGIN
|
|
// )
|
|
// })
|
|
// </script>
|
|
|
|
return (
|
|
<BrowserRouter>
|
|
<GlobalToast/>
|
|
<AuthGuide>
|
|
<Suspense
|
|
fallback={
|
|
<div className="flex min-h-screen items-center justify-center bg-[#08070E] px-6 text-center text-[14px] text-white/68">
|
|
{t('app.loading')}
|
|
</div>
|
|
}
|
|
>
|
|
<Routes>
|
|
<Route path="/" element={<HomePage/>}/>
|
|
<Route path="/goods" element={<GoodsPage/>}/>
|
|
<Route path="/record" element={<RecordPage/>}/>
|
|
<Route path="/account" element={<AccountPage/>}/>
|
|
</Routes>
|
|
</Suspense>
|
|
</AuthGuide>
|
|
</BrowserRouter>
|
|
)
|
|
}
|
|
|
|
export default App
|