You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.6 KiB
102 lines
2.6 KiB
import FontAwesome from '@expo/vector-icons/FontAwesome'; |
|
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; |
|
import { useFonts } from 'expo-font'; |
|
import { Stack } from 'expo-router'; |
|
import * as SplashScreen from 'expo-splash-screen'; |
|
import * as Updates from 'expo-updates'; |
|
import { useEffect } from 'react'; |
|
import { Alert, Platform } from 'react-native'; |
|
import 'react-native-reanimated'; |
|
|
|
import { useColorScheme } from '@/components/useColorScheme'; |
|
|
|
export { |
|
// Catch any errors thrown by the Layout component. |
|
ErrorBoundary, |
|
} from 'expo-router'; |
|
|
|
export const unstable_settings = { |
|
// Ensure that reloading on `/modal` keeps a back button present. |
|
initialRouteName: '(tabs)', |
|
}; |
|
|
|
// Prevent the splash screen from auto-hiding before asset loading is complete. |
|
SplashScreen.preventAutoHideAsync(); |
|
|
|
export default function RootLayout() { |
|
const [loaded, error] = useFonts({ |
|
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'), |
|
...FontAwesome.font, |
|
}); |
|
|
|
// Expo Router uses Error Boundaries to catch errors in the navigation tree. |
|
useEffect(() => { |
|
if (error) throw error; |
|
}, [error]); |
|
|
|
useEffect(() => { |
|
if (loaded) { |
|
SplashScreen.hideAsync(); |
|
} |
|
}, [loaded]); |
|
|
|
// 检查热更新 |
|
useEffect(() => { |
|
async function checkForUpdates() { |
|
if (__DEV__) { |
|
// 开发模式下不检查更新 |
|
return; |
|
} |
|
|
|
try { |
|
const update = await Updates.checkForUpdateAsync(); |
|
|
|
if (update.isAvailable) { |
|
await Updates.fetchUpdateAsync(); |
|
|
|
// 提示用户重启应用以应用更新 |
|
Alert.alert( |
|
'更新可用', |
|
'发现新版本,是否立即重启应用?', |
|
[ |
|
{ |
|
text: '稍后', |
|
style: 'cancel', |
|
}, |
|
{ |
|
text: '立即重启', |
|
onPress: async () => { |
|
await Updates.reloadAsync(); |
|
}, |
|
}, |
|
] |
|
); |
|
} |
|
} catch (error) { |
|
// 处理更新检查错误 |
|
console.error('检查更新失败:', error); |
|
} |
|
} |
|
|
|
checkForUpdates(); |
|
}, []); |
|
|
|
if (!loaded) { |
|
return null; |
|
} |
|
|
|
return <RootLayoutNav />; |
|
} |
|
|
|
function RootLayoutNav() { |
|
const colorScheme = useColorScheme(); |
|
|
|
return ( |
|
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}> |
|
<Stack> |
|
<Stack.Screen name="(tabs)" options={{ headerShown: false }} /> |
|
<Stack.Screen name="modal" options={{ presentation: 'modal' }} /> |
|
</Stack> |
|
</ThemeProvider> |
|
); |
|
}
|
|
|