fix(webui): preserve newly created topic route

This commit is contained in:
chengyongru
2026-08-07 16:10:01 +08:00
committed by chengyongru
parent cdb2a474f9
commit edb3b7e446
2 changed files with 30 additions and 3 deletions
+13 -3
View File
@@ -1004,6 +1004,7 @@ function Shell({
useState<Record<string, WorkspaceScopePayload>>({});
const runningChatIdsRef = useRef<Set<string>>(new Set());
const activeChatIdRef = useRef<string | null>(null);
const pendingCreatedSessionKeyRef = useRef<string | null>(null);
const hostSidebarPreviewCloseTimerRef = useRef<number | null>(null);
const effectiveRuntimeSurface =
settingsSnapshot?.surface ?? settingsSnapshot?.runtime_surface ?? runtimeSurface;
@@ -1181,8 +1182,15 @@ function Shell({
}, [loading, sessions]);
useEffect(() => {
if (loading || !activeKey) return;
if (sessions.some((session) => session.key === activeKey)) return;
if (loading) return;
const pendingCreatedKey = pendingCreatedSessionKeyRef.current;
if (pendingCreatedKey && sessions.some((session) => session.key === pendingCreatedKey)) {
pendingCreatedSessionKeyRef.current = null;
}
if (!activeKey || sessions.some((session) => session.key === activeKey)) return;
// WebKit can commit the route before useSessions' optimistic insert.
// Keep that just-created destination valid until the session list catches up.
if (pendingCreatedKey === activeKey) return;
const currentRoute = readShellRoute();
navigate(
currentRoute.view === "chat"
@@ -1366,9 +1374,11 @@ function Shell({
try {
const scope = workspaceScope ?? activeWorkspaceScope;
const chatId = await createChat(scope);
const key = `websocket:${chatId}`;
pendingCreatedSessionKeyRef.current = key;
navigate({
view: "chat",
activeKey: `websocket:${chatId}`,
activeKey: key,
settingsSection: "overview",
});
setMobileSidebarOpen(false);
+17
View File
@@ -367,6 +367,23 @@ describe("App layout", () => {
);
});
it("keeps a just-created topic route while the session list catches up", async () => {
render(<App />);
await waitFor(() => expect(connectSpy).toHaveBeenCalled());
fireEvent.change(screen.getByRole("textbox", { name: "Message input" }), {
target: { value: "/model" },
});
fireEvent.click(screen.getByRole("button", { name: "Send message" }));
await waitFor(() => expect(createChatSpy).toHaveBeenCalledTimes(1));
await waitFor(() =>
expect(window.location.hash).toBe(
`#/chat/${encodeURIComponent("websocket:chat-1")}`,
),
);
});
it("restores the Settings route after a restart fallback hash", async () => {
localStorage.setItem("nanobot-webui.restartStartedAt", String(Date.now()));
localStorage.setItem("nanobot-webui.restartRoute", "#/settings?section=channels");