From 4afba86bcb19535f812c655034fb13c32ed99a92 Mon Sep 17 00:00:00 2001 From: MT-Fire <798521692@qq.com> Date: Sun, 29 Mar 2026 01:02:01 +0800 Subject: [PATCH] =?UTF-8?q?refactor(frontend):=20=E5=9C=A8=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E6=A1=86=E5=86=85=E5=B5=8C=20iframe=20skill=20?= =?UTF-8?q?=E9=80=9A=E4=BF=A1=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/workspace/input-box.tsx | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/workspace/input-box.tsx b/frontend/src/components/workspace/input-box.tsx index 7d9607aa..92b377be 100644 --- a/frontend/src/components/workspace/input-box.tsx +++ b/frontend/src/components/workspace/input-box.tsx @@ -59,7 +59,6 @@ import { import { useI18n } from "@/core/i18n/hooks"; import { useModels } from "@/core/models/hooks"; import type { AgentThreadContext } from "@/core/threads"; -import { useIframeSkill } from "@/hooks/use-iframe-skill"; import { cn } from "@/lib/utils"; import { @@ -82,6 +81,79 @@ import { import { ModeHoverGuide } from "./mode-hover-guide"; import { Tooltip } from "./tooltip"; +const POST_MESSAGE_TYPES = { + SELECT_SKILL: "selectSkill", + OPEN_SKILL_DIALOG: "openSkillDialog", +} as const; + +const RECEIVE_MESSAGE_TYPES = { + SELECTED_SKILL: "selectedSkill", +} as const; + +type IframeSelectedSkillMessage = { + type: typeof RECEIVE_MESSAGE_TYPES.SELECTED_SKILL; + id: string | number; + title: string; +}; + +type IframeSkillData = { + skill_id: string; + title: string; +}; + +function sendIframeMessageToParent(message: unknown): void { + if (window.parent !== window) { + window.parent.postMessage(message, "*"); + } +} + +function useEmbeddedIframeSkill() { + const searchParams = useSearchParams(); + const skillIdFromQuery = searchParams.get("skill_id"); + const titleFromQuery = searchParams.get("title"); + const [selectedSkill, setSelectedSkill] = useState( + null, + ); + + useEffect(() => { + if (skillIdFromQuery && titleFromQuery) { + setSelectedSkill({ skill_id: skillIdFromQuery, title: titleFromQuery }); + } + }, [skillIdFromQuery, titleFromQuery]); + + useEffect(() => { + const handleMessage = (event: MessageEvent) => { + if (event.data?.type === RECEIVE_MESSAGE_TYPES.SELECTED_SKILL) { + const { id, title } = event.data as IframeSelectedSkillMessage; + setSelectedSkill({ skill_id: String(id), title }); + } + }; + window.addEventListener("message", handleMessage); + return () => window.removeEventListener("message", handleMessage); + }, []); + + const sendSelectSkill = useCallback((skill_id: string) => { + sendIframeMessageToParent({ type: POST_MESSAGE_TYPES.SELECT_SKILL, skill_id }); + }, []); + + const openSkillDialog = useCallback(() => { + sendIframeMessageToParent({ + type: POST_MESSAGE_TYPES.OPEN_SKILL_DIALOG, + openSkillDialog: true, + }); + }, []); + + const clearSkill = useCallback(() => { + setSelectedSkill(null); + sendIframeMessageToParent({ + type: POST_MESSAGE_TYPES.SELECT_SKILL, + skill_id: "0", + }); + }, []); + + return { selectedSkill, sendSelectSkill, openSkillDialog, clearSkill }; +} + export function InputBox({ className, disabled, @@ -125,7 +197,7 @@ export function InputBox({ }) { const { t } = useI18n(); const searchParams = useSearchParams(); - const iframeSkill = useIframeSkill(); + const iframeSkill = useEmbeddedIframeSkill(); const params = useParams(); const threadId = threadIdProp ?? params?.thread_id;