Preserve thread selection during background updates
This commit is contained in:
@@ -63,9 +63,12 @@ import {
|
||||
type WorkspaceItem,
|
||||
} from "@/lib/api";
|
||||
import { useSessionAuth } from "@/hooks/use-session-auth";
|
||||
import {
|
||||
resolveSidebarSelectionAfterRefresh,
|
||||
type SidebarSelection,
|
||||
} from "@/lib/sidebar-selection";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
type SidebarSelection = { kind: "chat" | "search"; id: string };
|
||||
type DraftSelectionKind = "chat" | "search";
|
||||
type SidebarItem = SidebarSelection & {
|
||||
title: string;
|
||||
@@ -94,7 +97,7 @@ type ActiveRunsState = {
|
||||
searches: Record<string, true>;
|
||||
};
|
||||
type RefreshCollectionsOptions = {
|
||||
preferredSelection?: SidebarSelection;
|
||||
initialSelection?: SidebarSelection;
|
||||
reportTransientError?: boolean;
|
||||
selectFallback?: boolean;
|
||||
};
|
||||
@@ -1131,7 +1134,7 @@ export default function App() {
|
||||
};
|
||||
|
||||
const refreshCollections = async ({
|
||||
preferredSelection,
|
||||
initialSelection,
|
||||
reportTransientError = true,
|
||||
selectFallback = false,
|
||||
}: RefreshCollectionsOptions = {}) => {
|
||||
@@ -1143,24 +1146,12 @@ export default function App() {
|
||||
setChats(nextChats);
|
||||
setSearches(nextSearches);
|
||||
|
||||
setSelectedItem((current) => {
|
||||
const hasItem = (candidate: SidebarSelection | null) => {
|
||||
if (!candidate) return false;
|
||||
return nextWorkspaceItems.some((item) => item.type === candidate.kind && item.id === candidate.id);
|
||||
};
|
||||
|
||||
if (preferredSelection && hasItem(preferredSelection)) {
|
||||
return preferredSelection;
|
||||
}
|
||||
if (hasItem(current)) {
|
||||
return current;
|
||||
}
|
||||
if (!selectFallback) {
|
||||
return null;
|
||||
}
|
||||
const first = nextWorkspaceItems[0];
|
||||
return first ? { kind: first.type, id: first.id } : null;
|
||||
});
|
||||
setSelectedItem((current) =>
|
||||
resolveSidebarSelectionAfterRefresh(current, nextWorkspaceItems, {
|
||||
initialSelection,
|
||||
selectFallback,
|
||||
})
|
||||
);
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
if (message.includes("bearer token")) {
|
||||
@@ -1252,10 +1243,10 @@ export default function App() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAuthenticated) return;
|
||||
const preferredSelection = initialRouteSelectionRef.current;
|
||||
const initialSelection = initialRouteSelectionRef.current;
|
||||
initialRouteSelectionRef.current = null;
|
||||
void Promise.all([
|
||||
refreshCollections({ preferredSelection: preferredSelection ?? undefined, selectFallback: true }),
|
||||
refreshCollections({ initialSelection: initialSelection ?? undefined, selectFallback: true }),
|
||||
refreshModels(),
|
||||
refreshChatTools(),
|
||||
refreshActiveRuns(),
|
||||
@@ -2480,7 +2471,7 @@ export default function App() {
|
||||
|
||||
backgroundSuspendedChatStreamsRef.current.delete(chatId);
|
||||
const persistedChat = await retryAfterAppResume(() => getChat(chatId));
|
||||
await refreshCollections({ preferredSelection: target, reportTransientError: false });
|
||||
await refreshCollections({ reportTransientError: false });
|
||||
if (isCurrentSelection(target)) {
|
||||
setSelectedChat(persistedChat);
|
||||
setSelectedSearch(null);
|
||||
@@ -2694,7 +2685,7 @@ export default function App() {
|
||||
}
|
||||
}
|
||||
|
||||
await refreshCollections({ preferredSelection: target });
|
||||
await refreshCollections();
|
||||
return target;
|
||||
};
|
||||
|
||||
@@ -2813,7 +2804,7 @@ export default function App() {
|
||||
setSelectedChat(persistedChat);
|
||||
setSelectedSearch(null);
|
||||
}
|
||||
void refreshCollections({ preferredSelection: target });
|
||||
void refreshCollections();
|
||||
return;
|
||||
} catch (resumeError) {
|
||||
err = resumeError;
|
||||
@@ -2919,7 +2910,7 @@ export default function App() {
|
||||
{ signal: abortController.signal }
|
||||
);
|
||||
|
||||
await refreshCollections({ preferredSelection: target });
|
||||
await refreshCollections();
|
||||
if (isCurrentSelection(target)) {
|
||||
await refreshSearch(searchId);
|
||||
}
|
||||
@@ -2987,7 +2978,7 @@ export default function App() {
|
||||
messages: [],
|
||||
});
|
||||
setSelectedSearch(null);
|
||||
await refreshCollections({ preferredSelection: { kind: "chat", id: chat.id } });
|
||||
await refreshCollections();
|
||||
await refreshChat(chat.id);
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
@@ -3149,7 +3140,7 @@ export default function App() {
|
||||
messages: [],
|
||||
});
|
||||
setSelectedSearch(null);
|
||||
await refreshCollections({ preferredSelection: { kind: "chat", id: chat.id } });
|
||||
await refreshCollections();
|
||||
await refreshChat(chat.id);
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
|
||||
Reference in New Issue
Block a user