/
Muip
/
ProBody
Обзор
Документация
Войти
/
Muip
/
ProBody
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
app/_layout.tsx
168 строк
5 KB
chmerev
new
14 авг 2024, 12:19
14 авг 2024, 12:19
e868ce4
Код
Авторство
О чём код?
import FontAwesome from '@expo/vector-icons/FontAwesome'; import { useFonts } from 'expo-font'; import { SplashScreen, Stack } from 'expo-router'; import { StatusBar } from 'expo-status-bar'; import { useEffect, useRef, useState } from 'react'; import { MainContextProvider } from '../context/mainContext'; import Strings from '../constants/Strings'; import createApiClient from '../context/apiClient'; import createApiClientAieTable from '../context/apiClientAirtable'; import { User } from '../model/user'; import Intro from '../components/Intro'; import AsyncStorage from '@react-native-async-storage/async-storage'; import * as Updates from 'expo-updates'; import { AppState } from 'react-native'; import { activateKeepAwakeAsync } from 'expo-keep-awake'; 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(); // SplashScreen.hideAsync(); export default function RootLayout() { const [loaded, error] = useFonts({ SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'), SfProDisplay: require('../assets/fonts/SF-Pro-Display-Regular.otf'), SfProDisplayMedium: require('../assets/fonts/SF-Pro-Display-Medium.otf'), SfProDisplayBold: require('../assets/fonts/SF-Pro-Display-Bold.otf'), Grotesk: require('../assets/fonts/Soyuz-Grotesk-Bold.otf'), ...FontAwesome.font, }); // Expo Router uses Error Boundaries to catch errors in the navigation tree. useEffect(() => { if (error) {throw error;} }, [error]); const [isComponentReady, setComponentReady] = useState<boolean>(false); const [loadedUser, setLoadedUser] = useState<boolean>(false); const [user, setUser] = useState<User | null>(null); const [showIntro, setShowIntro] = useState<boolean>(false); const api = createApiClient(); const airtable = createApiClientAieTable(); useEffect(() => { activateKeepAwakeAsync(); (async() => { const apiAuthorized = await api.isAuthorized(); try { if (apiAuthorized) { const resp = await api.user.me(); setUser(resp.body); } } catch (e) { api.Unauthorize(); } const introIsCompleted = await AsyncStorage.getItem(Strings.INTRO_COMPLETED); if (introIsCompleted == null) { setShowIntro(true); } setLoadedUser(true); })() }, []); useEffect(() => { if (loaded && loadedUser) { SplashScreen.hideAsync() setComponentReady(true); } }, [loaded, loadedUser]); if (!isComponentReady) { return null; } const onIntroCompleted = async () => { setShowIntro(false); await AsyncStorage.setItem(Strings.INTRO_COMPLETED, 'true'); } return ( <> <StatusBar style="dark" /> {showIntro ? <Intro onFinished={onIntroCompleted} /> : <MainContextProvider api={api} user={user} airTable={airtable}> <RootLayoutNav/> </MainContextProvider> } </> ) } function RootLayoutNav() { const appState = useRef(AppState.currentState); const updateApp = async () => { try { const update = await Updates.checkForUpdateAsync(); if (!update.isAvailable) { return } if (update.isAvailable) { await Updates.fetchUpdateAsync(); await Updates.reloadAsync(); } } catch (error) { return } } useEffect(() => { const subscription = AppState.addEventListener('change', nextAppState => { if ( appState.current.match(/inactive|background/) && nextAppState === 'active' ) { updateApp(); } appState.current = nextAppState; }); return () => { subscription.remove(); }; }, []); return ( <> <Stack screenOptions={{ animation: 'none', animationDuration: 200 }} > <Stack.Screen name="home" options={{ headerShown: false, animation: 'slide_from_left', animationDuration: 200 }} /> <Stack.Screen name="(tabs)" options={{ headerShown: false }}/> <Stack.Screen name="meditation" options={{ headerShown: true, presentation: 'modal', animation: 'fade_from_bottom' }} /> <Stack.Screen name="meditation-in" options={{ headerShown: true, presentation: 'modal', animation: 'fade_from_bottom' }} /> <Stack.Screen name="login" options={{ headerShown: false, animation: 'slide_from_left', animationDuration: 200 }} /> <Stack.Screen name="registration" options={{ headerShown: false, animation: 'slide_from_left', animationDuration: 200 }} /> <Stack.Screen name="forgot" options={{ headerShown: false, animation: 'slide_from_left', animationDuration: 200 }} /> </Stack> </> ); }