mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-06-18 21:55:59 +00:00
fix(frontend): isolate new chat thread messages (#3508)
* fix(frontend): isolate new chat thread messages * fix(frontend): keep live messages visible in new chat * fix(frontend): reset thread-local message refs
This commit is contained in:
@@ -1,29 +1,44 @@
|
||||
"use client";
|
||||
|
||||
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
|
||||
import { uuid } from "@/core/utils/uuid";
|
||||
|
||||
export function useThreadChat() {
|
||||
const { thread_id: threadIdFromPath } = useParams<{ thread_id: string }>();
|
||||
const pathname = usePathname();
|
||||
const actualPathname =
|
||||
typeof window === "undefined" ? pathname : window.location.pathname;
|
||||
const isNewPath = actualPathname.endsWith("/new");
|
||||
const newThreadIdRef = useRef<string | null>(
|
||||
threadIdFromPath === "new" ? uuid() : null,
|
||||
);
|
||||
|
||||
if (isNewPath && !newThreadIdRef.current) {
|
||||
newThreadIdRef.current = uuid();
|
||||
}
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
const [threadId, setThreadId] = useState(() => {
|
||||
return threadIdFromPath === "new" ? uuid() : threadIdFromPath;
|
||||
const [threadId, setThreadIdState] = useState(() => {
|
||||
return threadIdFromPath === "new"
|
||||
? (newThreadIdRef.current ?? uuid())
|
||||
: threadIdFromPath;
|
||||
});
|
||||
|
||||
const [isNewThread, setIsNewThread] = useState(
|
||||
const [isNewThreadState, setIsNewThreadState] = useState(
|
||||
() => threadIdFromPath === "new",
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (pathname.endsWith("/new")) {
|
||||
setIsNewThread(true);
|
||||
setThreadId(uuid());
|
||||
if (isNewPath) {
|
||||
const nextThreadId = newThreadIdRef.current ?? uuid();
|
||||
newThreadIdRef.current = nextThreadId;
|
||||
setIsNewThreadState(true);
|
||||
setThreadIdState(nextThreadId);
|
||||
return;
|
||||
}
|
||||
newThreadIdRef.current = null;
|
||||
// Guard: after history.replaceState updates the URL from /chats/new to
|
||||
// /chats/{UUID}, Next.js useParams may still return the stale "new" value
|
||||
// because replaceState does not trigger router updates. Avoid propagating
|
||||
@@ -32,9 +47,28 @@ export function useThreadChat() {
|
||||
if (threadIdFromPath === "new") {
|
||||
return;
|
||||
}
|
||||
setIsNewThread(false);
|
||||
setThreadId(threadIdFromPath);
|
||||
}, [pathname, threadIdFromPath]);
|
||||
setIsNewThreadState(false);
|
||||
setThreadIdState(threadIdFromPath);
|
||||
}, [isNewPath, threadIdFromPath]);
|
||||
|
||||
const setThreadId = useCallback((nextThreadId: string) => {
|
||||
newThreadIdRef.current = null;
|
||||
setThreadIdState(nextThreadId);
|
||||
}, []);
|
||||
|
||||
const setIsNewThread = useCallback((nextIsNewThread: boolean) => {
|
||||
if (!nextIsNewThread) {
|
||||
newThreadIdRef.current = null;
|
||||
}
|
||||
setIsNewThreadState(nextIsNewThread);
|
||||
}, []);
|
||||
|
||||
const isMock = searchParams.get("mock") === "true";
|
||||
return { threadId, setThreadId, isNewThread, setIsNewThread, isMock };
|
||||
return {
|
||||
threadId: isNewPath ? (newThreadIdRef.current ?? threadId) : threadId,
|
||||
setThreadId,
|
||||
isNewThread: isNewPath ? true : isNewThreadState,
|
||||
setIsNewThread,
|
||||
isMock,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user