Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/types/src/global-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,17 @@ export const globalSettingsSchema = z.object({
hasOpenedModeSelector: z.boolean().optional(),
lastModeExportPath: z.string().optional(),
lastModeImportPath: z.string().optional(),

// UI Settings
showEnhancePromptButton: z.boolean().optional(),
showCodebaseIndexingButton: z.boolean().optional(),
showAddImagesToMessageButton: z.boolean().optional(),
showManageSlashCommandsButton: z.boolean().optional(),
showHintText: z.boolean().optional(),
showSendButton: z.boolean().optional(),
showApiConfigurationButton: z.boolean().optional(),
showAutoApproveTab: z.boolean().optional(),
showContextPercentageBar: z.boolean().optional(),
})

export type GlobalSettings = z.infer<typeof globalSettingsSchema>
Expand Down
37 changes: 37 additions & 0 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2618,5 +2618,42 @@ export const webviewMessageHandler = async (
}
break
}
// UI Settings handlers
case "showEnhancePromptButton":
await updateGlobalState("showEnhancePromptButton", message.bool ?? true)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each UI toggle triggers a separate postStateToWebview() call, which could impact performance when users change multiple settings quickly. Consider batching these updates or debouncing the state synchronization to reduce the number of messages sent to the webview.

For example, you could collect all changes and send them in a single update after a short delay.

await provider.postStateToWebview()
break
case "showCodebaseIndexingButton":
await updateGlobalState("showCodebaseIndexingButton", message.bool ?? true)
await provider.postStateToWebview()
break
case "showAddImagesToMessageButton":
await updateGlobalState("showAddImagesToMessageButton", message.bool ?? true)
await provider.postStateToWebview()
break
case "showManageSlashCommandsButton":
await updateGlobalState("showManageSlashCommandsButton", message.bool ?? true)
await provider.postStateToWebview()
break
case "showHintText":
await updateGlobalState("showHintText", message.bool ?? true)
await provider.postStateToWebview()
break
case "showSendButton":
await updateGlobalState("showSendButton", message.bool ?? true)
await provider.postStateToWebview()
break
case "showApiConfigurationButton":
await updateGlobalState("showApiConfigurationButton", message.bool ?? true)
await provider.postStateToWebview()
break
case "showAutoApproveTab":
await updateGlobalState("showAutoApproveTab", message.bool ?? true)
await provider.postStateToWebview()
break
case "showContextPercentageBar":
await updateGlobalState("showContextPercentageBar", message.bool ?? true)
await provider.postStateToWebview()
break
}
}
18 changes: 18 additions & 0 deletions src/i18n/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,23 @@
"preventCompletionWithOpenTodos": {
"description": "Prevent task completion when there are incomplete todos in the todo list"
}
},
"uiSettings": {
"description": "Customize which UI elements are visible in the interface",
"promptInputArea": {
"title": "Prompt Input Area Customization",
"showEnhancePromptButton": "Show 'Enhance Prompt' button",
"showCodebaseIndexingButton": "Show 'Codebase Indexing' button",
"showAddImagesToMessageButton": "Show 'Add Images to Message' button",
"showManageSlashCommandsButton": "Show 'Manage Slash Commands' button",
"showHintText": "Show hint text (\"@ to add context, / to switch modes...\")",
"showSendButton": "Show 'Send' button",
"showApiConfigurationButton": "Show 'API Configuration' button",
"showAutoApproveTab": "Show 'Auto-Approve' tab"
},
"generalUI": {
"title": "General UI Element Customization",
"showContextPercentageBar": "Show context percentage bar during chat"
}
}
}
10 changes: 10 additions & 0 deletions src/shared/ExtensionMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,16 @@ export type ExtensionState = Pick<
| "includeDiagnosticMessages"
| "maxDiagnosticMessages"
| "remoteControlEnabled"
// UI Settings
| "showEnhancePromptButton"
| "showCodebaseIndexingButton"
| "showAddImagesToMessageButton"
| "showManageSlashCommandsButton"
| "showHintText"
| "showSendButton"
| "showApiConfigurationButton"
| "showAutoApproveTab"
| "showContextPercentageBar"
> & {
version: string
clineMessages: ClineMessage[]
Expand Down
10 changes: 10 additions & 0 deletions src/shared/WebviewMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,16 @@ export interface WebviewMessage {
| "deleteCommand"
| "createCommand"
| "insertTextIntoTextarea"
// UI Settings
| "showEnhancePromptButton"
| "showCodebaseIndexingButton"
| "showAddImagesToMessageButton"
| "showManageSlashCommandsButton"
| "showHintText"
| "showSendButton"
| "showApiConfigurationButton"
| "showAutoApproveTab"
| "showContextPercentageBar"
text?: string
editedMessageContent?: string
tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "account"
Expand Down
134 changes: 74 additions & 60 deletions webview-ui/src/components/chat/ChatTextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
taskHistory,
clineMessages,
commands,
// UI Settings
showEnhancePromptButton,
showCodebaseIndexingButton,
showAddImagesToMessageButton,
showManageSlashCommandsButton,
showHintText,
showSendButton,
showApiConfigurationButton,
} = useExtensionState()

// Find the ID and display text for the currently selected API configuration
Expand Down Expand Up @@ -921,19 +929,21 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
<div className={cn("flex", "items-center", "gap-1", "min-w-0")}>
<div className="shrink-0">{renderModeSelector()}</div>

<div className={cn("flex-1", "min-w-0", "overflow-hidden")}>
<ApiConfigSelector
value={currentConfigId}
displayName={displayName}
disabled={selectApiConfigDisabled}
title={t("chat:selectApiConfig")}
onChange={handleApiConfigChange}
triggerClassName="w-full text-ellipsis overflow-hidden"
listApiConfigMeta={listApiConfigMeta || []}
pinnedApiConfigs={pinnedApiConfigs}
togglePinnedApiConfig={togglePinnedApiConfig}
/>
</div>
{showApiConfigurationButton && (
<div className={cn("flex-1", "min-w-0", "overflow-hidden")}>
<ApiConfigSelector
value={currentConfigId}
displayName={displayName}
disabled={selectApiConfigDisabled}
title={t("chat:selectApiConfig")}
onChange={handleApiConfigChange}
triggerClassName="w-full text-ellipsis overflow-hidden"
listApiConfigMeta={listApiConfigMeta || []}
pinnedApiConfigs={pinnedApiConfigs}
togglePinnedApiConfig={togglePinnedApiConfig}
/>
</div>
)}
</div>

<div className={cn("flex", "items-center", "gap-0.5", "shrink-0")}>
Expand All @@ -957,30 +967,32 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
</button>
</StandardTooltip>
)}
<SlashCommandsPopover />
<IndexingStatusBadge />
<StandardTooltip content={t("chat:addImages")}>
<button
aria-label={t("chat:addImages")}
disabled={shouldDisableImages}
onClick={!shouldDisableImages ? onSelectImages : undefined}
className={cn(
"relative inline-flex items-center justify-center",
"bg-transparent border-none p-1.5",
"rounded-md min-w-[28px] min-h-[28px]",
"text-vscode-foreground opacity-85",
"transition-all duration-150",
"hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
"active:bg-[rgba(255,255,255,0.1)]",
!shouldDisableImages && "cursor-pointer",
shouldDisableImages &&
"opacity-40 cursor-not-allowed grayscale-[30%] hover:bg-transparent hover:border-[rgba(255,255,255,0.08)] active:bg-transparent",
"mr-1",
)}>
<Image className="w-4 h-4" />
</button>
</StandardTooltip>
{showManageSlashCommandsButton && <SlashCommandsPopover />}
{showCodebaseIndexingButton && <IndexingStatusBadge />}
{showAddImagesToMessageButton && (
<StandardTooltip content={t("chat:addImages")}>
<button
aria-label={t("chat:addImages")}
disabled={shouldDisableImages}
onClick={!shouldDisableImages ? onSelectImages : undefined}
className={cn(
"relative inline-flex items-center justify-center",
"bg-transparent border-none p-1.5",
"rounded-md min-w-[28px] min-h-[28px]",
"text-vscode-foreground opacity-85",
"transition-all duration-150",
"hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
"active:bg-[rgba(255,255,255,0.1)]",
!shouldDisableImages && "cursor-pointer",
shouldDisableImages &&
"opacity-40 cursor-not-allowed grayscale-[30%] hover:bg-transparent hover:border-[rgba(255,255,255,0.08)] active:bg-transparent",
"mr-1",
)}>
<Image className="w-4 h-4" />
</button>
</StandardTooltip>
)}
</div>
</div>
)
Expand Down Expand Up @@ -1091,29 +1103,31 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
onScroll={() => updateHighlights()}
/>

<div className="absolute top-1 right-1 z-30">
<StandardTooltip content={t("chat:enhancePrompt")}>
<button
aria-label={t("chat:enhancePrompt")}
disabled={false}
onClick={handleEnhancePrompt}
className={cn(
"relative inline-flex items-center justify-center",
"bg-transparent border-none p-1.5",
"rounded-md min-w-[28px] min-h-[28px]",
"opacity-60 hover:opacity-100 text-vscode-descriptionForeground hover:text-vscode-foreground",
"transition-all duration-150",
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
"active:bg-[rgba(255,255,255,0.1)]",
"cursor-pointer",
)}>
<WandSparkles className={cn("w-4 h-4", isEnhancingPrompt && "animate-spin")} />
</button>
</StandardTooltip>
</div>
{showEnhancePromptButton && (
<div className="absolute top-1 right-1 z-30">
<StandardTooltip content={t("chat:enhancePrompt")}>
<button
aria-label={t("chat:enhancePrompt")}
disabled={false}
onClick={handleEnhancePrompt}
className={cn(
"relative inline-flex items-center justify-center",
"bg-transparent border-none p-1.5",
"rounded-md min-w-[28px] min-h-[28px]",
"opacity-60 hover:opacity-100 text-vscode-descriptionForeground hover:text-vscode-foreground",
"transition-all duration-150",
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
"active:bg-[rgba(255,255,255,0.1)]",
"cursor-pointer",
)}>
<WandSparkles className={cn("w-4 h-4", isEnhancingPrompt && "animate-spin")} />
</button>
</StandardTooltip>
</div>
)}

{!isEditMode && (
{!isEditMode && showSendButton && (
<div className="absolute bottom-1 right-1 z-30">
<StandardTooltip content={t("chat:sendMessage")}>
<button
Expand All @@ -1137,7 +1151,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
</div>
)}

{!inputValue && !isEditMode && (
{!inputValue && !isEditMode && showHintText && (
<div
className="absolute left-2 z-30 pr-9 flex items-center h-8 font-vscode-font-family text-vscode-editor-font-size leading-vscode-editor-line-height"
style={{
Expand Down
13 changes: 9 additions & 4 deletions webview-ui/src/components/chat/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
soundEnabled,
soundVolume,
cloudIsAuthenticated,
showContextPercentageBar,
showAutoApproveTab,
} = useExtensionState()

const messagesRef = useRef(messages)
Expand Down Expand Up @@ -1794,6 +1796,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
buttonsDisabled={sendingDisabled}
handleCondenseContext={handleCondenseContext}
todos={latestTodos}
showContextPercentageBar={showContextPercentageBar}
/>

{hasSystemPromptOverride && (
Expand Down Expand Up @@ -1858,7 +1861,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
// This ensures it takes its natural height when there's space
// but becomes scrollable when the viewport is too small
*/}
{!task && (
{!task && showAutoApproveTab && (
<div className="mb-1 flex-initial min-h-0">
<AutoApproveMenu />
</div>
Expand All @@ -1885,9 +1888,11 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
initialTopMostItemIndex={groupedMessages.length - 1}
/>
</div>
<div className={`flex-initial min-h-0 ${!areButtonsVisible ? "mb-1" : ""}`}>
<AutoApproveMenu />
</div>
{showAutoApproveTab && (
<div className={`flex-initial min-h-0 ${!areButtonsVisible ? "mb-1" : ""}`}>
<AutoApproveMenu />
</div>
)}
{areButtonsVisible && (
<div
className={`flex h-9 items-center mb-1 px-[15px] ${
Expand Down
4 changes: 3 additions & 1 deletion webview-ui/src/components/chat/TaskHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface TaskHeaderProps {
buttonsDisabled: boolean
handleCondenseContext: (taskId: string) => void
todos?: any[]
showContextPercentageBar?: boolean
}

const TaskHeader = ({
Expand All @@ -44,6 +45,7 @@ const TaskHeader = ({
buttonsDisabled,
handleCondenseContext,
todos,
showContextPercentageBar = true,
}: TaskHeaderProps) => {
const { t } = useTranslation()
const { apiConfiguration, currentTaskItem } = useExtensionState()
Expand Down Expand Up @@ -120,7 +122,7 @@ const TaskHeader = ({
</div>
</div>
</div>
{!isTaskExpanded && contextWindow > 0 && (
{!isTaskExpanded && contextWindow > 0 && showContextPercentageBar && (
<div className="flex items-center gap-2 text-sm" onClick={(e) => e.stopPropagation()}>
<StandardTooltip
content={
Expand Down
Loading
Loading