From bce60bce8e559aff4a1ceb153e6d2e115c3f7fea Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 8 Jun 2026 16:11:34 +0000 Subject: [PATCH] Preserve scroll when opening file viewer Co-Authored-By: Paperclip --- ui/src/context/FileViewerContext.test.ts | 8 ++++++++ ui/src/context/FileViewerContext.tsx | 9 +++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ui/src/context/FileViewerContext.test.ts b/ui/src/context/FileViewerContext.test.ts index 1a83db738b0..6196cc79a63 100644 --- a/ui/src/context/FileViewerContext.test.ts +++ b/ui/src/context/FileViewerContext.test.ts @@ -2,10 +2,18 @@ import { describe, expect, it } from "vitest"; import { + FILE_VIEWER_NAVIGATE_OPTIONS, readFileViewerStateFromSearch, writeFileViewerStateToSearch, } from "./FileViewerContext"; +describe("FILE_VIEWER_NAVIGATE_OPTIONS", () => { + it("preserves page scroll when the viewer updates URL search params", () => { + expect(FILE_VIEWER_NAVIGATE_OPTIONS.preventScrollReset).toBe(true); + expect(FILE_VIEWER_NAVIGATE_OPTIONS.replace).toBe(false); + }); +}); + describe("readFileViewerStateFromSearch", () => { it("returns null when no file param is present", () => { expect(readFileViewerStateFromSearch("")).toBeNull(); diff --git a/ui/src/context/FileViewerContext.tsx b/ui/src/context/FileViewerContext.tsx index 04721063d61..410471490b1 100644 --- a/ui/src/context/FileViewerContext.tsx +++ b/ui/src/context/FileViewerContext.tsx @@ -1,5 +1,5 @@ import { createContext, useContext, useCallback, useMemo, type ReactNode } from "react"; -import { useLocation, useNavigate } from "@/lib/router"; +import { useLocation, useNavigate, type NavigateOptions } from "@/lib/router"; import type { WorkspaceFileSelector } from "@paperclipai/shared"; import type { ParsedWorkspaceFileRef } from "@/lib/workspace-file-parser"; @@ -31,6 +31,11 @@ export interface FileViewerContextValue { const FileViewerContext = createContext(null); +export const FILE_VIEWER_NAVIGATE_OPTIONS = { + replace: false, + preventScrollReset: true, +} satisfies NavigateOptions; + export function readFileViewerStateFromSearch(search: string): FileViewerUrlState | null { const params = new URLSearchParams(search); const path = params.get("file"); @@ -100,7 +105,7 @@ export function FileViewerProvider({ issueId, children }: FileViewerProviderProp (nextSearch: string) => { navigate( { pathname: location.pathname, hash: location.hash, search: nextSearch }, - { state: location.state, replace: false }, + { ...FILE_VIEWER_NAVIGATE_OPTIONS, state: location.state }, ); }, [location.hash, location.pathname, location.state, navigate],