Skip to content

Commit d8a4bbd

Browse files
committed
ui(chat): move browser globe to task header; show grey when inactive and green Active when session active
1 parent cebfcd0 commit d8a4bbd

File tree

2 files changed

+71
-37
lines changed

2 files changed

+71
-37
lines changed

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

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"
22
import { useEvent } from "react-use"
33
import DynamicTextArea from "react-textarea-autosize"
4-
import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX, Globe } from "lucide-react"
4+
import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX } from "lucide-react"
55

66
import { mentionRegex, mentionRegexGlobal, commandRegexGlobal, unescapeSpaces } from "@roo/context-mentions"
77
import { WebviewMessage } from "@roo/WebviewMessage"
@@ -21,7 +21,7 @@ import {
2121
} from "@src/utils/context-mentions"
2222
import { cn } from "@src/lib/utils"
2323
import { convertToMentionPath } from "@src/utils/path-mentions"
24-
import { StandardTooltip, Button } from "@src/components/ui"
24+
import { StandardTooltip } from "@src/components/ui"
2525

2626
import Thumbnails from "../common/Thumbnails"
2727
import { ModeSelector } from "./ModeSelector"
@@ -1264,32 +1264,14 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
12641264
</button>
12651265
</StandardTooltip>
12661266
)}
1267-
{!isEditMode && showBrowserDockToggle && (
1268-
<StandardTooltip content={t("chat:browser.session")}>
1269-
<Button
1270-
variant="ghost"
1271-
size="sm"
1272-
aria-label={t("chat:browser.session")}
1273-
onClick={() => vscode.postMessage({ type: "openBrowserSessionPanel" })}
1274-
className={cn(
1275-
"relative h-5 w-5 p-0",
1276-
"text-vscode-foreground opacity-85",
1277-
"hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)]",
1278-
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
1279-
)}>
1280-
<Globe
1281-
className="w-4 h-4"
1282-
style={{
1283-
color: isBrowserSessionActive
1284-
? "#4ade80"
1285-
: "var(--vscode-descriptionForeground)",
1286-
}}
1287-
/>
1288-
</Button>
1289-
</StandardTooltip>
1290-
)}
12911267
{!isEditMode ? <IndexingStatusBadge /> : null}
12921268
{!isEditMode && cloudUserInfo && <CloudAccountSwitcher />}
1269+
{/* keep props referenced after moving browser button */}
1270+
<div
1271+
className="hidden"
1272+
data-browser-session-active={isBrowserSessionActive}
1273+
data-show-browser-dock-toggle={showBrowserDockToggle}
1274+
/>
12931275
</div>
12941276
</div>
12951277
</div>

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

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { memo, useEffect, useRef, useState } from "react"
1+
import { memo, useEffect, useRef, useState, useMemo } from "react"
22
import { useTranslation } from "react-i18next"
33
import { useCloudUpsell } from "@src/hooks/useCloudUpsell"
44
import { CloudUpsellDialog } from "@src/components/cloud/CloudUpsellDialog"
@@ -10,7 +10,8 @@ import {
1010
Coins,
1111
HardDriveDownload,
1212
HardDriveUpload,
13-
FoldVerticalIcon,
13+
FoldVertical,
14+
Globe,
1415
} from "lucide-react"
1516
import prettyBytes from "pretty-bytes"
1617

@@ -21,9 +22,10 @@ import { findLastIndex } from "@roo/array"
2122

2223
import { formatLargeNumber } from "@src/utils/format"
2324
import { cn } from "@src/lib/utils"
24-
import { StandardTooltip } from "@src/components/ui"
25+
import { StandardTooltip, Button } from "@src/components/ui"
2526
import { useExtensionState } from "@src/context/ExtensionStateContext"
2627
import { useSelectedModel } from "@/components/ui/hooks/useSelectedModel"
28+
import { vscode } from "@src/utils/vscode"
2729

2830
import Thumbnails from "../common/Thumbnails"
2931

@@ -59,7 +61,7 @@ const TaskHeader = ({
5961
todos,
6062
}: TaskHeaderProps) => {
6163
const { t } = useTranslation()
62-
const { apiConfiguration, currentTaskItem, clineMessages } = useExtensionState()
64+
const { apiConfiguration, currentTaskItem, clineMessages, isBrowserSessionActive } = useExtensionState()
6365
const { id: modelId, info: model } = useSelectedModel(apiConfiguration)
6466
const [isTaskExpanded, setIsTaskExpanded] = useState(false)
6567
const [showLongRunningTaskMessage, setShowLongRunningTaskMessage] = useState(false)
@@ -95,14 +97,29 @@ const TaskHeader = ({
9597
const textRef = useRef<HTMLDivElement>(null)
9698
const contextWindow = model?.contextWindow || 1
9799

100+
// Detect if this task had any browser session activity so we can show a grey globe when inactive
101+
const browserSessionStartIndex = useMemo(() => {
102+
const msgs = clineMessages || []
103+
for (let i = 0; i < msgs.length; i++) {
104+
const m = msgs[i] as any
105+
if (m?.ask === "browser_action_launch") return i
106+
if (m?.say === "browser_session_status" && typeof m.text === "string" && m.text.includes("opened")) {
107+
return i
108+
}
109+
}
110+
return -1
111+
}, [clineMessages])
112+
113+
const showBrowserGlobe = browserSessionStartIndex !== -1 || !!isBrowserSessionActive
114+
98115
const condenseButton = (
99-
<LucideIconButton
100-
title={t("chat:task.condenseContext")}
101-
icon={FoldVerticalIcon}
102-
disabled={buttonsDisabled}
103-
onClick={() => currentTaskItem && handleCondenseContext(currentTaskItem.id)}
104-
/>
105-
)
116+
<LucideIconButton
117+
title={t("chat:task.condenseContext")}
118+
icon={FoldVertical}
119+
disabled={buttonsDisabled}
120+
onClick={() => currentTaskItem && handleCondenseContext(currentTaskItem.id)}
121+
/>
122+
)
106123

107124
const hasTodos = todos && Array.isArray(todos) && todos.length > 0
108125

@@ -355,6 +372,41 @@ const TaskHeader = ({
355372
)}
356373
{/* Todo list - always shown at bottom when todos exist */}
357374
{hasTodos && <TodoListDisplay todos={todos ?? (task as any)?.tool?.todos ?? []} />}
375+
376+
{/* Browser session status moved from bottom bar to header (bottom-right) */}
377+
{showBrowserGlobe && (
378+
<div
379+
className="absolute bottom-2 right-3 flex items-center gap-1"
380+
onClick={(e) => e.stopPropagation()}>
381+
<StandardTooltip content={t("chat:browser.session")}>
382+
<Button
383+
variant="ghost"
384+
size="sm"
385+
aria-label={t("chat:browser.session")}
386+
onClick={() => vscode.postMessage({ type: "openBrowserSessionPanel" } as any)}
387+
className={cn(
388+
"relative h-5 w-5 p-0",
389+
"text-vscode-foreground opacity-85",
390+
"hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)]",
391+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
392+
)}>
393+
<Globe
394+
className="w-4 h-4"
395+
style={{
396+
color: isBrowserSessionActive
397+
? "#4ade80"
398+
: "var(--vscode-descriptionForeground)",
399+
}}
400+
/>
401+
</Button>
402+
</StandardTooltip>
403+
{isBrowserSessionActive && (
404+
<span className="text-sm font-medium" style={{ color: "var(--vscode-testing-iconPassed)" }}>
405+
Active
406+
</span>
407+
)}
408+
</div>
409+
)}
358410
</div>
359411
<CloudUpsellDialog open={isOpen} onOpenChange={closeUpsell} onConnect={handleConnect} />
360412
</div>

0 commit comments

Comments
 (0)