import { useRouter, useSearchParams } from "next/navigation"; import { useState, useEffect, useCallback, useRef } from "react"; import { POST_MESSAGE_TYPES, RECEIVE_MESSAGE_TYPES, isSelectedSkillMessage, type SelectedSkillPayloadItem, sendToParent, } from "@/core/iframe-messages"; // Skill 数据类型 interface SkillData { skill_id: string; title: string; } // Hook 返回类型 interface UseIframeSkillReturn { selectedSkill: SkillData | null; sendSelectSkill: (selectedSkills: SelectedSkillPayloadItem[]) => void; openSkillDialog: () => void; clearSkill: () => void; } export function useIframeSkill(): UseIframeSkillReturn { const router = useRouter(); const searchParams = useSearchParams(); const threadIdFromQuery = searchParams.get("thread_id"); const isChattingFromQuery = searchParams.get("is_chatting"); const lastThreadIdRef = useRef(null); const [selectedSkill, setSelectedSkill] = useState(null); // 1. 监听 query 参数变化(临时禁用) // TODO: 当前 skill 仅通过 iframe postMessage 传递,暂不从 URL 读取 skill_id/title。 // useEffect(() => { // const skillIdFromQuery = searchParams.get("skill_id"); // const titleFromQuery = searchParams.get("title"); // if (skillIdFromQuery && titleFromQuery) { // setSelectedSkill({ skill_id: skillIdFromQuery, title: titleFromQuery }); // } // }, [searchParams]); // 0. 监听 query 中 is_chatting=true 且带 thread_id 时跳转到 thread 页面 useEffect(() => { if (!threadIdFromQuery) return; if (isChattingFromQuery !== "true") return; if (lastThreadIdRef.current === threadIdFromQuery) return; lastThreadIdRef.current = threadIdFromQuery; router.replace(`/workspace/chats/${threadIdFromQuery}`); }, [isChattingFromQuery, router, threadIdFromQuery]); // 2. 监听宿主页 postMessage useEffect(() => { const handleMessage = (event: MessageEvent) => { if (event.data?.type !== RECEIVE_MESSAGE_TYPES.SELECTED_SKILL) { return; } if (!isSelectedSkillMessage(event.data)) { console.warn("[useIframeSkill] 忽略非法 selectedSkill 消息", event.data); return; } const { id, title } = event.data; setSelectedSkill({ skill_id: String(id), title }); }; window.addEventListener("message", handleMessage); return () => window.removeEventListener("message", handleMessage); }, []); // 发送选择预定义 skill const sendSelectSkill = useCallback((selectedSkills: SelectedSkillPayloadItem[]) => { const message = { type: POST_MESSAGE_TYPES.SELECT_SKILLS, selectedSkills }; console.log("[useIframeSkill] sendSelectSkill:", message); sendToParent(message); }, []); // 打开 skill 选择对话框 const openSkillDialog = useCallback(() => { const message = { type: POST_MESSAGE_TYPES.OPEN_SKILL_DIALOG, openSkillDialog: true, } as const; console.log("[useIframeSkill] openSkillDialog:", message); sendToParent(message); }, []); // 清除选中并发送空 selectedSkills 数组给主页 const clearSkill = useCallback(() => { setSelectedSkill(null); // 发送空数组给主页,通知取消选择 const message = { type: POST_MESSAGE_TYPES.SELECT_SKILLS, selectedSkills: [] }; console.log("[useIframeSkill] clearSkill, sending selectedSkills=[]:", message); sendToParent(message); }, []); return { selectedSkill, sendSelectSkill, openSkillDialog, clearSkill }; }