Spaces:
Build error
Build error
| /** | |
| * @license | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| /* tslint:disable */ | |
| import React, {useEffect, useRef} from 'react'; | |
| import {InteractionData} from '../types'; | |
| interface GeneratedContentProps { | |
| htmlContent: string; | |
| onInteract: (data: InteractionData) => void; | |
| appContext: string | null; | |
| isLoading: boolean; // Added isLoading prop | |
| } | |
| export const GeneratedContent: React.FC<GeneratedContentProps> = ({ | |
| htmlContent, | |
| onInteract, | |
| appContext, | |
| isLoading, | |
| }) => { | |
| const contentRef = useRef<HTMLDivElement>(null); | |
| const processedHtmlContentRef = useRef<string | null>(null); // Ref to track processed content | |
| useEffect(() => { | |
| const container = contentRef.current; | |
| if (!container) return; | |
| const handleClick = (event: MouseEvent) => { | |
| let targetElement = event.target as HTMLElement; | |
| while ( | |
| targetElement && | |
| targetElement !== container && | |
| !targetElement.dataset.interactionId | |
| ) { | |
| targetElement = targetElement.parentElement as HTMLElement; | |
| } | |
| if (targetElement && targetElement.dataset.interactionId) { | |
| event.preventDefault(); | |
| let interactionValue: string | undefined = | |
| targetElement.dataset.interactionValue; | |
| if (targetElement.dataset.valueFrom) { | |
| const inputElement = document.getElementById( | |
| targetElement.dataset.valueFrom, | |
| ) as HTMLInputElement | HTMLTextAreaElement; | |
| if (inputElement) { | |
| interactionValue = inputElement.value; | |
| } | |
| } | |
| const interactionData: InteractionData = { | |
| id: targetElement.dataset.interactionId, | |
| type: targetElement.dataset.interactionType || 'generic_click', | |
| value: interactionValue, | |
| elementType: targetElement.tagName.toLowerCase(), | |
| elementText: ( | |
| targetElement.innerText || | |
| (targetElement as HTMLInputElement).value || | |
| '' | |
| ) | |
| .trim() | |
| .substring(0, 75), | |
| appContext: appContext, | |
| }; | |
| onInteract(interactionData); | |
| } | |
| }; | |
| container.addEventListener('click', handleClick); | |
| // Process scripts only when loading is complete and content has changed | |
| if (!isLoading) { | |
| if (htmlContent !== processedHtmlContentRef.current) { | |
| const scripts = Array.from(container.getElementsByTagName('script')); | |
| scripts.forEach((oldScript) => { | |
| try { | |
| const newScript = document.createElement('script'); | |
| Array.from(oldScript.attributes).forEach((attr) => | |
| newScript.setAttribute(attr.name, attr.value), | |
| ); | |
| newScript.text = oldScript.innerHTML; | |
| if (oldScript.parentNode) { | |
| oldScript.parentNode.replaceChild(newScript, oldScript); | |
| } else { | |
| console.warn( | |
| 'Script tag found without a parent node:', | |
| oldScript, | |
| ); | |
| } | |
| } catch (e) { | |
| console.error( | |
| 'Error processing/executing script tag. This usually indicates a syntax error in the LLM-generated script.', | |
| { | |
| scriptContent: | |
| oldScript.innerHTML.substring(0, 500) + | |
| (oldScript.innerHTML.length > 500 ? '...' : ''), | |
| error: e, | |
| }, | |
| ); | |
| } | |
| }); | |
| processedHtmlContentRef.current = htmlContent; // Mark this content as processed | |
| } | |
| } else { | |
| // If loading, reset the processed content ref. This ensures that when loading finishes, | |
| // the new content (even if identical to a previous state before loading) is processed. | |
| processedHtmlContentRef.current = null; | |
| } | |
| return () => { | |
| container.removeEventListener('click', handleClick); | |
| }; | |
| }, [htmlContent, onInteract, appContext, isLoading]); | |
| return ( | |
| <div | |
| ref={contentRef} | |
| className="w-full h-full overflow-y-auto" | |
| dangerouslySetInnerHTML={{__html: htmlContent}} | |
| /> | |
| ); | |
| }; | |