From 1c99cbd0332de99dae82d5ee3092e0c04d02aacb Mon Sep 17 00:00:00 2001 From: Innei Date: Sun, 30 Mar 2025 21:57:47 +0800 Subject: [PATCH] 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 --- apps/mobile/src/lib/navigation/Navigation.ts | 12 +------- .../src/lib/navigation/StackNavigation.tsx | 4 +-- .../src/lib/navigation/WrappedScreenItem.tsx | 25 +++++++++++++---- .../src/lib/navigation/__internal/hooks.ts | 28 +++++++++++-------- apps/mobile/src/screens/(modal)/login.tsx | 2 +- 5 files changed, 40 insertions(+), 31 deletions(-) diff --git a/apps/mobile/src/lib/navigation/Navigation.ts b/apps/mobile/src/lib/navigation/Navigation.ts index ce3b1a866..de502241d 100644 --- a/apps/mobile/src/lib/navigation/Navigation.ts +++ b/apps/mobile/src/lib/navigation/Navigation.ts @@ -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, []) } diff --git a/apps/mobile/src/lib/navigation/StackNavigation.tsx b/apps/mobile/src/lib/navigation/StackNavigation.tsx index 4e99c318c..ffe3edcc1 100644 --- a/apps/mobile/src/lib/navigation/StackNavigation.tsx +++ b/apps/mobile/src/lib/navigation/StackNavigation.tsx @@ -35,7 +35,7 @@ export const RootStackNavigation = ({ children, headerConfig }: RootStackNavigat atom(""), [])}> @@ -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) diff --git a/apps/mobile/src/lib/navigation/WrappedScreenItem.tsx b/apps/mobile/src/lib/navigation/WrappedScreenItem.tsx index e62229750..d5a1faf2a 100644 --- a/apps/mobile/src/lib/navigation/WrappedScreenItem.tsx +++ b/apps/mobile/src/lib/navigation/WrappedScreenItem.tsx @@ -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>( () => 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 ( @@ -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} >
{children} diff --git a/apps/mobile/src/lib/navigation/__internal/hooks.ts b/apps/mobile/src/lib/navigation/__internal/hooks.ts index b3f68cc46..3566565a2 100644 --- a/apps/mobile/src/lib/navigation/__internal/hooks.ts +++ b/apps/mobile/src/lib/navigation/__internal/hooks.ts @@ -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]) diff --git a/apps/mobile/src/screens/(modal)/login.tsx b/apps/mobile/src/screens/(modal)/login.tsx index 8da624e63..4a7a6ec00 100644 --- a/apps/mobile/src/screens/(modal)/login.tsx +++ b/apps/mobile/src/screens/(modal)/login.tsx @@ -32,7 +32,7 @@ export const LoginScreen: NavigationControllerView = () => { {!!whoami?.id && __DEV__ && ( { exit()