Files
playX/src/App.tsx
2026-04-15 09:20:02 +08:00

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