deerflow2/frontend/src/components/workspace/chats/use-thread-chat.ts

91 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useParams, usePathname, useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
export function useThreadChat() {
const pathname = usePathname();
const params = useParams<{ thread_id: string }>();
const searchParams = useSearchParams();
const threadIdFromSearchParams = searchParams.get("thread_id")?.trim();
// showWelcomeStyle的子判断
const isChattingFromQuery = (() => {
const isChatting = searchParams.get("is_chatting");
return isChatting === "true";
})();
// 兜底:当 params 还未就绪时,从 pathname 解析 thread_id。
const threadIdFromPathname = (() => {
const parts = pathname.split("?")[0]?.split("/") ?? [];
const idx = parts.lastIndexOf("chats");
if (idx >= 0 && parts.length > idx + 1) {
return parts[idx + 1];
}
return undefined;
})();
const rawPathThreadId = params?.thread_id ?? threadIdFromPathname;
const isNewRoute = rawPathThreadId === "new";
const threadIdFromPathOrParams = isNewRoute
? normalizeThreadId(threadIdFromSearchParams)
: normalizeThreadId(rawPathThreadId);
// console.log("[useThreadChat] pathname", pathname);
// console.log("[useThreadChat] params.thread_id", params?.thread_id);
// console.log("[useThreadChat] threadIdFromPathname", threadIdFromPathname);
// console.log("[useThreadChat] threadIdFromPath", threadIdFromPath);
// New session is only controlled by `/workspace/chats/new`.
const [isNewThread, setIsNewThread] = useState(() => isNewRoute);
const [showWelcomeStyle, setShowWelcomeStyle] = useState(() => {
return isNewRoute || !isChattingFromQuery;
});
// console.log("[useThreadChat] effectiveThreadIdFromPath", effectiveThreadIdFromPath);
const [threadId, setThreadId] = useState<string>(() => {
return threadIdFromPathOrParams ?? "";
});
useEffect(() => {
// 记住最近一次有效的 thread_id供下次加载兜底使用。
if (threadId && threadId !== "new" && typeof window !== "undefined") {
window.sessionStorage.setItem("workspace.thread_id", threadId);
}
setIsNewThread(isNewRoute);
// Prefer path thread id, fall back to query thread_id when path is /new.
setThreadId(threadIdFromPathOrParams ?? "");
setShowWelcomeStyle(isNewRoute || !isChattingFromQuery);
}, [
isNewRoute,
pathname,
searchParams,
isChattingFromQuery,
threadId,
threadIdFromPathOrParams,
]);
const isMock = searchParams.get("mock") === "true";
return {
threadId,
isNewThread,
setIsNewThread,
isMock,
showWelcomeStyle,
};
}
function normalizeThreadId(value?: string | null): string | undefined {
if (!value) return undefined;
return isValidThreadId(value) ? value.trim() : undefined;
}
function isValidThreadId(value?: string | null): value is string {
if (!value) return false;
const normalized = value.trim().toLowerCase();
return (
normalized.length > 0 &&
normalized !== "new" &&
normalized !== "undefined" &&
normalized !== "null"
);
}