fix(agent): 切换会话不再重挂载整页、不重播入场动画
控制台主内容区按 pathname 重挂载,每换一个会话整页透明 + 模糊再淡入, 左栏滚动、分页、展开状态全部丢失。智能体列表页与会话页共用一个 key。 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
ad3bf8926b
commit
177d21c26b
3 files changed
+33
-1
No files matched your search
@@ -0,0 +1,17 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { isAgentPage, outletKey } from "./agent-store.ts";
|
||||||
|
|
||||||
|
// 智能体页面切换的状态逻辑:整页重挂载 key、分栏与 URL、草稿、滚动策略、快捷键在智能体页面的行为。
|
||||||
|
|
||||||
|
describe("主内容区重挂载 key", () => {
|
||||||
|
it("列表页与各会话页共用一个 key,切换会话不重挂载", () => {
|
||||||
|
expect(outletKey("/console/agent")).toBe("/console/agent");
|
||||||
|
expect(outletKey("/console/agent/0b1c")).toBe("/console/agent");
|
||||||
|
expect(outletKey("/console/agent/9f2e")).toBe(outletKey("/console/agent/0b1c"));
|
||||||
|
});
|
||||||
|
it("其它页面仍按路径重挂载", () => {
|
||||||
|
expect(outletKey("/console/library")).toBe("/console/library");
|
||||||
|
expect(outletKey("/console/agents-x")).toBe("/console/agents-x");
|
||||||
|
expect(isAgentPage("/console/agentx")).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -123,6 +123,17 @@ export function contextFromPath(pathname: string): AgentContext | null {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 当前在不在智能体页面(列表页或会话页) */
|
||||||
|
export const isAgentPage = (pathname: string) => /^\/console\/agent(\/|$)/.test(pathname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制台主内容区的重挂载 key:智能体列表页与各会话页共用一个 key,
|
||||||
|
* 切换会话不重挂载整页、不重播入场动画,左栏的分栏 / 滚动 / 展开状态保留。
|
||||||
|
*/
|
||||||
|
export function outletKey(pathname: string): string {
|
||||||
|
return isAgentPage(pathname) ? "/console/agent" : pathname;
|
||||||
|
}
|
||||||
|
|
||||||
export function useAgentDrawer(): State {
|
export function useAgentDrawer(): State {
|
||||||
return useSyncExternalStore(
|
return useSyncExternalStore(
|
||||||
(l) => {
|
(l) => {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react
|
|||||||
import { Link, Outlet, useLocation, useMatches } from "react-router";
|
import { Link, Outlet, useLocation, useMatches } from "react-router";
|
||||||
import { useSession } from "~/api/auth.ts";
|
import { useSession } from "~/api/auth.ts";
|
||||||
import { AgentDrawer, AgentDrawerTrigger } from "~/components/agent/agent-drawer.tsx";
|
import { AgentDrawer, AgentDrawerTrigger } from "~/components/agent/agent-drawer.tsx";
|
||||||
|
import { outletKey } from "~/components/agent/agent-store.ts";
|
||||||
import { AccountMenu } from "~/components/console/account-menu.tsx";
|
import { AccountMenu } from "~/components/console/account-menu.tsx";
|
||||||
import { AgentLauncher, AgentNavEntry } from "~/components/console/agent-launcher.tsx";
|
import { AgentLauncher, AgentNavEntry } from "~/components/console/agent-launcher.tsx";
|
||||||
import { ErrorState } from "~/components/console/empty-state.tsx";
|
import { ErrorState } from "~/components/console/empty-state.tsx";
|
||||||
@@ -248,7 +249,10 @@ function ConsoleShell({ session }: { session: SessionInfo }) {
|
|||||||
|
|
||||||
{/* 底部留出悬浮按钮的高度,页面末尾的内容能滚到它上面 */}
|
{/* 底部留出悬浮按钮的高度,页面末尾的内容能滚到它上面 */}
|
||||||
<main className={cn("relative flex-1 overflow-x-clip", !wide && "px-4 pt-6 pb-24 md:px-6 md:pt-8")}>
|
<main className={cn("relative flex-1 overflow-x-clip", !wide && "px-4 pt-6 pb-24 md:px-6 md:pt-8")}>
|
||||||
<div key={location.pathname} className={cn(!wide && "mx-auto max-w-6xl", "motion-safe:animate-blur-in")}>
|
<div
|
||||||
|
key={outletKey(location.pathname)}
|
||||||
|
className={cn(!wide && "mx-auto max-w-6xl", "motion-safe:animate-blur-in")}
|
||||||
|
>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
Reference in new issue
Block a user