refactor: rename internal context retrieval method and remove unused popTo function

- Renamed `__internal_getCtxValue` to `__dangerous_getCtxValue` for clarity.
- Removed the unused `popTo` method from the Navigation class.
- Updated references to the renamed method in StackNavigation and WrappedScreenItem components.
- Introduced a new `handleDismiss` function in WrappedScreenItem to handle dismiss events more effectively.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei 2025-03-30 21:57:47 +08:00
parent 14ae20fb5a
commit 1c99cbd033
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
5 changed files with 40 additions and 31 deletions

View File

@ -18,11 +18,10 @@ export class Navigation {
this.presentControllerView = this.presentControllerView.bind(this)
this.dismiss = this.dismiss.bind(this)
this.back = this.back.bind(this)
this.popTo = this.popTo.bind(this)
this.popToRoot = this.popToRoot.bind(this)
}
__internal_getCtxValue() {
__dangerous_getCtxValue() {
return this.ctxValue
}
@ -156,15 +155,6 @@ export class Navigation {
return routes.length > 0
}
popTo(routeId: string) {
const routes = jotaiStore.get(this.ctxValue.routesAtom)
const index = routes.findIndex((r) => r.id === routeId)
if (index === -1) {
return
}
jotaiStore.set(this.ctxValue.routesAtom, routes.slice(0, index + 1))
}
popToRoot() {
jotaiStore.set(this.ctxValue.routesAtom, [])
}

View File

@ -35,7 +35,7 @@ export const RootStackNavigation = ({ children, headerConfig }: RootStackNavigat
<AttachNavigationScrollViewProvider>
<ScreenNameContext.Provider value={useMemo(() => atom(""), [])}>
<ChainNavigationContext.Provider
value={Navigation.rootNavigation.__internal_getCtxValue()}
value={Navigation.rootNavigation.__dangerous_getCtxValue()}
>
<NavigationInstanceContext.Provider value={Navigation.rootNavigation}>
<ScreenStack style={StyleSheet.absoluteFill}>
@ -76,7 +76,7 @@ const StateHandler = () => {
return navigation.on("screenChange", (payload) => {
if (!payload.route) return
const Component = payload.route.Component as NavigationControllerView
const state = jotaiStore.get(navigationInstance.__internal_getCtxValue().routesAtom)
const state = jotaiStore.get(navigationInstance.__dangerous_getCtxValue().routesAtom)
if (payload.type === "appear" && state.at(-1)?.id === payload.route.id) {
previousName.current = jotaiStore.get(nameAtom)
jotaiStore.set(nameAtom, Component.title || Component.displayName || Component.name)

View File

@ -2,7 +2,8 @@ import { isUndefined } from "es-toolkit/compat"
import type { PrimitiveAtom } from "jotai"
import { atom, useAtomValue, useSetAtom } from "jotai"
import type { FC, ReactNode } from "react"
import { memo, useContext, useMemo } from "react"
import { memo, useCallback, useContext, useMemo } from "react"
import type { NativeSyntheticEvent } from "react-native"
import { StyleSheet, View } from "react-native"
import { useSharedValue } from "react-native-reanimated"
import type { ScreenStackHeaderConfigProps, StackPresentationTypes } from "react-native-screens"
@ -88,7 +89,7 @@ export const WrappedScreenItem: FC<
setIsAppeared(false)
setIsDisappeared(true)
},
})
}) as any
const screenOptionsCtxValue = useMemo<PrimitiveAtom<ScreenOptionsContextType>>(
() => atom({}),
@ -108,6 +109,21 @@ export const WrappedScreenItem: FC<
}),
[screenOptionsFromCtx, screenOptionsProp],
)
const handleDismiss = useCallback(
(
e: NativeSyntheticEvent<{
dismissCount: number
}>,
) => {
if (e.nativeEvent.dismissCount > 0) {
for (let i = 0; i < e.nativeEvent.dismissCount; i++) {
navigation.__internal_dismiss(screenId)
}
}
},
[navigation, screenId],
)
return (
<ScreenItemContext.Provider value={ctxValue}>
<ScreenOptionsContext.Provider value={screenOptionsCtxValue}>
@ -124,11 +140,10 @@ export const WrappedScreenItem: FC<
StyleSheet.absoluteFill,
{ backgroundColor: screenOptionsProp?.transparent ? undefined : backgroundColor },
]}
onDismissed={() => {
navigation.__internal_dismiss(screenId)
}}
{...rest}
{...mergedScreenOptions}
onDismissed={handleDismiss}
onNativeDismissCancelled={handleDismiss}
>
<Header />
{children}

View File

@ -1,7 +1,11 @@
import { useEffect, useMemo, useRef } from "react"
import type { NativeSyntheticEvent } from "react-native"
import { useNavigation } from "../hooks"
type LifecycleEvent = NativeSyntheticEvent<{
dismissCount: number
}>
export const useCombinedLifecycleEvents = (
screenId: string,
{
@ -10,10 +14,10 @@ export const useCombinedLifecycleEvents = (
onWillAppear,
onWillDisappear,
}: {
onAppear?: () => void
onDisappear?: () => void
onWillAppear?: () => void
onWillDisappear?: () => void
onAppear?: (e: LifecycleEvent) => void
onDisappear?: (e: LifecycleEvent) => void
onWillAppear?: (e: LifecycleEvent) => void
onWillDisappear?: (e: LifecycleEvent) => void
} = {},
) => {
const navigation = useNavigation()
@ -34,21 +38,21 @@ export const useCombinedLifecycleEvents = (
}, [onAppear, onDisappear, onWillAppear, onWillDisappear])
return useMemo(() => {
return {
onAppear: () => {
onAppear: (e: LifecycleEvent) => {
navigation.emit("didAppear", { screenId })
stableRef.current.onAppear?.()
stableRef.current.onAppear?.(e)
},
onDisappear: () => {
onDisappear: (e: LifecycleEvent) => {
navigation.emit("didDisappear", { screenId })
stableRef.current.onDisappear?.()
stableRef.current.onDisappear?.(e)
},
onWillAppear: () => {
onWillAppear: (e: LifecycleEvent) => {
navigation.emit("willAppear", { screenId })
stableRef.current.onWillAppear?.()
stableRef.current.onWillAppear?.(e)
},
onWillDisappear: () => {
onWillDisappear: (e: LifecycleEvent) => {
navigation.emit("willDisappear", { screenId })
stableRef.current.onWillDisappear?.()
stableRef.current.onWillDisappear?.(e)
},
}
}, [navigation, screenId])

View File

@ -32,7 +32,7 @@ export const LoginScreen: NavigationControllerView = () => {
<HeaderCloseOnly />
{!!whoami?.id && __DEV__ && (
<TouchableOpacity
className="bg-system-fill absolute bottom-8 left-1/2 -translate-x-1/2 flex-row items-center justify-center rounded-xl p-2 px-4"
className="bg-system-fill bottom-safe-offset-8 absolute left-1/2 -translate-x-1/2 flex-row items-center justify-center rounded-xl p-2 px-4"
activeOpacity={0.7}
onPress={() => {
exit()