import { useMemo, useRef, useEffect, useCallback } from 'react'; import type { InteractiveContent } from '@/lib/types/stage'; import { useWidgetIframeStore } from '@/lib/store/widget-iframe'; import { patchHtmlForIframe } from '@/lib/utils/iframe'; interface InteractiveRendererProps { readonly content: InteractiveContent; readonly sceneId: string; } export function InteractiveRenderer({ content, sceneId }: InteractiveRendererProps) { const iframeRef = useRef(null); const registerIframe = useWidgetIframeStore((state) => state.registerIframe); const setActiveScene = useWidgetIframeStore((state) => state.setActiveScene); const patchedHtml = useMemo( () => (content.html ? patchHtmlForIframe(content.html) : undefined), [content.html], ); // Create iframe messaging callback const sendMessageToIframe = useCallback((type: string, payload: Record) => { if (iframeRef.current?.contentWindow) { iframeRef.current.contentWindow.postMessage({ type, ...payload }, '*'); } }, []); // Register iframe messaging callback on mount, unregister on unmount // Key by sceneId to prevent race conditions on scene switch useEffect(() => { registerIframe(sceneId, sendMessageToIframe); setActiveScene(sceneId); return () => { registerIframe(sceneId, null); }; }, [sceneId, registerIframe, sendMessageToIframe, setActiveScene]); return (