From 06ebd2964ab68aa295f3385c188f40c33e3e0a23 Mon Sep 17 00:00:00 2001
From: Samuel Newman <mozzius@protonmail.com>
Date: Wed, 18 Jun 2025 19:25:14 +0300
Subject: Fix linking to specific search results (#8520)

* fix linking to bsky.app/search?q=xyz

* add name to comment

* skip if notfound
---
 src/components/Link.tsx | 43 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 7 deletions(-)

(limited to 'src/components/Link.tsx')

diff --git a/src/components/Link.tsx b/src/components/Link.tsx
index d0f8678ff..28cd19418 100644
--- a/src/components/Link.tsx
+++ b/src/components/Link.tsx
@@ -9,7 +9,7 @@ import {
 import {BSKY_DOWNLOAD_URL} from '#/lib/constants'
 import {useNavigationDeduped} from '#/lib/hooks/useNavigationDeduped'
 import {useOpenLink} from '#/lib/hooks/useOpenLink'
-import {type AllNavigatorParams} from '#/lib/routes/types'
+import {type AllNavigatorParams, type RouteParams} from '#/lib/routes/types'
 import {shareUrl} from '#/lib/sharing'
 import {
   convertBskyAppUrlIfNeeded,
@@ -155,15 +155,44 @@ export function useLink({
           } else {
             closeModal() // close any active modals
 
+            const [screen, params] = router.matchPath(href) as [
+              screen: keyof AllNavigatorParams,
+              params?: RouteParams,
+            ]
+
+            // does not apply to web's flat navigator
+            if (isNative && screen !== 'NotFound') {
+              const state = navigation.getState()
+              // if screen is not in the current navigator, it means it's
+              // most likely a tab screen
+              if (!state.routeNames.includes(screen)) {
+                const parent = navigation.getParent()
+                if (
+                  parent &&
+                  parent.getState().routeNames.includes(`${screen}Tab`)
+                ) {
+                  // yep, it's a tab screen. i.e. SearchTab
+                  // thus we need to navigate to the child screen
+                  // via the parent navigator
+                  // see https://reactnavigation.org/docs/upgrading-from-6.x/#changes-to-the-navigate-action
+                  // TODO: can we support the other kinds of actions? push/replace -sfn
+
+                  // @ts-expect-error include does not narrow the type unfortunately
+                  parent.navigate(`${screen}Tab`, {screen, params})
+                  return
+                } else {
+                  // will probably fail, but let's try anyway
+                }
+              }
+            }
+
             if (action === 'push') {
-              navigation.dispatch(StackActions.push(...router.matchPath(href)))
+              navigation.dispatch(StackActions.push(screen, params))
             } else if (action === 'replace') {
-              navigation.dispatch(
-                StackActions.replace(...router.matchPath(href)),
-              )
+              navigation.dispatch(StackActions.replace(screen, params))
             } else if (action === 'navigate') {
-              // @ts-ignore
-              navigation.navigate(...router.matchPath(href))
+              // @ts-expect-error not typed
+              navigation.navigate(screen, params)
             } else {
               throw Error('Unsupported navigator action.')
             }
-- 
cgit 1.4.1

