From 4e95838f1f7576a63bf2714dce72c2da2ea894ff Mon Sep 17 00:00:00 2001 From: MT-Mint <798521692@qq.com> Date: Wed, 8 Apr 2026 10:30:28 +0800 Subject: [PATCH] =?UTF-8?q?refactor(frontend):=20=E5=B0=86=E5=A4=8D?= =?UTF-8?q?=E7=94=A8=E6=AC=A2=E8=BF=8E=E6=80=81=E8=B7=AF=E7=94=B1=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=BB=9F=E4=B8=80=E4=B8=BA=20show=5Freuse=5Fwelcome?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/workspace/chats/[thread_id]/page.tsx | 6 +++--- .../workspace/chats/use-thread-chat.ts | 10 ++++++++-- .../workspace/iframe-test-panel.tsx | 20 +++++++++---------- .../src/components/workspace/input-box.tsx | 4 ++-- frontend/src/core/iframe-messages.ts | 12 +++++------ frontend/src/hooks/use-iframe-skill.ts | 9 ++++----- frontend/tests/e2e/support/chat-helpers.ts | 14 ++++++------- 7 files changed, 40 insertions(+), 35 deletions(-) diff --git a/frontend/src/app/workspace/chats/[thread_id]/page.tsx b/frontend/src/app/workspace/chats/[thread_id]/page.tsx index 2272662c..635b2166 100644 --- a/frontend/src/app/workspace/chats/[thread_id]/page.tsx +++ b/frontend/src/app/workspace/chats/[thread_id]/page.tsx @@ -63,7 +63,7 @@ export default function ChatPage() { showWelcomeStyle, } = useThreadChat(); - // 新逻辑:历史渲染和新会话仅由路由 /chats/new 控制,不再读取 isnew/xclaw_used 参数。 + // 新逻辑:历史渲染和新会话仅由路由 /chats/new 控制,不再读取 isnew/show_reuse_welcome 参数。 const shouldRenderHistory = !showWelcomeStyle; const createNewSession = useMemo(() => isNewThread, [isNewThread]); @@ -485,8 +485,8 @@ export default function ChatPage() { } setShowExitDialog(false); sendToParent({ - type: POST_MESSAGE_TYPES.XCLAW_USED, - XClawUsed: false, + type: POST_MESSAGE_TYPES.SHOW_REUSE_WELCOME, + showReuseWelcome: true, }); resetNewSessionState(); // 始终复用 query 中的 thread_id。 diff --git a/frontend/src/components/workspace/chats/use-thread-chat.ts b/frontend/src/components/workspace/chats/use-thread-chat.ts index ba201334..9f6098a2 100644 --- a/frontend/src/components/workspace/chats/use-thread-chat.ts +++ b/frontend/src/components/workspace/chats/use-thread-chat.ts @@ -9,6 +9,11 @@ export function useThreadChat() { const params = useParams<{ thread_id: string }>(); const searchParams = useSearchParams(); const threadIdFromSearchParams = searchParams.get("thread_id")?.trim(); + // showWelcomeStyle的子判断 + const showReuseWelcomeFromQuery = (() => { + const showReuseWelcome = searchParams.get("show_reuse_welcome"); + return showReuseWelcome === "true"; + })(); // 兜底:当 params 还未就绪时,从 pathname 解析 thread_id。 const threadIdFromPathname = (() => { const parts = pathname.split("?")[0]?.split("/") ?? []; @@ -72,7 +77,7 @@ export function useThreadChat() { const [isNewThread, setIsNewThread] = useState(() => isNewRoute); const [showWelcomeStyle, setShowWelcomeStyle] = useState(() => { - return isNewRoute|| searchParams.get("xclaw_used") === "true"; + return isNewRoute || showReuseWelcomeFromQuery; }); // console.log("[useThreadChat] effectiveThreadIdFromPath", effectiveThreadIdFromPath); @@ -89,12 +94,13 @@ export function useThreadChat() { setIsNewThread(isNewRoute); // Prefer path thread id, fall back to query thread_id when path is /new. setThreadId(threadIdFromPathOrParams); - setShowWelcomeStyle(isNewRoute || searchParams.get("xclaw_used") === "true"); + setShowWelcomeStyle(isNewRoute || showReuseWelcomeFromQuery); }, [ isNewRoute, normalizeThreadId, pathname, searchParams, + showReuseWelcomeFromQuery, threadId, threadIdFromPathOrParams, ]); diff --git a/frontend/src/components/workspace/iframe-test-panel.tsx b/frontend/src/components/workspace/iframe-test-panel.tsx index a89172c3..a900a5e3 100644 --- a/frontend/src/components/workspace/iframe-test-panel.tsx +++ b/frontend/src/components/workspace/iframe-test-panel.tsx @@ -76,12 +76,12 @@ export function IframeTestPanel() { addLog(`copyToClipboard → "${testText.slice(0, 30)}..."`); } - function handleSendXClawUsed(used: boolean) { + function handleSendShowReuseWelcome(showReuseWelcome: boolean) { sendToParent({ - type: POST_MESSAGE_TYPES.XCLAW_USED, - XClawUsed: used, + type: POST_MESSAGE_TYPES.SHOW_REUSE_WELCOME, + showReuseWelcome: showReuseWelcome, }); - addLog(`postMessage → XClawUsed (${used})`); + addLog(`postMessage → show_reuse_welcome (${showReuseWelcome})`); } function handlePointerDown(event: ReactPointerEvent) { @@ -327,27 +327,27 @@ export function IframeTestPanel() { - {/* 场景 5:XClaw 使用状态 */} + {/* 场景 5:show_reuse_welcome */}
- ⑤ XClaw 使用状态 + ⑤ show_reuse_welcome
diff --git a/frontend/src/components/workspace/input-box.tsx b/frontend/src/components/workspace/input-box.tsx index 3b15c515..9f74c531 100644 --- a/frontend/src/components/workspace/input-box.tsx +++ b/frontend/src/components/workspace/input-box.tsx @@ -213,8 +213,8 @@ export function InputBox({ setIsFocused(false); if (showWelcomeStyle) { sendToParent({ - type: POST_MESSAGE_TYPES.XCLAW_USED, - XClawUsed: true, + type: POST_MESSAGE_TYPES.SHOW_REUSE_WELCOME, + showReuseWelcome: false, }); } onSubmit?.(message); diff --git a/frontend/src/core/iframe-messages.ts b/frontend/src/core/iframe-messages.ts index fe238ed6..a5cd892b 100644 --- a/frontend/src/core/iframe-messages.ts +++ b/frontend/src/core/iframe-messages.ts @@ -9,8 +9,8 @@ export const POST_MESSAGE_TYPES = { // 全屏切换 FULLSCREEN: "fullscreen", - // XClaw 使用状态 - XCLAW_USED: "XClawUsed", + // 是否展示复用欢迎态 + SHOW_REUSE_WELCOME: "showReuseWelcome", // 选择预定义 skill SELECT_SKILL: "selectSkill", // 打开 skill 选择对话框 @@ -35,9 +35,9 @@ export interface FullscreenMessage { fullscreen: boolean; } -export interface XClawUsedMessage { - type: typeof POST_MESSAGE_TYPES.XCLAW_USED; - XClawUsed: boolean; +export interface ShowReuseWelcomeMessage { + type: typeof POST_MESSAGE_TYPES.SHOW_REUSE_WELCOME; + showReuseWelcome: boolean; } export interface SelectSkillMessage { @@ -79,7 +79,7 @@ export function isSelectedSkillMessage(value: unknown): value is SelectedSkillMe export function sendToParent( message: | FullscreenMessage - | XClawUsedMessage + | ShowReuseWelcomeMessage | SelectSkillMessage | OpenSkillDialogMessage, ): void { diff --git a/frontend/src/hooks/use-iframe-skill.ts b/frontend/src/hooks/use-iframe-skill.ts index e506e7fc..afb68636 100644 --- a/frontend/src/hooks/use-iframe-skill.ts +++ b/frontend/src/hooks/use-iframe-skill.ts @@ -28,7 +28,7 @@ export function useIframeSkill(): UseIframeSkillReturn { const skillIdFromQuery = searchParams.get("skill_id"); const titleFromQuery = searchParams.get("title"); const threadIdFromQuery = searchParams.get("thread_id"); - const xClawUsedFromQuery = searchParams.get("xclaw_used"); + const showReuseWelcomeFromQuery = searchParams.get("show_reuse_welcome"); const lastThreadIdRef = useRef(null); const [selectedSkill, setSelectedSkill] = useState(null); @@ -40,15 +40,14 @@ export function useIframeSkill(): UseIframeSkillReturn { } }, [skillIdFromQuery, titleFromQuery]); - // 0. 监听 query 中 XClawUsed=true 且带 thread_id 时跳转并清理 query + // 0. 监听 query 中 show_reuse_welcome=false 且带 thread_id 时跳转到 thread 页面 useEffect(() => { - if (!threadIdFromQuery) return; - if (xClawUsedFromQuery !== "true") return; + if (showReuseWelcomeFromQuery !== "false") return; if (lastThreadIdRef.current === threadIdFromQuery) return; lastThreadIdRef.current = threadIdFromQuery; router.replace(`/workspace/chats/${threadIdFromQuery}`); - }, [router, threadIdFromQuery, xClawUsedFromQuery]); + }, [router, showReuseWelcomeFromQuery, threadIdFromQuery]); // 2. 监听宿主页 postMessage useEffect(() => { diff --git a/frontend/tests/e2e/support/chat-helpers.ts b/frontend/tests/e2e/support/chat-helpers.ts index a3b3501a..446c8e22 100644 --- a/frontend/tests/e2e/support/chat-helpers.ts +++ b/frontend/tests/e2e/support/chat-helpers.ts @@ -29,11 +29,11 @@ export function skipIfMissingThread( export function buildChatUrl({ pathThreadId, - xclawUsed, + showReuseWelcome, threadId, }: { pathThreadId?: string; - xclawUsed: boolean; + showReuseWelcome: boolean; threadId: string; }) { const resolvedThreadId = threadId ?? pathThreadId; @@ -42,7 +42,7 @@ export function buildChatUrl({ } const query = new URLSearchParams(); - query.set("xclaw_used", String(xclawUsed)); + query.set("show_reuse_welcome", String(showReuseWelcome)); if (resolvedThreadId) { query.set("thread_id", resolvedThreadId); } @@ -55,20 +55,20 @@ export function buildChatUrl({ export function invalidNewChatUrl() { const query = new URLSearchParams(); - query.set("xclaw_used", "false"); + query.set("show_reuse_welcome", "true"); return `/workspace/chats/new?${query.toString()}`; } export function newChatEntry(threadId: string) { return buildChatUrl({ - xclawUsed: false, + showReuseWelcome: true, threadId, }); } export function reuseThreadWelcomeEntry(threadId: string) { return buildChatUrl({ - xclawUsed: false, + showReuseWelcome: true, threadId, }); } @@ -76,7 +76,7 @@ export function reuseThreadWelcomeEntry(threadId: string) { export function reuseThreadChatEntry(threadId: string) { return buildChatUrl({ pathThreadId: threadId, - xclawUsed: true, + showReuseWelcome: false, threadId, }); }