修复「新对话」流式中无法重置 + 参考文献开关默认关闭并加对勾

- 流式回答过程中点「新对话」:URL 同路径导致 react-router navigate 静默 no-op,
  下游 hook 收不到事件;改为显式 navigate(..., {replace:true, state:{resetAt}})
  保证每次点击刷新 location.key,并让 useThreadChat 监听 location.key 触发重置
- useThreadStream 在 threadId 变化时 stop() 掉上一条 SSE,避免旧流继续派发事件
- 引入 KeyedChatPage 用 location.key 作 ChatRuntime key,真正的导航触发整树 remount,
  解决 useStream 内部 stream.values 残留导致欢迎页底下还能看到旧消息的过渡帧问题
- 「参考文献」开关默认关闭(local.ts),开启态在文字前额外多一个 ✓ 对勾
This commit is contained in:
吉鑫升 committed 2026-05-25 19:47:55 +08:00
1 parent a800baf8ae
commit b7aa8b06ca
6 files changed
+120 -62

No files matched your search

+16 -4
View File
@@ -1,5 +1,5 @@
import type { CSSProperties, ReactNode } from "react";
import { Navigate, Route, Routes } from "react-router-dom";
import { Navigate, Route, Routes, useLocation } from "react-router-dom";
import { getStoredAuth } from "@/core/auth";
@@ -87,6 +87,20 @@ export function ChatRuntime({ children }: { children: ReactNode }) {
);
}
/**
* 让 ChatPage 在每次真正的 react-router navigation 上完整 remount。
*
* 背景:点「新对话」时即使路径不变,我们也会用 `navigate(..., { replace: true,
* state: { resetAt } })` 强制刷新 location.key —— 用它作 key 能保证 useStream、
* useThreadStream、optimistic state、refs 一次性全部丢弃,避免上一条流的
* `stream.values` 残留把欢迎页底下的旧消息拖出来(SDK 的 stream.clear() 需要
* 多次 effect tick 才会清干净,中间过渡帧用户能看见)。
*/
function KeyedChatPage({ render }: { render: () => ReactNode }) {
const key = useLocation().key;
return <ChatRuntime key={key}>{render()}</ChatRuntime>;
}
export default function WorkspaceRoutes({
pageSidebarCollapsed = false,
pageSidebarHidden = false,
@@ -121,9 +135,7 @@ export default function WorkspaceRoutes({
path="chats/:thread_id"
element={
<WorkspaceLayout {...layoutProps}>
<ChatRuntime>
<ChatPage />
</ChatRuntime>
<KeyedChatPage render={() => <ChatPage />} />
</WorkspaceLayout>
}
/>