History

Retarget diff panel to active route thread on visit

- Prefer route thread id over stored diff thread when rendering diffs - When visiting a different thread with diff open, retarget diff state and clear stale turn/file selection - Add reducer test coverage for open-diff retargeting behavior

Julius Marminge committed 8 months ago

Commit b253d1f1 parent 564474f3 files · +58 −1Browse files

Unified · Split

3 files
  1. apps/web/src/components/DiffPanel.tsx +12 −1
  2. apps/web/src/store.test.ts +42 −0
  3. apps/web/src/store.ts +4 −0
apps/web/src/components/DiffPanel.tsx+12−1
@@ -107,7 +107,7 @@ export default function DiffPanel({ mode = "inline" }: DiffPanelProps) { · 106 unmodified lines
107107 const patchViewportRef = useRef<HTMLDivElement>(null);
108108 const params = useParams({ strict: false });
109109 const routeThreadId = typeof params.threadId === "string" ? params.threadId : null;
110− const activeThreadId = state.diffThreadId ?? routeThreadId;
110+ const activeThreadId = routeThreadId ?? state.diffThreadId;
111111 const activeThread = state.threads.find((thread) => thread.id === activeThreadId);
112112 const activeThreadRuntimeId =
113113 activeThread?.codexThreadId ?? activeThread?.session?.threadId ?? null;
@@ -216,6 +216,17 @@ export default function DiffPanel({ mode = "inline" }: DiffPanelProps) { · 102 unmodified lines
216216 target?.scrollIntoView({ block: "nearest" });
217217 }, [selectedFilePath, renderableFiles]);
218218
219+ useEffect(() => {
220+ if (!state.diffOpen) return;
221+ if (!routeThreadId) return;
222+ if (state.diffThreadId === routeThreadId) return;
223+
224+ dispatch({
225+ type: "SET_DIFF_TARGET",
226+ threadId: routeThreadId,
227+ });
228+ }, [dispatch, routeThreadId, state.diffOpen, state.diffThreadId]);
229+
219230 const selectTurn = (turnId: string) => {
220231 if (!activeThread) return;
221232 dispatch({
apps/web/src/store.test.ts+42−0
@@ -833,6 +833,48 @@ describe("store reducer thread continuity", () => { · 832 unmodified lines
833833 expect(next.threads[0]?.lastVisitedAt).toBe(nextVisitedAt);
834834 });
835835
836+ it("retargets open diff state to the visited thread", () => {
837+ const state: AppState = {
838+ ...makeState(
839+ makeThread({
840+ id: "thread-local-1",
841+ latestTurnCompletedAt: "2026-02-08T10:00:10.000Z",
842+ lastVisitedAt: "2026-02-08T10:00:00.000Z",
843+ }),
844+ ),
845+ threads: [
846+ makeThread({
847+ id: "thread-local-1",
848+ latestTurnCompletedAt: "2026-02-08T10:00:10.000Z",
849+ lastVisitedAt: "2026-02-08T10:00:00.000Z",
850+ }),
851+ makeThread({
852+ id: "thread-local-2",
853+ session: makeSession({ sessionId: "sess-2" }),
854+ latestTurnCompletedAt: "2026-02-08T09:00:10.000Z",
855+ lastVisitedAt: "2026-02-08T09:00:00.000Z",
856+ }),
857+ ],
858+ diffOpen: true,
859+ diffThreadId: "thread-local-1",
860+ diffTurnId: "turn-1",
861+ diffFilePath: "src/old.ts",
862+ };
863+
864+ const nextVisitedAt = "2026-02-08T10:00:20.000Z";
865+ const next = reducer(state, {
866+ type: "MARK_THREAD_VISITED",
867+ threadId: "thread-local-2",
868+ visitedAt: nextVisitedAt,
869+ });
870+
871+ expect(next.threads[1]?.lastVisitedAt).toBe(nextVisitedAt);
872+ expect(next.diffOpen).toBe(true);
873+ expect(next.diffThreadId).toBe("thread-local-2");
874+ expect(next.diffTurnId).toBeNull();
875+ expect(next.diffFilePath).toBeNull();
876+ });
877+
836878 it("reverts thread state to a checkpoint snapshot", () => {
837879 const state = makeState(
838880 makeThread({
apps/web/src/store.ts+4−0
@@ -1078,12 +1078,16 @@ export function reducer(state: AppState, action: Action): AppState { · 1077 unmodified lines
10781078
10791079 case "MARK_THREAD_VISITED": {
10801080 const visitedAt = action.visitedAt ?? new Date().toISOString();
1081+ const shouldRetargetOpenDiff = state.diffOpen && state.diffThreadId !== action.threadId;
10811082 return {
10821083 ...state,
10831084 threads: updateThread(state.threads, action.threadId, (t) => ({
10841085 ...t,
10851086 lastVisitedAt: visitedAt,
10861087 })),
1088+ diffThreadId: shouldRetargetOpenDiff ? action.threadId : state.diffThreadId,
1089+ diffTurnId: shouldRetargetOpenDiff ? null : state.diffTurnId,
1090+ diffFilePath: shouldRetargetOpenDiff ? null : state.diffFilePath,
10871091 };
10881092 }
10891093

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t