"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(() => { 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" ); }