Skip to content

Commit 23931e9

Browse files
fix: preserve directory context through navigate state across session navigations
1 parent 0c56032 commit 23931e9

5 files changed

Lines changed: 271 additions & 24 deletions

File tree

frontend/src/components/session/SessionList.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ interface SessionListProps {
1515
createDirectory?: string;
1616
directoryLabels?: Record<string, string>;
1717
activeSessionID?: string;
18-
onSelectSession: (sessionID: string) => void;
18+
onSelectSession: (sessionID: string, directory?: string) => void;
1919
}
2020

2121
export const SessionList = ({
@@ -41,7 +41,7 @@ export const SessionList = ({
4141
const { data: sessions, isLoading, fetchNextPage, hasNextPage, isFetchingNextPage } = useSessionsAcrossDirectories(opcodeUrl, directoriesList, { search: searchQuery, limit: 25 });
4242
const deleteSession = useDeleteSession(opcodeUrl, directoriesList);
4343
const createSession = useCreateSession(opcodeUrl, sessionCreateDirectory, (newSession) => {
44-
onSelectSession(newSession.id);
44+
onSelectSession(newSession.id, primaryDirectory);
4545
});
4646
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
4747
const [sessionToDelete, setSessionToDelete] = useState<DeleteSessionTarget | DeleteSessionTarget[] | null>(null);
@@ -273,7 +273,7 @@ export const SessionList = ({
273273
isActive={activeSessionID === session.id}
274274
manageMode={manageMode}
275275
workspaceLabel={session.directory ? directoryLabels?.[session.directory] : undefined}
276-
onSelect={onSelectSession}
276+
onSelect={(sessionID) => onSelectSession(sessionID, session.directory ?? primaryDirectory)}
277277
onToggleSelection={(selected) => toggleSessionSelection(session, selected)}
278278
onDelete={(e) => handleDelete(session, e)}
279279
/>
@@ -292,7 +292,7 @@ export const SessionList = ({
292292
isActive={activeSessionID === session.id}
293293
manageMode={manageMode}
294294
workspaceLabel={session.directory ? directoryLabels?.[session.directory] : undefined}
295-
onSelect={onSelectSession}
295+
onSelect={(sessionID) => onSelectSession(sessionID, session.directory ?? primaryDirectory)}
296296
onToggleSelection={(selected) => toggleSessionSelection(session, selected)}
297297
onDelete={(e) => handleDelete(session, e)}
298298
/>

frontend/src/pages/AssistantRedirect.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useCallback, useEffect, useState } from "react"
22
import { useNavigate, useLocation } from "react-router-dom"
33
import { useQuery, useQueryClient } from "@tanstack/react-query"
44
import { getRepo } from "@/api/repos"
5+
import { OpenCodeClient } from "@/api/opencode"
56
import { setCachedAssistantSessionId, useAssistantSessionLauncher } from "@/hooks/useAssistantSessionLauncher"
67
import { useCreateSession } from "@/hooks/useOpenCode"
78
import { useDialogParam } from "@/hooks/useDialogParam"
@@ -16,7 +17,7 @@ import { RepoSkillsDialog } from "@/components/repo/RepoSkillsDialog"
1617
import { SourceControlPanel } from "@/components/source-control"
1718
import { ResetPermissionsDialog } from "@/components/repo/ResetPermissionsDialog"
1819
import { PendingActionsGroup } from "@/components/notifications/PendingActionsGroup"
19-
import { invalidateConfigCaches } from "@/lib/queryInvalidation"
20+
import { invalidateConfigCaches, messagesQueryKey } from "@/lib/queryInvalidation"
2021
import { getSessionListPath, getAssistantPath, getAssistantSessionListPath } from "@/lib/navigation"
2122
import { SwitchConfigDialog } from "@/components/repo/SwitchConfigDialog"
2223
import { Loader2, Plus } from "lucide-react"
@@ -45,13 +46,17 @@ export function AssistantRedirect() {
4546
const handleNavigate = useCallback((sessionId: string) => {
4647
if (repo?.fullPath) {
4748
setCachedAssistantSessionId(repoId, repo.fullPath, sessionId)
49+
void queryClient.prefetchQuery({
50+
queryKey: messagesQueryKey(opcodeUrl, sessionId, repo.fullPath),
51+
queryFn: () => new OpenCodeClient(opcodeUrl, repo.fullPath).listMessages(sessionId),
52+
})
4853
}
4954
setStatus("opening")
5055
if (!showSessionList) {
5156
window.history.replaceState(window.history.state, "", getSessionListPath(repoId, true))
5257
}
53-
navigate(`/repos/${repoId}/sessions/${sessionId}?assistant=1`)
54-
}, [navigate, repo?.fullPath, repoId, showSessionList])
58+
navigate(`/repos/${repoId}/sessions/${sessionId}?assistant=1`, { state: { directory: repo?.fullPath } })
59+
}, [navigate, opcodeUrl, queryClient, repo?.fullPath, repoId, showSessionList])
5560

5661
const handleMissingCachedSession = useCallback(() => {
5762
navigate(getAssistantSessionListPath(), { replace: true })
@@ -74,14 +79,15 @@ export function AssistantRedirect() {
7479
if (assistantDirectory) {
7580
setCachedAssistantSessionId(repoId, assistantDirectory, session.id)
7681
}
77-
navigate(`/repos/${repoId}/sessions/${session.id}?assistant=1`)
82+
navigate(`/repos/${repoId}/sessions/${session.id}?assistant=1`, { state: { directory: assistantDirectory } })
7883
})
7984

80-
const handleSelectSession = useCallback((sessionId: string) => {
81-
if (assistantDirectory) {
82-
setCachedAssistantSessionId(repoId, assistantDirectory, sessionId)
85+
const handleSelectSession = useCallback((sessionId: string, directory?: string) => {
86+
const selectedDirectory = directory ?? assistantDirectory
87+
if (selectedDirectory) {
88+
setCachedAssistantSessionId(repoId, selectedDirectory, sessionId)
8389
}
84-
navigate(`/repos/${repoId}/sessions/${sessionId}?assistant=1`)
90+
navigate(`/repos/${repoId}/sessions/${sessionId}?assistant=1`, { state: { directory: selectedDirectory } })
8591
}, [assistantDirectory, navigate, repoId])
8692

8793
const handleCreateSession = async () => {

frontend/src/pages/RepoDetail.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export function RepoDetail() {
114114
);
115115

116116
const createSessionMutation = useCreateSession(opcodeUrl, composerDirectory, (session) => {
117-
navigate(sessionUrl(session.id));
117+
navigate(sessionUrl(session.id), { state: { directory: composerDirectory } });
118118
});
119119

120120
const handleCreateSession = async (options?: {
@@ -149,8 +149,8 @@ export function RepoDetail() {
149149
setWorkspaceSelectorOpen(true);
150150
};
151151

152-
const handleSelectSession = (sessionId: string) => {
153-
navigate(sessionUrl(sessionId));
152+
const handleSelectSession = (sessionId: string, directory?: string) => {
153+
navigate(sessionUrl(sessionId), { state: { directory: directory ?? composerDirectory } });
154154
};
155155

156156
useSidebarAction('new-session', () => {

frontend/src/pages/SessionDetail.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export function SessionDetail() {
6868
const { id, sessionId } = useParams<{ id: string; sessionId: string }>();
6969
const navigate = useNavigate();
7070
const location = useLocation();
71+
const navigationDirectory = (location.state as { directory?: string } | null)?.directory;
7172
const repoId = Number(id) || 0;
7273
const isAssistantSession = new URLSearchParams(location.search).get('assistant') === '1';
7374
const { preferences, updateSettings } = useSettings();
@@ -119,7 +120,7 @@ export function SessionDetail() {
119120

120121
const opcodeUrl = OPENCODE_API_ENDPOINT;
121122

122-
const repoDirectory = repo?.fullPath;
123+
const repoDirectory = navigationDirectory ?? repo?.fullPath;
123124
const sessionRouteSuffix = isAssistantSession ? '?assistant=1' : '';
124125

125126
useEffect(() => {
@@ -244,7 +245,7 @@ export function SessionDetail() {
244245
if (isAssistantSession && repoDirectory) {
245246
setCachedAssistantSessionId(repoId, repoDirectory, newSession.id);
246247
}
247-
navigate(`/repos/${repoId}/sessions/${newSession.id}${sessionRouteSuffix}`);
248+
navigate(`/repos/${repoId}/sessions/${newSession.id}${sessionRouteSuffix}`, { state: { directory: repoDirectory } });
248249
}
249250
} catch {
250251
showToast.error('Failed to create new session');
@@ -298,7 +299,7 @@ export function SessionDetail() {
298299
const client = createOpenCodeClient(opcodeUrl, repoDirectory);
299300
const forkedSession = await client.forkSession(sessionId);
300301
if (forkedSession?.id) {
301-
navigate(`/repos/${repoId}/sessions/${forkedSession.id}${sessionRouteSuffix}`);
302+
navigate(`/repos/${repoId}/sessions/${forkedSession.id}${sessionRouteSuffix}`, { state: { directory: repoDirectory } });
302303
showToast.success('Session forked');
303304
}
304305
} catch (error) {
@@ -375,14 +376,14 @@ export function SessionDetail() {
375376
}, [setFileBrowserOpen]);
376377

377378
const handleChildSessionClick = useCallback((childSessionId: string) => {
378-
navigate(`/repos/${repoId}/sessions/${childSessionId}${sessionRouteSuffix}`)
379-
}, [navigate, repoId, sessionRouteSuffix]);
379+
navigate(`/repos/${repoId}/sessions/${childSessionId}${sessionRouteSuffix}`, { state: { directory: repoDirectory } })
380+
}, [navigate, repoDirectory, repoId, sessionRouteSuffix]);
380381

381382
const handleParentSessionClick = useCallback(() => {
382383
if (session?.parentID) {
383-
navigate(`/repos/${repoId}/sessions/${session.parentID}${sessionRouteSuffix}`)
384+
navigate(`/repos/${repoId}/sessions/${session.parentID}${sessionRouteSuffix}`, { state: { directory: repoDirectory } })
384385
}
385-
}, [navigate, repoId, session?.parentID, sessionRouteSuffix]);
386+
}, [navigate, repoDirectory, repoId, session?.parentID, sessionRouteSuffix]);
386387

387388
const handleToggleDetails = useCallback(() => {
388389
const newValue = !preferences?.expandToolCalls
@@ -590,8 +591,8 @@ export function SessionDetail() {
590591
opcodeUrl={opcodeUrl}
591592
directory={repoDirectory}
592593
activeSessionID={sessionId || undefined}
593-
onSelectSession={(sessionID) => {
594-
navigate(`/repos/${repoId}/sessions/${sessionID}${sessionRouteSuffix}`)
594+
onSelectSession={(sessionID, directory) => {
595+
navigate(`/repos/${repoId}/sessions/${sessionID}${sessionRouteSuffix}`, { state: { directory: directory ?? repoDirectory } })
595596
setSessionsDialogOpen(false)
596597
}}
597598
/>

0 commit comments

Comments
 (0)