Skip to content

Commit 652c5d7

Browse files
authored
feat(chat): add mode toggle with vibe/strict options in ModeSelector (#564)
1 parent 15bbf3a commit 652c5d7

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

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

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import React from "react"
1+
import React, { useCallback } from "react"
22
import { Fzf } from "fzf"
33
import { Check, X } from "lucide-react"
44

55
import { type ModeConfig, type CustomModePrompts, TelemetryEventName } from "@roo-code/types"
66

7-
import { type Mode, filterModesByZgsmCodeMode, getAllModes } from "@roo/modes"
7+
import { type Mode, ZgsmCodeMode, filterModesByZgsmCodeMode, getAllModes } from "@roo/modes"
88

99
import { vscode } from "@/utils/vscode"
1010
import { telemetryClient } from "@/utils/TelemetryClient"
1111
import { cn } from "@/lib/utils"
1212
import { useExtensionState } from "@/context/ExtensionStateContext"
1313
import { useAppTranslation } from "@/i18n/TranslationContext"
1414
import { useRooPortal } from "@/components/ui/hooks/useRooPortal"
15-
import { Popover, PopoverContent, PopoverTrigger, StandardTooltip } from "@/components/ui"
15+
import { Popover, PopoverContent, PopoverTrigger, StandardTooltip, ToggleSwitch } from "@/components/ui"
1616

1717
import { IconButton } from "./IconButton"
1818

@@ -47,9 +47,25 @@ export const ModeSelector = ({
4747
const selectedItemRef = React.useRef<HTMLDivElement>(null)
4848
const scrollContainerRef = React.useRef<HTMLDivElement>(null)
4949
const portalContainer = useRooPortal("roo-portal")
50-
const { hasOpenedModeSelector, setHasOpenedModeSelector, zgsmCodeMode } = useExtensionState()
50+
const { hasOpenedModeSelector, setHasOpenedModeSelector, zgsmCodeMode, setZgsmCodeMode } = useExtensionState()
5151
const { t } = useAppTranslation()
52-
52+
const switchMode = useCallback(
53+
(slug: ZgsmCodeMode) => {
54+
setZgsmCodeMode(slug)
55+
vscode.postMessage({
56+
type: "zgsmCodeMode",
57+
text: slug,
58+
})
59+
vscode.postMessage({
60+
type: "mode",
61+
text: slug === "vibe" ? "code" : "strict",
62+
})
63+
},
64+
[setZgsmCodeMode],
65+
)
66+
const handleCodeModeToggle = React.useCallback(() => {
67+
switchMode(zgsmCodeMode === "vibe" ? "strict" : "vibe")
68+
}, [switchMode, zgsmCodeMode])
5369
const trackModeSelectorOpened = React.useCallback(() => {
5470
// Track telemetry every time the mode selector is opened.
5571
telemetryClient.capture(TelemetryEventName.MODE_SELECTOR_OPENED)
@@ -311,6 +327,35 @@ export const ModeSelector = ({
311327
setOpen(false)
312328
}}
313329
/>
330+
<label
331+
className="flex items-center gap-2 cursor-pointer"
332+
onClick={() => {
333+
handleCodeModeToggle()
334+
}}>
335+
<span
336+
className={cn(
337+
"text-sm font-bold select-none",
338+
zgsmCodeMode === "vibe"
339+
? "text-vscode-foreground"
340+
: "text-vscode-descriptionForeground opacity-50",
341+
)}>
342+
Vibe
343+
</span>
344+
<ToggleSwitch
345+
checked={zgsmCodeMode === "strict"}
346+
aria-label="Toggle auto-approval"
347+
onChange={() => {}}
348+
/>
349+
<span
350+
className={cn(
351+
"text-sm font-bold select-none",
352+
zgsmCodeMode === "strict"
353+
? "text-vscode-foreground"
354+
: "text-vscode-descriptionForeground opacity-50",
355+
)}>
356+
Strict
357+
</span>
358+
</label>
314359
</div>
315360

316361
{/* Info icon and title on the right - only show info icon when search bar is visible */}
@@ -320,9 +365,9 @@ export const ModeSelector = ({
320365
<span className="codicon codicon-info text-xs text-vscode-descriptionForeground opacity-70 hover:opacity-100 cursor-help" />
321366
</StandardTooltip>
322367
)}
323-
<h4 className="m-0 font-medium text-sm text-vscode-descriptionForeground">
368+
{/* <h4 className="m-0 font-medium text-sm text-vscode-descriptionForeground">
324369
{t("chat:modeSelector.title")}
325-
</h4>
370+
</h4> */}
326371
</div>
327372
</div>
328373
</div>

webview-ui/src/components/chat/__tests__/ModeSelector.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ describe("ModeSelector", () => {
100100
expect(screen.getByTestId("mode-search-input")).toBeInTheDocument()
101101

102102
// Info icon should be visible.
103-
expect(screen.getByText("chat:modeSelector.title")).toBeInTheDocument()
103+
// expect(screen.getByText("chat:modeSelector.title")).toBeInTheDocument()
104104
const infoIcon = document.querySelector(".codicon-info")
105105
expect(infoIcon).toBeInTheDocument()
106106
})

0 commit comments

Comments
 (0)