import { useEffect, useState, Component } from "react"; import type { ReactNode } from "react"; import { Stack, router } from "expo-router"; import { StatusBar } from "expo-status-bar"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { View, Text, ScrollView } from "react-native"; import "../global.css"; import { Colors } from "@/constants/theme"; import { useSettings } from "@/hooks/useSettings"; // Catch JS errors in release mode and show them on-screen instead of // silently crashing to desktop. Remove once the crash is identified. class CrashBoundary extends Component< { children: ReactNode }, { error: Error | null } > { state = { error: null }; static getDerivedStateFromError(e: Error) { return { error: e }; } render() { const { error } = this.state; if (error) { return ( CRASH — copie ce texte {String(error)}{"\n\n"}{(error as any).stack} ); } return this.props.children; } } export default function RootLayout() { const { settings, ready } = useSettings(); const [jsError, setJsError] = useState(null); useEffect(() => { const prev = (ErrorUtils as any).getGlobalHandler(); (ErrorUtils as any).setGlobalHandler((e: Error, isFatal: boolean) => { if (isFatal) setJsError(`${String(e)}\n\n${(e as any).stack ?? ""}`); prev?.(e, isFatal); }); return () => (ErrorUtils as any).setGlobalHandler(prev); }, []); useEffect(() => { if (!ready) return; if (!settings.onboardingDone) { router.replace("/onboarding"); } }, [ready, settings.onboardingDone]); if (jsError) { return ( FATAL JS ERROR — copie ce texte {jsError} ); } return ( ); }