Checkpoint: works but feels hacky
This commit is contained in:
+51
-3
@@ -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
|
||||||
|
|||||||
@@ -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,32 +148,24 @@ function NativeStackNavigator({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationContent>
|
<NavigationContent>
|
||||||
<AnalyticsContext
|
<View role="main" style={a.flex_1}>
|
||||||
metadata={utils.useMeta({
|
<NativeStackView
|
||||||
navigation: {
|
{...rest}
|
||||||
previousScreen: prevActiveRouteName || activeRoute.name,
|
state={state}
|
||||||
currentScreen: activeRoute.name,
|
navigation={navigation}
|
||||||
},
|
descriptors={descriptors}
|
||||||
})}>
|
describe={describe}
|
||||||
<View role="main" style={a.flex_1}>
|
/>
|
||||||
<NativeStackView
|
</View>
|
||||||
{...rest}
|
{IS_WEB && (
|
||||||
state={state}
|
<>
|
||||||
navigation={navigation}
|
{showBottomBar ? <BottomBarWeb /> : <DesktopLeftNav />}
|
||||||
descriptors={descriptors}
|
{!isMobile && <DesktopRightNav routeName={activeRoute.name} />}
|
||||||
describe={describe}
|
</>
|
||||||
/>
|
)}
|
||||||
</View>
|
|
||||||
{IS_WEB && (
|
|
||||||
<>
|
|
||||||
{showBottomBar ? <BottomBarWeb /> : <DesktopLeftNav />}
|
|
||||||
{!isMobile && <DesktopRightNav routeName={activeRoute.name} />}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user