Skip to content

Commit 6f20321

Browse files
authored
refactor & perf: declare constant object for inline style of file BrowserSessionRow (RooCodeInc#2645)
1 parent adf4c92 commit 6f20321

File tree

2 files changed

+116
-109
lines changed

2 files changed

+116
-109
lines changed

.changeset/calm-cheetahs-clean.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": patch
3+
---
4+
5+
declare constant object for inline style of file `BrowserSessionRow`

webview-ui/src/components/chat/BrowserSessionRow.tsx

Lines changed: 111 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
22
import deepEqual from "fast-deep-equal"
3-
import React, { memo, useEffect, useMemo, useRef, useState } from "react"
3+
import React, { CSSProperties, memo, useEffect, useMemo, useRef, useState } from "react"
44
import { useSize } from "react-use"
55
import styled from "styled-components"
66
import { BROWSER_VIEWPORT_PRESETS } from "../../../../src/shared/BrowserSettings"
@@ -21,6 +21,93 @@ interface BrowserSessionRowProps {
2121
onHeightChange: (isTaller: boolean) => void
2222
}
2323

24+
const browserSessionRowContainerInnerStyle: CSSProperties = {
25+
display: "flex",
26+
alignItems: "center",
27+
gap: "10px",
28+
marginBottom: "10px",
29+
}
30+
const browserIconStyle: CSSProperties = {
31+
color: "var(--vscode-foreground)",
32+
marginBottom: "-1.5px",
33+
}
34+
const approveTextStyle: CSSProperties = { fontWeight: "bold" }
35+
const urlBarContainerStyle: CSSProperties = {
36+
margin: "5px auto",
37+
width: "calc(100% - 10px)",
38+
display: "flex",
39+
alignItems: "center",
40+
gap: "4px",
41+
}
42+
const urlTextStyle: CSSProperties = {
43+
textOverflow: "ellipsis",
44+
overflow: "hidden",
45+
whiteSpace: "nowrap",
46+
width: "100%",
47+
textAlign: "center",
48+
}
49+
const imgScreenshotStyle: CSSProperties = {
50+
position: "absolute",
51+
top: 0,
52+
left: 0,
53+
width: "100%",
54+
height: "100%",
55+
objectFit: "contain",
56+
cursor: "pointer",
57+
}
58+
const noScreenshotContainerStyle: CSSProperties = {
59+
position: "absolute",
60+
top: "50%",
61+
left: "50%",
62+
transform: "translate(-50%, -50%)",
63+
}
64+
const noScreenshotIconStyle: CSSProperties = {
65+
fontSize: "80px",
66+
color: "var(--vscode-descriptionForeground)",
67+
}
68+
const consoleLogsContainerStyle: CSSProperties = { width: "100%" }
69+
const consoleLogsTextStyle: CSSProperties = { fontSize: "0.8em" }
70+
const paginationContainerStyle: CSSProperties = {
71+
display: "flex",
72+
justifyContent: "space-between",
73+
alignItems: "center",
74+
padding: "8px 0px",
75+
marginTop: "15px",
76+
borderTop: "1px solid var(--vscode-editorGroup-border)",
77+
}
78+
const paginationButtonGroupStyle: CSSProperties = { display: "flex", gap: "4px" }
79+
const browserSessionStartedTextStyle: CSSProperties = { fontWeight: "bold" }
80+
const codeBlockContainerStyle: CSSProperties = {
81+
borderRadius: 3,
82+
border: "1px solid var(--vscode-editorGroup-border)",
83+
overflow: "hidden",
84+
backgroundColor: CODE_BLOCK_BG_COLOR,
85+
}
86+
const browserActionBoxContainerStyle: CSSProperties = { padding: "10px 0 0 0" }
87+
const browserActionBoxContainerInnerStyle: CSSProperties = {
88+
borderRadius: 3,
89+
backgroundColor: CODE_BLOCK_BG_COLOR,
90+
overflow: "hidden",
91+
border: "1px solid var(--vscode-editorGroup-border)",
92+
}
93+
const browseActionRowContainerStyle: CSSProperties = {
94+
display: "flex",
95+
alignItems: "center",
96+
padding: "9px 10px",
97+
}
98+
const browseActionRowStyle: CSSProperties = {
99+
whiteSpace: "normal",
100+
wordBreak: "break-word",
101+
}
102+
const browseActionTextStyle: CSSProperties = { fontWeight: 500 }
103+
const chatRowContentContainerStyle: CSSProperties = { padding: "10px 0 10px 0" }
104+
const headerStyle: CSSProperties = {
105+
display: "flex",
106+
alignItems: "center",
107+
gap: "10px",
108+
marginBottom: "10px",
109+
}
110+
24111
const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
25112
const { messages, isLast, onHeightChange, lastModifiedMessage } = props
26113
const { browserSettings } = useExtensionState()
@@ -244,25 +331,12 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
244331
const maxWidth = browserSettings.viewport.width < BROWSER_VIEWPORT_PRESETS["Small Desktop (900x600)"].width ? 200 : undefined
245332

246333
const [browserSessionRow, { height }] = useSize(
334+
// We don't declare a constant for the inline style here because `useSize` will try to modify the style object
335+
// Which will cause `Uncaught TypeError: Cannot assign to read only property 'position' of object '#<Object>'`
247336
<BrowserSessionRowContainer style={{ marginBottom: -10 }}>
248-
<div
249-
style={{
250-
display: "flex",
251-
alignItems: "center",
252-
gap: "10px",
253-
marginBottom: "10px",
254-
}}>
255-
{isBrowsing ? (
256-
<ProgressIndicator />
257-
) : (
258-
<span
259-
className={`codicon codicon-inspect`}
260-
style={{
261-
color: "var(--vscode-foreground)",
262-
marginBottom: "-1.5px",
263-
}}></span>
264-
)}
265-
<span style={{ fontWeight: "bold" }}>
337+
<div style={browserSessionRowContainerInnerStyle}>
338+
{isBrowsing ? <ProgressIndicator /> : <span className="codicon codicon-inspect" style={browserIconStyle}></span>}
339+
<span style={approveTextStyle}>
266340
<>{isAutoApproved ? "Cline is using the browser:" : "Cline wants to use the browser:"}</>
267341
</span>
268342
</div>
@@ -277,14 +351,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
277351
margin: "0 auto 10px auto", // Center the container
278352
}}>
279353
{/* URL Bar */}
280-
<div
281-
style={{
282-
margin: "5px auto",
283-
width: "calc(100% - 10px)",
284-
display: "flex",
285-
alignItems: "center",
286-
gap: "4px",
287-
}}>
354+
<div style={urlBarContainerStyle}>
288355
<div
289356
style={{
290357
flex: 1,
@@ -296,16 +363,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
296363
color: displayState.url ? "var(--vscode-input-foreground)" : "var(--vscode-descriptionForeground)",
297364
fontSize: "12px",
298365
}}>
299-
<div
300-
style={{
301-
textOverflow: "ellipsis",
302-
overflow: "hidden",
303-
whiteSpace: "nowrap",
304-
width: "100%",
305-
textAlign: "center",
306-
}}>
307-
{displayState.url || "http"}
308-
</div>
366+
<div style={urlTextStyle}>{displayState.url || "http"}</div>
309367
</div>
310368
<BrowserSettingsMenu disabled={!shouldShowSettings} maxWidth={maxWidth} />
311369
</div>
@@ -322,15 +380,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
322380
<img
323381
src={displayState.screenshot}
324382
alt="Browser screenshot"
325-
style={{
326-
position: "absolute",
327-
top: 0,
328-
left: 0,
329-
width: "100%",
330-
height: "100%",
331-
objectFit: "contain",
332-
cursor: "pointer",
333-
}}
383+
style={imgScreenshotStyle}
334384
onClick={() =>
335385
vscode.postMessage({
336386
type: "openImage",
@@ -339,20 +389,8 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
339389
}
340390
/>
341391
) : (
342-
<div
343-
style={{
344-
position: "absolute",
345-
top: "50%",
346-
left: "50%",
347-
transform: "translate(-50%, -50%)",
348-
}}>
349-
<span
350-
className="codicon codicon-globe"
351-
style={{
352-
fontSize: "80px",
353-
color: "var(--vscode-descriptionForeground)",
354-
}}
355-
/>
392+
<div style={noScreenshotContainerStyle}>
393+
<span className="codicon codicon-globe" style={noScreenshotIconStyle} />
356394
</div>
357395
)}
358396
{displayState.mousePosition && (
@@ -367,7 +405,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
367405
)}
368406
</div>
369407

370-
<div style={{ width: "100%" }}>
408+
<div style={consoleLogsContainerStyle}>
371409
<div
372410
onClick={() => {
373411
setConsoleLogsExpanded(!consoleLogsExpanded)
@@ -382,7 +420,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
382420
padding: `9px 8px ${consoleLogsExpanded ? 0 : 8}px 8px`,
383421
}}>
384422
<span className={`codicon codicon-chevron-${consoleLogsExpanded ? "down" : "right"}`}></span>
385-
<span style={{ fontSize: "0.8em" }}>Console Logs</span>
423+
<span style={consoleLogsTextStyle}>Console Logs</span>
386424
</div>
387425
{consoleLogsExpanded && (
388426
<CodeBlock source={`${"```"}shell\n${displayState.consoleLogs || "(No new logs)"}\n${"```"}`} />
@@ -395,19 +433,11 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
395433

396434
{/* Pagination moved to bottom */}
397435
{pages.length > 1 && (
398-
<div
399-
style={{
400-
display: "flex",
401-
justifyContent: "space-between",
402-
alignItems: "center",
403-
padding: "8px 0px",
404-
marginTop: "15px",
405-
borderTop: "1px solid var(--vscode-editorGroup-border)",
406-
}}>
436+
<div style={paginationContainerStyle}>
407437
<div>
408438
Step {currentPageIndex + 1} of {pages.length}
409439
</div>
410-
<div style={{ display: "flex", gap: "4px" }}>
440+
<div style={paginationButtonGroupStyle}>
411441
<VSCodeButton
412442
disabled={currentPageIndex === 0 || isBrowsing}
413443
onClick={() => setCurrentPageIndex((i) => i - 1)}>
@@ -453,26 +483,13 @@ const BrowserSessionRowContent = ({
453483
isLast,
454484
setMaxActionHeight,
455485
}: BrowserSessionRowContentProps) => {
456-
const headerStyle: React.CSSProperties = {
457-
display: "flex",
458-
alignItems: "center",
459-
gap: "10px",
460-
marginBottom: "10px",
461-
}
462-
463486
if (message.ask === "browser_action_launch" || message.say === "browser_action_launch") {
464487
return (
465488
<>
466489
<div style={headerStyle}>
467-
<span style={{ fontWeight: "bold" }}>Browser Session Started</span>
490+
<span style={browserSessionStartedTextStyle}>Browser Session Started</span>
468491
</div>
469-
<div
470-
style={{
471-
borderRadius: 3,
472-
border: "1px solid var(--vscode-editorGroup-border)",
473-
overflow: "hidden",
474-
backgroundColor: CODE_BLOCK_BG_COLOR,
475-
}}>
492+
<div style={codeBlockContainerStyle}>
476493
<CodeBlock source={`${"```"}shell\n${message.text}\n${"```"}`} forceWrap={true} />
477494
</div>
478495
</>
@@ -485,7 +502,7 @@ const BrowserSessionRowContent = ({
485502
case "api_req_started":
486503
case "text":
487504
return (
488-
<div style={{ padding: "10px 0 10px 0" }}>
505+
<div style={chatRowContentContainerStyle}>
489506
<ChatRowContent
490507
message={message}
491508
isExpanded={isExpanded(message.ts)}
@@ -543,26 +560,11 @@ const BrowserActionBox = ({ action, coordinate, text }: { action: BrowserAction;
543560
}
544561
}
545562
return (
546-
<div style={{ padding: "10px 0 0 0" }}>
547-
<div
548-
style={{
549-
borderRadius: 3,
550-
backgroundColor: CODE_BLOCK_BG_COLOR,
551-
overflow: "hidden",
552-
border: "1px solid var(--vscode-editorGroup-border)",
553-
}}>
554-
<div
555-
style={{
556-
display: "flex",
557-
alignItems: "center",
558-
padding: "9px 10px",
559-
}}>
560-
<span
561-
style={{
562-
whiteSpace: "normal",
563-
wordBreak: "break-word",
564-
}}>
565-
<span style={{ fontWeight: 500 }}>Browse Action: </span>
563+
<div style={browserActionBoxContainerStyle}>
564+
<div style={browserActionBoxContainerInnerStyle}>
565+
<div style={browseActionRowContainerStyle}>
566+
<span style={browseActionRowStyle}>
567+
<span style={browseActionTextStyle}>Browse Action: </span>
566568
{getBrowserActionText(action, coordinate, text)}
567569
</span>
568570
</div>
@@ -571,7 +573,7 @@ const BrowserActionBox = ({ action, coordinate, text }: { action: BrowserAction;
571573
)
572574
}
573575

574-
const BrowserCursor: React.FC<{ style?: React.CSSProperties }> = ({ style }) => {
576+
const BrowserCursor: React.FC<{ style?: CSSProperties }> = ({ style }) => {
575577
// (can't use svgs in vsc extensions)
576578
const cursorBase64 =
577579
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAFaADAAQAAAABAAAAGAAAAADwi9a/AAADGElEQVQ4EZ2VbUiTURTH772be/PxZdsz3cZwC4RVaB8SAjMpxQwSWZbQG/TFkN7oW1Df+h6IRV9C+hCpKUSIZUXOfGM5tAKViijFFEyfZ7Ol29S1Pbdzl8Uw9+aBu91zzv3/nt17zt2DEZjBYOAkKrtFMXIghAWM8U2vMN/FctsxGRMpM7NbEEYNMM2CYUSInlJx3OpawO9i+XSNQYkmk2uFb9njzkcfVSr1p/GJiQKMULVaw2WuBv296UKRxWJR6wxGCmM1EAhSNppv33GBH9qI32cPTAtss9lUm6EM3N7R+RbigT+5/CeosFCZKpjEW+iorS1pb30wDUXzQfHqtD/9L3ieZ2ee1OJCmbL8QHnRs+4uj0wmW4QzrpCwvJ8zGg3JqAmhTLynuLiwv8/5KyND8Q3cEkUEDWu15oJE4KRQJt5hs1rcriGNRqP+DK4dyyWXXm/aFQ+cEpSJ8/LyDGPuEZNOmzsOroUSOqzXG/dtBU4ZysTZYKNut91sNo2Cq6cE9enz86s2g9OCMrFSqVC5hgb32u072W3jKMU90Hb1seC0oUwsB+t92bO/rKx0EFGkgFCnjjc1/gVvC8rE0L+4o63t4InjxwbAJQjTe3qD8QrLkXA4DC24fWtuajp06cLFYSBIFKGmXKPRRmAnME9sPt+yLwIWb9WN69fKoTneQz4Dh2mpPNkvfeV0jjecb9wNAkwIEVQq5VJOds4Kb+DXoAsiVquVwI1Dougpij6UyGYx+5cKroeDEFibm5lWRRMbH1+npmYrq6qhwlQHIbajZEf1fElcqGGFpGg9HMuKzpfBjhytCTMgkJ56RX09zy/ysENTBElmjIgJnmNChJqohDVQqpEfwkILE8v/o0GAnV9F1eEvofVQCbiTBEXOIPQh5PGgefDZeAcjrpGZjULBr/m3tZOnz7oEQWRAQZLjWlEU/XEJWySiILgRc5Cz1DkcAyuBFcnpfF0JiXWKpcolQXizhS5hKAqFpr0MVbgbuxJ6+5xX+P4wNpbqPPrugZfbmIbLmgQR3Aw8QSi66hUXulOFbF73GxqjE5BNXWNeAAAAAElFTkSuQmCC"

0 commit comments

Comments
 (0)