xtablo-source/xtablo-expo/app/_layout.tsx
Arthur Belleville 75328fbe96
Format codebase
2025-10-10 08:50:56 +02:00

81 lines
2.6 KiB
TypeScript

import { DarkTheme, DefaultTheme, ThemeProvider } from "@react-navigation/native";
import { Stack } from "expo-router";
import * as SplashScreen from "expo-splash-screen";
import { StatusBar } from "expo-status-bar";
import "react-native-reanimated";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { useColorScheme } from "@/hooks/useColorScheme";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { cloneDeep } from "lodash";
import { SplashScreenController } from "@/components/Splash";
import { useInitializeApp } from "@/hooks/auth";
import { LoadingView } from "@/components/LoadingView";
import { supabase } from "@/lib/supabase";
import { AppState } from "react-native";
window.structuredClone = cloneDeep;
// Prevent the splash screen from auto-hiding before asset loading is complete.
SplashScreen.preventAutoHideAsync();
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// 3 total attempts (1 initial + 2 retries)
retry: 2,
// 0s -> 1s, 1s → 5s. Little resiliency 😁
retryDelay: (attemptIndex) => Math.min(1000 * 5 ** attemptIndex, 10000),
},
},
});
// Tells Supabase Auth to continuously refresh the session automatically if
// the app is in the foreground. When this is added, you will continue to receive
// `onAuthStateChange` events with the `TOKEN_REFRESHED` or `SIGNED_OUT` event
// if the user's session is terminated. This should only be registered once.
AppState.addEventListener("change", (state) => {
if (state === "active") {
supabase.auth.startAutoRefresh();
} else {
supabase.auth.stopAutoRefresh();
}
});
export default function RootLayout() {
const colorScheme = useColorScheme();
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<QueryClientProvider client={queryClient}>
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
<SplashScreenController />
<RootNavigator />
<StatusBar style="auto" />
</ThemeProvider>
</QueryClientProvider>
</GestureHandlerRootView>
);
}
const RootNavigator = () => {
const { isLoading, isLoggedIn } = useInitializeApp();
if (isLoading) {
return <LoadingView />;
}
return (
<Stack>
<Stack.Protected guard={isLoggedIn}>
<Stack.Screen name="(app)" options={{ headerShown: false }} />
</Stack.Protected>
<Stack.Protected guard={!isLoggedIn}>
<Stack.Screen name="login" options={{ headerShown: false }} />
<Stack.Screen name="signup" options={{ headerShown: false }} />
</Stack.Protected>
<Stack.Screen name="+not-found" />
</Stack>
);
};