mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Add title and logs; fix row expansion in browser group
This commit is contained in:
@@ -5,13 +5,13 @@ import { BrowserActionResult, ClineMessage, ClineSayBrowserAction } from "../../
|
|||||||
import { vscode } from "../../utils/vscode"
|
import { vscode } from "../../utils/vscode"
|
||||||
import CodeAccordian from "../common/CodeAccordian"
|
import CodeAccordian from "../common/CodeAccordian"
|
||||||
import CodeBlock, { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock"
|
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"
|
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
|
||||||
|
|
||||||
interface BrowserSessionRowProps {
|
interface BrowserSessionRowProps {
|
||||||
messages: ClineMessage[]
|
messages: ClineMessage[]
|
||||||
isExpanded: boolean
|
isExpanded: (messageTs: number) => boolean
|
||||||
onToggleExpand: () => void
|
onToggleExpand: (messageTs: number) => void
|
||||||
lastModifiedMessage?: ClineMessage
|
lastModifiedMessage?: ClineMessage
|
||||||
isLast: boolean
|
isLast: boolean
|
||||||
onHeightChange: (isTaller: boolean) => void
|
onHeightChange: (isTaller: boolean) => void
|
||||||
@@ -20,12 +20,20 @@ interface BrowserSessionRowProps {
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
- console logs will be aggregate up to that current page
|
- 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 BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
||||||
const { messages, isLast, onHeightChange } = props
|
const { messages, isLast, onHeightChange, lastModifiedMessage, isExpanded } = props
|
||||||
const prevHeightRef = useRef(0)
|
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
|
// Organize messages into pages with current state and next action
|
||||||
const pages = useMemo(() => {
|
const pages = useMemo(() => {
|
||||||
@@ -33,6 +41,8 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
|||||||
currentState: {
|
currentState: {
|
||||||
url?: string
|
url?: string
|
||||||
screenshot?: string
|
screenshot?: string
|
||||||
|
mousePosition?: string
|
||||||
|
consoleLogs?: string
|
||||||
messages: ClineMessage[] // messages up to and including the result
|
messages: ClineMessage[] // messages up to and including the result
|
||||||
}
|
}
|
||||||
nextAction?: {
|
nextAction?: {
|
||||||
@@ -57,6 +67,8 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
|||||||
currentState: {
|
currentState: {
|
||||||
url: resultData.currentUrl,
|
url: resultData.currentUrl,
|
||||||
screenshot: resultData.screenshot,
|
screenshot: resultData.screenshot,
|
||||||
|
mousePosition: resultData.currentMousePosition,
|
||||||
|
consoleLogs: resultData.logs,
|
||||||
messages: [...currentStateMessages],
|
messages: [...currentStateMessages],
|
||||||
},
|
},
|
||||||
nextAction:
|
nextAction:
|
||||||
@@ -120,11 +132,13 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
|||||||
if (page.currentState.url || page.currentState.screenshot) {
|
if (page.currentState.url || page.currentState.screenshot) {
|
||||||
return {
|
return {
|
||||||
url: page.currentState.url,
|
url: page.currentState.url,
|
||||||
|
mousePosition: page.currentState.mousePosition,
|
||||||
|
consoleLogs: page.currentState.consoleLogs,
|
||||||
screenshot: page.currentState.screenshot,
|
screenshot: page.currentState.screenshot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { url: undefined, screenshot: undefined }
|
return { url: undefined, mousePosition: undefined, consoleLogs: undefined, screenshot: undefined }
|
||||||
}, [pages])
|
}, [pages])
|
||||||
|
|
||||||
const currentPage = pages[currentPageIndex]
|
const currentPage = pages[currentPageIndex]
|
||||||
@@ -134,17 +148,26 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
|||||||
const displayState = isLastPage
|
const displayState = isLastPage
|
||||||
? {
|
? {
|
||||||
url: currentPage?.currentState.url || latestState.url || initialUrl,
|
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,
|
screenshot: currentPage?.currentState.screenshot || latestState.screenshot,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
url: currentPage?.currentState.url || initialUrl,
|
url: currentPage?.currentState.url || initialUrl,
|
||||||
|
mousePosition: currentPage?.currentState.mousePosition || "400,300",
|
||||||
|
consoleLogs: currentPage?.currentState.consoleLogs,
|
||||||
screenshot: currentPage?.currentState.screenshot,
|
screenshot: currentPage?.currentState.screenshot,
|
||||||
}
|
}
|
||||||
|
|
||||||
const [actionContent, { height: actionHeight }] = useSize(
|
const [actionContent, { height: actionHeight }] = useSize(
|
||||||
<div>
|
<div>
|
||||||
{currentPage?.nextAction?.messages.map((message) => (
|
{currentPage?.nextAction?.messages.map((message) => (
|
||||||
<BrowserSessionRowContent key={message.ts} {...props} message={message} />
|
<BrowserSessionRowContent
|
||||||
|
key={message.ts}
|
||||||
|
{...props}
|
||||||
|
message={message}
|
||||||
|
setMaxActionHeight={setMaxActionHeight}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -153,13 +176,31 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
|||||||
if (actionHeight === 0 || actionHeight === Infinity) {
|
if (actionHeight === 0 || actionHeight === Infinity) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (actionHeight > maxActionHeightRef.current) {
|
if (actionHeight > maxActionHeight) {
|
||||||
maxActionHeightRef.current = actionHeight
|
setMaxActionHeight(actionHeight)
|
||||||
}
|
}
|
||||||
}, [actionHeight])
|
}, [actionHeight, maxActionHeight])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!displayState.consoleLogs || displayState.consoleLogs.trim() === "") {
|
||||||
|
setConsoleLogsExpanded(false)
|
||||||
|
}
|
||||||
|
}, [displayState.consoleLogs])
|
||||||
|
|
||||||
const [browserSessionRow, { height }] = useSize(
|
const [browserSessionRow, { height }] = useSize(
|
||||||
<div style={{ padding: "10px 6px 10px 15px" }}>
|
<div style={{ padding: "10px 6px 10px 15px" }}>
|
||||||
|
<div style={{ display: "flex", alignItems: "center", gap: "10px", marginBottom: "10px" }}>
|
||||||
|
{isBrowsing ? (
|
||||||
|
<ProgressIndicator />
|
||||||
|
) : (
|
||||||
|
<span
|
||||||
|
className={`codicon codicon-inspect`}
|
||||||
|
style={{ color: "var(--vscode-foreground)", marginBottom: "-1.5px" }}></span>
|
||||||
|
)}
|
||||||
|
<span style={{ fontWeight: "bold" }}>
|
||||||
|
<>Cline wants to use the browser:</>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
@@ -172,6 +213,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
|||||||
style={{
|
style={{
|
||||||
margin: "5px auto",
|
margin: "5px auto",
|
||||||
width: "calc(100% - 10px)",
|
width: "calc(100% - 10px)",
|
||||||
|
boxSizing: "border-box", // includes padding in width calculation
|
||||||
backgroundColor: "var(--vscode-input-background)",
|
backgroundColor: "var(--vscode-input-background)",
|
||||||
border: "1px solid var(--vscode-input-border)",
|
border: "1px solid var(--vscode-input-border)",
|
||||||
borderRadius: "4px",
|
borderRadius: "4px",
|
||||||
@@ -228,11 +270,42 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{displayState.mousePosition && (
|
||||||
|
<BrowserCursor
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: `${(parseInt(displayState.mousePosition.split(",")[1]) / 600) * 100}%`,
|
||||||
|
left: `${(parseInt(displayState.mousePosition.split(",")[0]) / 800) * 100}%`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
setConsoleLogsExpanded(!consoleLogsExpanded)
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "4px",
|
||||||
|
width: "100%",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
cursor: "pointer",
|
||||||
|
padding: `9px 8px ${consoleLogsExpanded ? 0 : 8}px 8px`,
|
||||||
|
}}>
|
||||||
|
<span className={`codicon codicon-chevron-${consoleLogsExpanded ? "down" : "right"}`}></span>
|
||||||
|
<span style={{ fontSize: "0.8em" }}>Console Logs</span>
|
||||||
|
</div>
|
||||||
|
{consoleLogsExpanded && (
|
||||||
|
<CodeBlock source={`${"```"}shell\n${displayState.consoleLogs || "(No new logs)"}\n${"```"}`} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Action content with min height */}
|
{/* Action content with min height */}
|
||||||
<div style={{ minHeight: maxActionHeightRef.current }}>{actionContent}</div>
|
<div style={{ minHeight: maxActionHeight }}>{actionContent}</div>
|
||||||
|
|
||||||
{/* Pagination moved to bottom */}
|
{/* Pagination moved to bottom */}
|
||||||
{pages.length > 1 && (
|
{pages.length > 1 && (
|
||||||
@@ -250,12 +323,12 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
|||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", gap: "4px" }}>
|
<div style={{ display: "flex", gap: "4px" }}>
|
||||||
<VSCodeButton
|
<VSCodeButton
|
||||||
disabled={currentPageIndex === 0}
|
disabled={currentPageIndex === 0 || isBrowsing}
|
||||||
onClick={() => setCurrentPageIndex((i) => i - 1)}>
|
onClick={() => setCurrentPageIndex((i) => i - 1)}>
|
||||||
Previous
|
Previous
|
||||||
</VSCodeButton>
|
</VSCodeButton>
|
||||||
<VSCodeButton
|
<VSCodeButton
|
||||||
disabled={currentPageIndex === pages.length - 1}
|
disabled={currentPageIndex === pages.length - 1 || isBrowsing}
|
||||||
onClick={() => setCurrentPageIndex((i) => i + 1)}>
|
onClick={() => setCurrentPageIndex((i) => i + 1)}>
|
||||||
Next
|
Next
|
||||||
</VSCodeButton>
|
</VSCodeButton>
|
||||||
@@ -281,6 +354,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
|
|||||||
|
|
||||||
interface BrowserSessionRowContentProps extends Omit<BrowserSessionRowProps, "messages"> {
|
interface BrowserSessionRowContentProps extends Omit<BrowserSessionRowProps, "messages"> {
|
||||||
message: ClineMessage
|
message: ClineMessage
|
||||||
|
setMaxActionHeight: (height: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const BrowserSessionRowContent = ({
|
const BrowserSessionRowContent = ({
|
||||||
@@ -289,6 +363,7 @@ const BrowserSessionRowContent = ({
|
|||||||
onToggleExpand,
|
onToggleExpand,
|
||||||
lastModifiedMessage,
|
lastModifiedMessage,
|
||||||
isLast,
|
isLast,
|
||||||
|
setMaxActionHeight,
|
||||||
}: BrowserSessionRowContentProps) => {
|
}: BrowserSessionRowContentProps) => {
|
||||||
const headerStyle: React.CSSProperties = {
|
const headerStyle: React.CSSProperties = {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -307,13 +382,20 @@ const BrowserSessionRowContent = ({
|
|||||||
case "api_req_started":
|
case "api_req_started":
|
||||||
case "text":
|
case "text":
|
||||||
return (
|
return (
|
||||||
<ChatRowContent
|
<div style={{ padding: "15px 0 5px 0" }}>
|
||||||
message={message}
|
<ChatRowContent
|
||||||
isExpanded={isExpanded}
|
message={message}
|
||||||
onToggleExpand={onToggleExpand}
|
isExpanded={isExpanded(message.ts)}
|
||||||
lastModifiedMessage={lastModifiedMessage}
|
onToggleExpand={() => {
|
||||||
isLast={isLast}
|
if (message.say === "api_req_started") {
|
||||||
/>
|
setMaxActionHeight(0)
|
||||||
|
}
|
||||||
|
onToggleExpand(message.ts)
|
||||||
|
}}
|
||||||
|
lastModifiedMessage={lastModifiedMessage}
|
||||||
|
isLast={isLast}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
case "browser_action":
|
case "browser_action":
|
||||||
@@ -355,8 +437,8 @@ const BrowserSessionRowContent = ({
|
|||||||
code={logs}
|
code={logs}
|
||||||
language="shell"
|
language="shell"
|
||||||
isConsoleLogs={true}
|
isConsoleLogs={true}
|
||||||
isExpanded={isExpanded}
|
isExpanded={isExpanded(message.ts)}
|
||||||
onToggleExpand={onToggleExpand}
|
onToggleExpand={() => onToggleExpand(message.ts)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -754,7 +754,7 @@ export const ChatRowContent = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgressIndicator = () => (
|
export const ProgressIndicator = () => (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
width: "16px",
|
width: "16px",
|
||||||
|
|||||||
@@ -627,16 +627,20 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
|
|||||||
(index: number, messageOrGroup: ClineMessage | ClineMessage[]) => {
|
(index: number, messageOrGroup: ClineMessage | ClineMessage[]) => {
|
||||||
// browser session group
|
// browser session group
|
||||||
if (Array.isArray(messageOrGroup)) {
|
if (Array.isArray(messageOrGroup)) {
|
||||||
const firstMessage = messageOrGroup[0]
|
|
||||||
return (
|
return (
|
||||||
<BrowserSessionRow
|
<BrowserSessionRow
|
||||||
key={firstMessage.ts}
|
|
||||||
messages={messageOrGroup}
|
messages={messageOrGroup}
|
||||||
isExpanded={expandedRows[firstMessage.ts] || false}
|
|
||||||
onToggleExpand={() => toggleRowExpansion(firstMessage.ts)}
|
|
||||||
lastModifiedMessage={modifiedMessages.at(-1)}
|
|
||||||
isLast={index === groupedMessages.length - 1}
|
isLast={index === groupedMessages.length - 1}
|
||||||
|
lastModifiedMessage={modifiedMessages.at(-1)}
|
||||||
onHeightChange={handleRowHeightChange}
|
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],
|
||||||
|
}))
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user