diff --git a/frontend/src/app/share/[threadId]/page.tsx b/frontend/src/app/share/[threadId]/page.tsx index ec4a4089..889cbed4 100644 --- a/frontend/src/app/share/[threadId]/page.tsx +++ b/frontend/src/app/share/[threadId]/page.tsx @@ -1,11 +1,11 @@ 'use client'; -import React, { useCallback, useEffect, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState, useMemo } from 'react'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; import { Button } from '@/components/ui/button'; import { - ArrowDown, CircleDashed, Info, File, ChevronRight, Play, Pause + ArrowDown, CircleDashed, Info, File, ChevronRight, Play, Pause, MonitorPlay, ExternalLink } from 'lucide-react'; import { getMessages, getProject, getThread, Project, Message as BaseApiMessageType } from '@/lib/api'; import { toast } from 'sonner'; @@ -1090,6 +1090,7 @@ export default function ThreadPage({ params }: { params: Promise } } }, [projectName]); + // In the useEffect where streamingTextContent is handled useEffect(() => { if (streamingTextContent && streamHookStatus === 'streaming' && messages.length > 0) { // Find the last assistant message to update with streaming content @@ -1126,256 +1127,56 @@ export default function ThreadPage({ params }: { params: Promise } } }, [streamingTextContent, streamHookStatus, messages, isStreamingText, isPlaying, currentMessageIndex, streamText]); - // Create a message-to-tool-index map for faster lookups - const [messageToToolIndex, setMessageToToolIndex] = useState>({}); - - // Build the message-to-tool-index map when tool calls change + // Create a memoized VNC iframe component to prevent reconnections + const memoizedVncIframe = useMemo(() => { + if (!vncPreviewUrl) return null; + + return ( +