Fix back swipe opening the drawer after a cold-start deep link (#11065)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-07-07 16:51:06 +03:00
committed by GitHub
parent 5e24a0b48c
commit 102905b962
3 changed files with 130 additions and 9 deletions
+2 -5
View File
@@ -30,7 +30,7 @@ import {
} from '#/lib/hooks/useNotificationHandler'
import {useWebScrollRestoration} from '#/lib/hooks/useWebScrollRestoration'
import {useCallOnce} from '#/lib/once'
import {buildStateObject} from '#/lib/routes/helpers'
import {buildStateObject, getCurrentRoute} from '#/lib/routes/helpers'
import {
type AllNavigatorParams,
type BottomTabNavigatorParams,
@@ -783,10 +783,7 @@ const LINKING = {
getPathFromState(state: State) {
// find the current node in the navigation tree
let node = state.routes[state.index || 0]
while (node.state?.routes && typeof node.state?.index === 'number') {
node = node.state?.routes[node.state?.index]
}
const node = getCurrentRoute(state)
// build the path
const route = router.matchName(node.name)
+21 -4
View File
@@ -13,12 +13,20 @@ export function getRootNavigation<T extends {}>(
export function getCurrentRoute(state?: State) {
if (!state) {
return {name: 'Home'}
return {name: 'Home', params: undefined}
}
/*
* Nested navigator states may still be partial ("stale") right after a cold
* start from a deep link, in which case `index` is not set yet. React
* Navigation focuses the last route when it rehydrates such a state, so
* mirror that here instead of stopping the descent early and misreporting
* the tab root as the current route (which e.g. re-enabled the drawer
* swipe gesture on top of a deep-linked screen).
*/
let node = state.routes[state.index || 0]
while (node.state?.routes && typeof node.state?.index === 'number') {
node = node.state?.routes[node.state?.index]
while (node.state?.routes) {
node = node.state.routes[node.state.index ?? node.state.routes.length - 1]
}
return node
}
@@ -83,15 +91,24 @@ export function buildStateObject(
) {
if (stack === 'Flat') {
return {
index: 0,
routes: [{name: route, params}],
}
}
/*
* Set `index` explicitly so consumers of this state (e.g. getCurrentRoute)
* can tell which route is focused before React Navigation has rehydrated
* the nested navigator state.
*/
const routes = [...state, {name: route, params}]
return {
index: 0,
routes: [
{
name: stack,
state: {
routes: [...state, {name: route, params}],
index: routes.length - 1,
routes,
},
},
],