Checkpoint: works but feels hacky

This commit is contained in:
Eric Bailey
2026-01-22 11:26:14 -06:00
parent 0ea7152f5c
commit 4245f71cd8
3 changed files with 70 additions and 33 deletions
+51 -3
View File
@@ -1,4 +1,4 @@
import {type JSX, useCallback, useRef} from 'react' import {type JSX, useCallback, useEffect, useRef, useState} from 'react'
import {Linking} from 'react-native' import {Linking} from 'react-native'
import * as Notifications from 'expo-notifications' import * as Notifications from 'expo-notifications'
import {i18n, type MessageDescriptor} from '@lingui/core' import {i18n, type MessageDescriptor} from '@lingui/core'
@@ -14,7 +14,9 @@ import {
DefaultTheme, DefaultTheme,
type LinkingOptions, type LinkingOptions,
NavigationContainer, NavigationContainer,
type NavigationState,
StackActions, StackActions,
useNavigation,
} from '@react-navigation/native' } from '@react-navigation/native'
import {timeout} from '#/lib/async/timeout' import {timeout} from '#/lib/async/timeout'
@@ -136,7 +138,12 @@ import {
EmailDialogScreenID, EmailDialogScreenID,
useEmailDialogControl, useEmailDialogControl,
} from '#/components/dialogs/EmailDialog' } from '#/components/dialogs/EmailDialog'
import {useAnalytics} from '#/analytics' import {
AnalyticsContext,
type AnalyticsContextType,
useAnalytics,
utils,
} from '#/analytics'
import {IS_NATIVE, IS_WEB} from '#/env' import {IS_NATIVE, IS_WEB} from '#/env'
import {router} from '#/routes' import {router} from '#/routes'
import {Referrer} from '../modules/expo-bluesky-swiss-army' import {Referrer} from '../modules/expo-bluesky-swiss-army'
@@ -1065,11 +1072,52 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) {
// We will need to confirm we handle nested navigators correctly by the time we migrate to React Navigation 8.x // We will need to confirm we handle nested navigators correctly by the time we migrate to React Navigation 8.x
// -sfn // -sfn
navigationInChildEnabled> navigationInChildEnabled>
{children} <NavigationAnalyticsContext>{children}</NavigationAnalyticsContext>
</NavigationContainer> </NavigationContainer>
) )
} }
function getActiveRouteFromNavigationState(state?: NavigationState) {
if (!state) return undefined
const currentRoute = state?.routes[state.index]
return currentRoute.name
}
function NavigationAnalyticsContext({children}: {children: React.ReactNode}) {
const nav = useNavigation()
const [previousScreen, setPreviousScreen] = useState<string | undefined>(
() => getActiveRouteFromNavigationState(nav.getState()) ?? 'Home',
)
const [metadata, setMetadata] = useState<
Pick<AnalyticsContextType['metadata'], 'navigation'>
>(() => {
return {
navigation: {
previousScreen,
currentScreen: previousScreen,
},
}
})
useEffect(() => {
return nav.addListener('state', payload => {
const curr =
getActiveRouteFromNavigationState(payload.data.state) ?? 'Home'
setMetadata({
navigation: {
previousScreen,
currentScreen: curr,
},
})
setPreviousScreen(curr)
})
}, [nav, previousScreen])
return (
<AnalyticsContext metadata={utils.useMeta(metadata)}>
{children}
</AnalyticsContext>
)
}
function getCurrentRouteName() { function getCurrentRouteName() {
if (navigationRef.isReady()) { if (navigationRef.isReady()) {
return navigationRef.getCurrentRoute()?.name return navigationRef.getCurrentRoute()?.name
+2 -1
View File
@@ -12,10 +12,11 @@ import {
* Thin `useMemo` wrapper that marks the metadata as memoized and provides a * Thin `useMemo` wrapper that marks the metadata as memoized and provides a
* type guard. * type guard.
*/ */
export function useMeta(metadata: MergeableMetadata) { export function useMeta(metadata?: MergeableMetadata) {
const m = useMemo(() => metadata, [metadata]) const m = useMemo(() => metadata, [metadata])
// @ts-ignore // @ts-ignore
m.__meta = true m.__meta = true
console.log('useMeta', JSON.stringify(m, null, 2))
return m return m
} }
@@ -37,7 +37,6 @@ import {Onboarding} from '#/screens/Onboarding'
import {SignupQueued} from '#/screens/SignupQueued' import {SignupQueued} from '#/screens/SignupQueued'
import {atoms as a, useLayoutBreakpoints} from '#/alf' import {atoms as a, useLayoutBreakpoints} from '#/alf'
import {PolicyUpdateOverlay} from '#/components/PolicyUpdateOverlay' import {PolicyUpdateOverlay} from '#/components/PolicyUpdateOverlay'
import {AnalyticsContext, utils} from '#/analytics'
import {IS_NATIVE, IS_WEB} from '#/env' import {IS_NATIVE, IS_WEB} from '#/env'
import {BottomBarWeb} from './bottom-bar/BottomBarWeb' import {BottomBarWeb} from './bottom-bar/BottomBarWeb'
import {DesktopLeftNav} from './desktop/LeftNav' import {DesktopLeftNav} from './desktop/LeftNav'
@@ -47,8 +46,6 @@ type NativeStackNavigationOptionsWithAuth = NativeStackNavigationOptions & {
requireAuth?: boolean requireAuth?: boolean
} }
let prevActiveRouteName: string | undefined
function NativeStackNavigator({ function NativeStackNavigator({
id, id,
initialRouteName, initialRouteName,
@@ -117,7 +114,6 @@ function NativeStackNavigator({
const {setShowLoggedOut} = useLoggedOutViewControls() const {setShowLoggedOut} = useLoggedOutViewControls()
const {isMobile} = useWebMediaQueries() const {isMobile} = useWebMediaQueries()
const {leftNavMinimal} = useLayoutBreakpoints() const {leftNavMinimal} = useLayoutBreakpoints()
if (!hasSession && (activeRouteRequiresAuth || IS_NATIVE)) { if (!hasSession && (activeRouteRequiresAuth || IS_NATIVE)) {
return <LoggedOut /> return <LoggedOut />
} }
@@ -152,13 +148,6 @@ function NativeStackNavigator({
return ( return (
<NavigationContent> <NavigationContent>
<AnalyticsContext
metadata={utils.useMeta({
navigation: {
previousScreen: prevActiveRouteName || activeRoute.name,
currentScreen: activeRoute.name,
},
})}>
<View role="main" style={a.flex_1}> <View role="main" style={a.flex_1}>
<NativeStackView <NativeStackView
{...rest} {...rest}
@@ -177,7 +166,6 @@ function NativeStackNavigator({
{/* Only shown after logged in and onboaring etc are complete */} {/* Only shown after logged in and onboaring etc are complete */}
{hasSession && <PolicyUpdateOverlay />} {hasSession && <PolicyUpdateOverlay />}
</AnalyticsContext>
</NavigationContent> </NavigationContent>
) )
} }