import '../global.css' import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native' import { Stack, usePathname, useRouter } from 'expo-router' import { StatusBar } from 'expo-status-bar' import { useEffect } from 'react' import 'react-native-reanimated' import { GestureHandlerRootView } from 'react-native-gesture-handler' import { View, ActivityIndicator, AppState } from 'react-native' import * as Updates from 'expo-updates' import { useColorScheme } from '@/hooks/use-color-scheme' import { KeyboardProvider } from 'react-native-keyboard-controller' import { SafeAreaProvider } from 'react-native-safe-area-context' import { ModalPortal } from '@/components/ui' import '@/lib/i18n' import { useSession } from '@/lib/auth' export const unstable_settings = { anchor: '(tabs)', } // 受保护的路由(需要登录才能访问) const PROTECTED_ROUTES = [ '/(tabs)', '/channels', '/generateVideo', '/generationRecord', '/worksList', '/membership', '/changePassword', ] // 公开路由(无需登录) const PUBLIC_ROUTES = [ '/auth', '/modal', '/searchTemplate', '/searchResults', '/searchWorks', '/searchWorksResults', '/templateDetail', '/terms', '/privacy', ] // 认证守卫组件 function AuthGuard({ children }: { children: React.ReactNode }) { const pathname = usePathname() const router = useRouter() const { data: session, isPending } = useSession() useEffect(() => { // 加载中不处理 if (isPending) return // 检查是否在受保护路由 const isProtectedRoute = PROTECTED_ROUTES.some(route => pathname?.startsWith(route)) // 未登录访问受保护路由 -> 跳转到登录页 if (isProtectedRoute && !session?.user) { router.replace('/auth') return } // 已登录访问登录页 -> 跳转到首页 if (pathname === '/auth' && session?.user) { router.replace('/(tabs)') return } }, [pathname, session, isPending, router]) // 加载中显示 loading if (isPending) { return ( ) } return <>{children} } // 路由层 export default function RootLayout() { return ( ) } function Providers({ children }: { children: React.ReactNode }) { const colorScheme = useColorScheme() // 热更新检查 useEffect(() => { // 检查更新的函数 async function checkForUpdates() { // 开发环境不检查更新 if (__DEV__) return try { const update = await Updates.checkForUpdateAsync() if (update.isAvailable) { await Updates.fetchUpdateAsync() // 提示用户重启应用 ;(global as any).toast?.show({ type: 'success', message: '发现新版本,即将重启应用', }) // 延迟重启,让用户看到提示 setTimeout(() => { Updates.reloadAsync() }, 2000) } } catch (error) { console.error('检查更新失败:', error) } } // App 启动时检查 checkForUpdates() // 监听 App 状态变化,从后台返回前台时检查 const subscription = AppState.addEventListener('change', (nextAppState) => { if (nextAppState === 'active') { checkForUpdates() } }) return () => { subscription.remove() } }, []) return ( {children} {/* modals */} {/* 挂载全局方法 */} ((global as any).actionSheet = ref)} /> ((global as any).modal = ref)} /> ((global as any).loading = ref)} /> ((global as any).toast = ref)} /> ) }