From 3ba1eaf90851160d2d4867ecc3f0cfe551274e95 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 27 Oct 2024 14:17:50 -0400 Subject: [PATCH] Add title and logs; fix row expansion in browser group --- .../src/components/chat/BrowserSessionRow.tsx | 126 +++++++++++++++--- webview-ui/src/components/chat/ChatRow.tsx | 2 +- webview-ui/src/components/chat/ChatView.tsx | 14 +- 3 files changed, 114 insertions(+), 28 deletions(-) diff --git a/webview-ui/src/components/chat/BrowserSessionRow.tsx b/webview-ui/src/components/chat/BrowserSessionRow.tsx index 46e715c..44f655d 100644 --- a/webview-ui/src/components/chat/BrowserSessionRow.tsx +++ b/webview-ui/src/components/chat/BrowserSessionRow.tsx @@ -5,13 +5,13 @@ import { BrowserActionResult, ClineMessage, ClineSayBrowserAction } from "../../ import { vscode } from "../../utils/vscode" import CodeAccordian from "../common/CodeAccordian" import CodeBlock, { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" -import { ChatRowContent } from "./ChatRow" +import { ChatRowContent, ProgressIndicator } from "./ChatRow" import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" interface BrowserSessionRowProps { messages: ClineMessage[] - isExpanded: boolean - onToggleExpand: () => void + isExpanded: (messageTs: number) => boolean + onToggleExpand: (messageTs: number) => void lastModifiedMessage?: ClineMessage isLast: boolean onHeightChange: (isTaller: boolean) => void @@ -20,12 +20,20 @@ interface BrowserSessionRowProps { /* - console logs will be aggregate up to that current page +- while isbrowsing, disable next prev buttons and latest action if click use that as position instead of display state */ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { - const { messages, isLast, onHeightChange } = props + const { messages, isLast, onHeightChange, lastModifiedMessage, isExpanded } = props const prevHeightRef = useRef(0) - const maxActionHeightRef = useRef(0) // Track max height of action section + const [maxActionHeight, setMaxActionHeight] = useState(0) + const [consoleLogsExpanded, setConsoleLogsExpanded] = useState(false) + + const isBrowsing = useMemo(() => { + return ( + isLast && lastModifiedMessage?.ask !== "resume_task" && lastModifiedMessage?.ask !== "resume_completed_task" + ) + }, [isLast, lastModifiedMessage]) // Organize messages into pages with current state and next action const pages = useMemo(() => { @@ -33,6 +41,8 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { currentState: { url?: string screenshot?: string + mousePosition?: string + consoleLogs?: string messages: ClineMessage[] // messages up to and including the result } nextAction?: { @@ -57,6 +67,8 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { currentState: { url: resultData.currentUrl, screenshot: resultData.screenshot, + mousePosition: resultData.currentMousePosition, + consoleLogs: resultData.logs, messages: [...currentStateMessages], }, nextAction: @@ -120,11 +132,13 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { if (page.currentState.url || page.currentState.screenshot) { return { url: page.currentState.url, + mousePosition: page.currentState.mousePosition, + consoleLogs: page.currentState.consoleLogs, screenshot: page.currentState.screenshot, } } } - return { url: undefined, screenshot: undefined } + return { url: undefined, mousePosition: undefined, consoleLogs: undefined, screenshot: undefined } }, [pages]) const currentPage = pages[currentPageIndex] @@ -134,17 +148,26 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { const displayState = isLastPage ? { url: currentPage?.currentState.url || latestState.url || initialUrl, + mousePosition: currentPage?.currentState.mousePosition || latestState.mousePosition || "400,300", + consoleLogs: currentPage?.currentState.consoleLogs, screenshot: currentPage?.currentState.screenshot || latestState.screenshot, } : { url: currentPage?.currentState.url || initialUrl, + mousePosition: currentPage?.currentState.mousePosition || "400,300", + consoleLogs: currentPage?.currentState.consoleLogs, screenshot: currentPage?.currentState.screenshot, } const [actionContent, { height: actionHeight }] = useSize(
{currentPage?.nextAction?.messages.map((message) => ( - + ))}
) @@ -153,13 +176,31 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { if (actionHeight === 0 || actionHeight === Infinity) { return } - if (actionHeight > maxActionHeightRef.current) { - maxActionHeightRef.current = actionHeight + if (actionHeight > maxActionHeight) { + setMaxActionHeight(actionHeight) } - }, [actionHeight]) + }, [actionHeight, maxActionHeight]) + + useEffect(() => { + if (!displayState.consoleLogs || displayState.consoleLogs.trim() === "") { + setConsoleLogsExpanded(false) + } + }, [displayState.consoleLogs]) const [browserSessionRow, { height }] = useSize(
+
+ {isBrowsing ? ( + + ) : ( + + )} + + <>Cline wants to use the browser: + +
{ style={{ margin: "5px auto", width: "calc(100% - 10px)", + boxSizing: "border-box", // includes padding in width calculation backgroundColor: "var(--vscode-input-background)", border: "1px solid var(--vscode-input-border)", borderRadius: "4px", @@ -228,11 +270,42 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { />
)} + {displayState.mousePosition && ( + + )} +
+ +
+
{ + setConsoleLogsExpanded(!consoleLogsExpanded) + }} + style={{ + display: "flex", + alignItems: "center", + gap: "4px", + width: "100%", + justifyContent: "flex-start", + cursor: "pointer", + padding: `9px 8px ${consoleLogsExpanded ? 0 : 8}px 8px`, + }}> + + Console Logs +
+ {consoleLogsExpanded && ( + + )}
{/* Action content with min height */} -
{actionContent}
+
{actionContent}
{/* Pagination moved to bottom */} {pages.length > 1 && ( @@ -250,12 +323,12 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
setCurrentPageIndex((i) => i - 1)}> Previous setCurrentPageIndex((i) => i + 1)}> Next @@ -281,6 +354,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { interface BrowserSessionRowContentProps extends Omit { message: ClineMessage + setMaxActionHeight: (height: number) => void } const BrowserSessionRowContent = ({ @@ -289,6 +363,7 @@ const BrowserSessionRowContent = ({ onToggleExpand, lastModifiedMessage, isLast, + setMaxActionHeight, }: BrowserSessionRowContentProps) => { const headerStyle: React.CSSProperties = { display: "flex", @@ -307,13 +382,20 @@ const BrowserSessionRowContent = ({ case "api_req_started": case "text": return ( - +
+ { + if (message.say === "api_req_started") { + setMaxActionHeight(0) + } + onToggleExpand(message.ts) + }} + lastModifiedMessage={lastModifiedMessage} + isLast={isLast} + /> +
) case "browser_action": @@ -355,8 +437,8 @@ const BrowserSessionRowContent = ({ code={logs} language="shell" isConsoleLogs={true} - isExpanded={isExpanded} - onToggleExpand={onToggleExpand} + isExpanded={isExpanded(message.ts)} + onToggleExpand={() => onToggleExpand(message.ts)} /> )}
diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 8c2457c..12d3ade 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -754,7 +754,7 @@ export const ChatRowContent = ({ } } -const ProgressIndicator = () => ( +export const ProgressIndicator = () => (
{ // browser session group if (Array.isArray(messageOrGroup)) { - const firstMessage = messageOrGroup[0] return ( toggleRowExpansion(firstMessage.ts)} - lastModifiedMessage={modifiedMessages.at(-1)} isLast={index === groupedMessages.length - 1} + lastModifiedMessage={modifiedMessages.at(-1)} onHeightChange={handleRowHeightChange} + // Pass handlers for each message in the group + isExpanded={(messageTs: number) => expandedRows[messageTs] ?? false} + onToggleExpand={(messageTs: number) => { + setExpandedRows((prev) => ({ + ...prev, + [messageTs]: !prev[messageTs], + })) + }} /> ) }