fix(web): preserve view mode and path when switching refs

Quentin Gliech and Claude Opus 4.6 (1M context) created

the ref selector now navigates to the same view (tree/blob/commits)
and path on the new ref, instead of always resetting to tree root

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Change summary

webui2/src/routes/$repo/_code.tsx | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)

Detailed changes

webui2/src/routes/$repo/_code.tsx 🔗

@@ -39,6 +39,11 @@ function CodeLayout() {
   const currentPath = allParams._splat ?? "";
 
   const matchRoute = useMatchRoute();
+  const isBlobView = !!matchRoute({
+    to: "/$repo/blob/$ref/$",
+    params: { repo, ref: currentRef, _splat: currentPath },
+    fuzzy: true,
+  });
   const isCommitsView = !!matchRoute({
     to: "/$repo/commits/$ref",
     params: { repo, ref: currentRef },
@@ -47,11 +52,23 @@ function CodeLayout() {
 
   const navigate = useNavigate();
 
-  function handleRefSelect(ref: GitRef) {
-    void navigate({
-      to: "/$repo/tree/$ref/$",
-      params: { repo, ref: ref.shortName, _splat: "" },
-    });
+  function handleRefSelect(newRef: GitRef) {
+    if (isCommitsView) {
+      void navigate({
+        to: "/$repo/commits/$ref",
+        params: { repo, ref: newRef.shortName },
+      });
+    } else if (isBlobView) {
+      void navigate({
+        to: "/$repo/blob/$ref/$",
+        params: { repo, ref: newRef.shortName, _splat: currentPath },
+      });
+    } else {
+      void navigate({
+        to: "/$repo/tree/$ref/$",
+        params: { repo, ref: newRef.shortName, _splat: currentPath },
+      });
+    }
   }
 
   return (