import '../global.css'
import 'react-native-reanimated'
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'
import * as Sentry from '@sentry/react-native'
import { Stack, useNavigationContainerRef } from 'expo-router'
import { StatusBar } from 'expo-status-bar'
import { useEffect } from 'react'
import { GestureHandlerRootView } from 'react-native-gesture-handler'
import { KeyboardProvider } from 'react-native-keyboard-controller'
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'
import { ModalPortal } from '@/@share/components'
import { bleManager } from '@/ble/managers/bleManager'
import { HotUpdate } from '@/components/hot-update'
import { useColorScheme } from '@/hooks/use-color-scheme'
import { setupGlobalFetchLogger } from '@/lib/fetch-logger'
import { useUserSession } from '@/stores/userStore'
const isProd = process.env.EXPO_PUBLIC_ENV !== 'development'
Sentry.init({
dsn: 'https://ef710a118839b1e86e38a3833a9a3c6c@o4507705403965440.ingest.us.sentry.io/4510576286302208',
sendDefaultPii: true,
enableLogs: true,
enabled: isProd,
})
if (__DEV__) {
setupGlobalFetchLogger()
}
export const unstable_settings = {
anchor: '(tabs)',
}
function RootLayout() {
const ref = useNavigationContainerRef()
useEffect(() => {
if (!ref?.current) return
const unsubscribe = ref.addListener('state', (e) => {
try {
const routes = e.data.state?.routes
if (!routes || routes.length === 0) return
const currentRoute = routes[routes.length - 1]
if (!currentRoute) return
let screenName = currentRoute.name
let params = currentRoute.params
// 处理嵌套路由
if (currentRoute.state?.routes) {
const nestedRoutes = currentRoute.state.routes
const activeNestedRoute = nestedRoutes[nestedRoutes.length - 1]
if (activeNestedRoute && activeNestedRoute.name !== '__root') {
screenName = activeNestedRoute.name
params = activeNestedRoute.params
}
}
// 使用 debug 而非 warn,避免噪音
if (__DEV__) {
console.debug(`📍 Navigation: ${screenName}`, params ? `(${JSON.stringify(params)})` : '')
}
// 上报到 Sentry(可选)
Sentry.captureMessage(`Navigation: ${screenName}`, 'info')
} catch (error) {
console.error('❌ Navigation listener error:', error)
Sentry.captureException(error)
}
})
return unsubscribe
}, [ref])
useEffect(() => {
bleManager.initialize()
return () => {
bleManager.destroy()
}
}, [])
return (
)
}
function Providers({ children }: { children: React.ReactNode }) {
const colorScheme = useColorScheme()
useUserSession()
return (
{children}
((global as any).actionSheet = ref)} />
((global as any).modal = ref)} />
((global as any).loading = ref)} />
((global as any).toast = ref)} />
)
}
export default Sentry.wrap(RootLayout)