Skip to content

Commit 4056598

Browse files
committed
style(webview): 优化样式变量及组件样式细节
- 更新全局CSS变量,统一主色调为 #4d6bfe,替换原 vscode 主题色 - 修改 ContinuePrompt 和 PermissionPrompt 组件边框及背景为主色调变量 - 调整 PromptAttachments 中附件标签的文字颜色为主色调 - 优化 PromptAttachments 中移除按钮的圆角样式 - 修改 SkillsTags 组件 Badge 圆角为统一圆角样式 refactor(input-prompt): 用下拉菜单替代计划模式开关 - 用 DropdownMenu 替换旧版 Switch 组件控制 planMode - planMode 状态类型调整为 "true" | "false" 字符串 - 添加下拉选项说明不同模式的行为含义 - 发送消息时将字符串状态转换为布尔值传递 - 优化按钮显示图标及文字切换,区分默认与计划模式 feat(messages): 当消息为空时显示欢迎界面 - 新增无消息时展示 Deep Code AI IDE 欢迎图标和提示文字 - 保持消息渲染逻辑稳定,分角色正确展示各消息气泡 - 改进滚动处理逻辑,自动滚到底部 fix(messages): 移除多余控制台日志语句 - 删除 handleToBottom 函数中的无用 console.log 调试信息
1 parent c4c0bab commit 4056598

7 files changed

Lines changed: 115 additions & 51 deletions

File tree

packages/vscode-ide-companion/src/webview/components/ContinuePrompt.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export interface ContinuePromptProps {
99
export default function ContinuePrompt({ onContinue, onDismiss }: ContinuePromptProps) {
1010
return (
1111
<div className="px-4 py-2 w-full max-w-237.5 mx-auto min-w-sm">
12-
<div className="rounded-md border border-(--vscode-focusBorder) bg-(--vscode-editor-background) p-3 text-sm">
12+
<div className="rounded-md border border-primary bg-background p-3 text-sm">
1313
<div className="flex items-center justify-between mb-2">
1414
<span className="font-medium">Session interrupted</span>
1515
<Button

packages/vscode-ide-companion/src/webview/components/InputPrompt.tsx

Lines changed: 93 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import SkillsTags from "@/webview/components/SkillsTags";
44
import ContextIndicator from "@/webview/components/ContextIndicator";
55
import { PromptAttachments, usePromptAttachments } from "@/webview/components/PromptAttachments";
66
import type { ActiveEditor, EditingMessage, SessionMessage, SkillInfo, TokenTelemetry } from "@/webview/types";
7-
import { FileCodeIcon, Reply, Siren, Square } from "lucide-react";
7+
import { FileCodeIcon, Hand, Reply, Siren, Square, SquareChartGantt } from "lucide-react";
88
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupTextarea } from "@/webview/components/ui/input-group";
99
import { Separator } from "@/webview/components/ui/separator";
1010
import { HoverCard, HoverCardContent, HoverCardTrigger } from "./ui/hover-card";
@@ -13,6 +13,16 @@ import { Field, FieldDescription, FieldGroup } from "./ui/field";
1313
import { Spinner } from "@/webview/components/ui/spinner";
1414
import { Switch } from "@/webview/components/ui/switch";
1515
import { Tooltip, TooltipContent, TooltipTrigger } from "@/webview/components/ui/tooltip";
16+
import {
17+
DropdownMenu,
18+
DropdownMenuContent,
19+
DropdownMenuGroup,
20+
DropdownMenuLabel,
21+
DropdownMenuRadioGroup,
22+
DropdownMenuRadioItem,
23+
DropdownMenuTrigger,
24+
} from "@/webview/components/ui/dropdown-menu";
25+
import { Item, ItemContent, ItemDescription, ItemMedia, ItemTitle } from "@/webview/components/ui/item";
1626

1727
export interface InputPromptProps {
1828
loading: boolean;
@@ -54,7 +64,7 @@ export default function InputPrompt({
5464
onClearEditingMessage,
5565
}: InputPromptProps) {
5666
const [value, setValue] = useState<string>("");
57-
const [planMode, setPlanMode] = useState<boolean>(false);
67+
const [planMode, setPlanMode] = useState<"false" | "true">("false");
5868
const [history, setHistory] = useState<string[]>([]);
5969
const [historyIdx, setHistoryIdx] = useState<number>(-1);
6070
const [draftBeforeHistory, setDraftBeforeHistory] = useState<string>("");
@@ -125,7 +135,7 @@ export default function InputPrompt({
125135
setValue("");
126136
setHistoryIdx(-1);
127137

128-
onSendPrompt(trimmed, selectedSkills, images, { ...reply, planMode });
138+
onSendPrompt(trimmed, selectedSkills, images, { ...reply, planMode: planMode === "true" });
129139
onSelectSkills([]);
130140
clearAttachments();
131141
onClearEditingMessage();
@@ -237,18 +247,6 @@ export default function InputPrompt({
237247
}}
238248
/>
239249
<Separator orientation="vertical" className="h-5 mt-1.5" />
240-
<Tooltip>
241-
<TooltipTrigger asChild>
242-
<div className="flex items-center gap-1 cursor-pointer">
243-
<Siren className="size-3.5" />
244-
<Switch id="switch-size-sm" checked={planMode} onCheckedChange={(e) => setPlanMode(e)} size="sm" />
245-
</div>
246-
</TooltipTrigger>
247-
<TooltipContent side="bottom">
248-
<p>Plan Mode</p>
249-
</TooltipContent>
250-
</Tooltip>
251-
<Separator orientation="vertical" className="h-5 mt-1.5" />
252250
<ContextIndicator tokenTelemetry={tokenTelemetry} />
253251
<Separator orientation="vertical" className="h-5 mt-1.5" />
254252
{activeEditor && (
@@ -272,31 +270,86 @@ export default function InputPrompt({
272270
</HoverCardContent>
273271
</HoverCard>
274272
)}
275-
{loading ? (
276-
<InputGroupButton
277-
variant="secondary"
278-
size="icon-sm"
279-
className="ml-auto group"
280-
onClick={onInterrupt}
281-
title="Stop"
282-
>
283-
<Square className="h-3 w-3 hidden fill-primary group-hover:block" strokeWidth={0} />
284-
<Spinner className="h-4 w-4 block group-hover:hidden text-primary" />
285-
</InputGroupButton>
286-
) : (
287-
<InputGroupButton
288-
variant="default"
289-
className={cn("ml-auto cursor-pointer", {
290-
"cursor-not-allowed!": !hasContent && !loading,
291-
})}
292-
onClick={handleSend}
293-
disabled={!hasContent && !loading}
294-
title="Send"
295-
size="icon-sm"
296-
>
297-
<Reply className="rotate-x-180" />
298-
</InputGroupButton>
299-
)}
273+
<div className="ml-auto flex gap-2 items-center">
274+
<DropdownMenu>
275+
<DropdownMenuTrigger asChild>
276+
<InputGroupButton variant="ghost" className="h-8">
277+
{planMode === "true" ? (
278+
<div className="flex items-center gap-0.5">
279+
<SquareChartGantt className="size-3.5" strokeWidth={1.5} />
280+
<span className="text-xs font-normal">Plan</span>
281+
</div>
282+
) : (
283+
<div className="flex items-center gap-0.5">
284+
<Hand className="size-3.5" strokeWidth={1.5} />
285+
<span className="text-xs font-normal">Default</span>
286+
</div>
287+
)}
288+
</InputGroupButton>
289+
</DropdownMenuTrigger>
290+
<DropdownMenuContent className="w-80" side="top" align="end">
291+
<DropdownMenuGroup>
292+
<DropdownMenuLabel>Modes</DropdownMenuLabel>
293+
<DropdownMenuRadioGroup
294+
value={planMode}
295+
onValueChange={(value) => setPlanMode(value as "true" | "false")}
296+
>
297+
<DropdownMenuRadioItem value="false">
298+
<Item size="xs">
299+
<ItemMedia variant="icon">
300+
<Hand className="size-4.5 mt-2.5" strokeWidth={1.5} />
301+
</ItemMedia>
302+
<ItemContent>
303+
<ItemTitle className="text-xs">Default</ItemTitle>
304+
<ItemDescription className="text-[10px]">
305+
Deep code will ask for approval before making each edit
306+
</ItemDescription>
307+
</ItemContent>
308+
</Item>
309+
</DropdownMenuRadioItem>
310+
<DropdownMenuRadioItem value="true">
311+
<Item size="xs">
312+
<ItemMedia variant="icon">
313+
<SquareChartGantt className="size-4.5 mt-2.5" strokeWidth={1.5} />
314+
</ItemMedia>
315+
<ItemContent>
316+
<ItemTitle className="text-xs">Plan</ItemTitle>
317+
<ItemDescription className="text-[8px]">
318+
Deep code will explore the code and present a plan before editing
319+
</ItemDescription>
320+
</ItemContent>
321+
</Item>
322+
</DropdownMenuRadioItem>
323+
</DropdownMenuRadioGroup>
324+
</DropdownMenuGroup>
325+
</DropdownMenuContent>
326+
</DropdownMenu>
327+
{loading ? (
328+
<InputGroupButton
329+
variant="secondary"
330+
size="icon-sm"
331+
className="group"
332+
onClick={onInterrupt}
333+
title="Stop"
334+
>
335+
<Square className="h-3 w-3 hidden fill-primary group-hover:block" strokeWidth={0} />
336+
<Spinner className="h-4 w-4 block group-hover:hidden text-primary" />
337+
</InputGroupButton>
338+
) : (
339+
<InputGroupButton
340+
variant="default"
341+
className={cn("cursor-pointer", {
342+
"cursor-not-allowed!": !hasContent && !loading,
343+
})}
344+
onClick={handleSend}
345+
disabled={!hasContent && !loading}
346+
title="Send"
347+
size="icon-sm"
348+
>
349+
<Reply className="rotate-x-180" />
350+
</InputGroupButton>
351+
)}
352+
</div>
300353
</InputGroupAddon>
301354
<SkillsTags
302355
selectedSkills={selectedSkills}

packages/vscode-ide-companion/src/webview/components/Messages.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ToolBubble, {
1010
import SystemBubble from "@/webview/components/bubbles/SystemBubble";
1111
import type { EditingMessage, SessionMessage } from "@/webview/types";
1212
import AskQuestionSummary from "@/webview/components/AskQuestionSummary";
13+
import icon from "../../../assets/deepcoding_icon.png";
1314

1415
interface MessagesProps {
1516
messages: SessionMessage[];
@@ -23,7 +24,6 @@ const Messages = forwardRef<HTMLDivElement, MessagesProps>(
2324
const bottomRef = useRef<HTMLDivElement>(null);
2425

2526
const handleToBottom = () => {
26-
console.log("handleToBottom");
2727
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
2828
};
2929
useEffect(() => {
@@ -34,6 +34,17 @@ const Messages = forwardRef<HTMLDivElement, MessagesProps>(
3434
// return bottomRef.current ? bottomRef.current : undefined;
3535
// })
3636

37+
if (messages.length === 0) {
38+
return (
39+
<div className="flex-1 flex flex-col justify-center items-center w-full">
40+
<img src={icon} alt="" className="size-32 shrink-0 mb-6" />
41+
<div className="mb-3 text-[16px] font-semibold">Welcome to the Deep Code AI IDE!</div>
42+
<p className="text-xs text-muted-foreground">
43+
What would you like to do? Ask about this codebase or we can start writing code.
44+
</p>
45+
</div>
46+
);
47+
}
3748
return (
3849
<ScrollArea
3950
ref={ref}

packages/vscode-ide-companion/src/webview/components/PermissionPrompt.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ export default function PermissionPrompt({
249249

250250
return (
251251
<div className="px-4 py-2 w-full max-w-237.5 mx-auto min-w-sm">
252-
<div className="rounded-md border border-(--vscode-focusBorder) bg-(--vscode-editor-background) p-3 text-sm">
252+
<div className="rounded-md border border-primary bg-background p-3 text-sm">
253253
<div className="flex items-center justify-between mb-2">
254254
<div>
255255
<span className="font-medium">Permission required</span>

packages/vscode-ide-companion/src/webview/components/PromptAttachments.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,15 @@ export function PromptAttachments({ attachments, onRemove }: PromptAttachmentsPr
121121
<HoverCardTrigger asChild>
122122
<div
123123
key={attachment.id}
124-
className="relative group flex items-center gap-1 rounded-md cursor-pointer border border-border bg-accent/50 text-xs text-muted-foreground hover:bg-accent transition-colors"
124+
className="relative group flex items-center gap-1 rounded cursor-pointer border border-border bg-accent/50 text-xs text-muted-foreground hover:bg-accent transition-colors"
125125
>
126126
<div className="flex items-center gap-1 py-0.5 px-1.5">
127127
<img src={attachment.dataUrl} alt={attachment.label} className="size-3 rounded-xs object-cover" />
128-
<span className="max-w-20 truncate">{attachment.label}</span>
128+
<span className="max-w-20 truncate text-primary">{attachment.label}</span>
129129
</div>
130130
<Button
131131
variant="ghost"
132-
className="py-2.5 size-3 inline-flex cursor-pointer text-muted-foreground hover:bg-destructive/10 hover:text-destructive focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
132+
className="py-2.5 size-3 inline-flex cursor-pointer rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
133133
onClick={() => onRemove(attachment.id)}
134134
title="Remove"
135135
>

packages/vscode-ide-companion/src/webview/components/SkillsTags.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default function SkillsTags({ selectedSkills, onRemove }: SkillsTagsProps
1515
return (
1616
<InputGroupAddon className="flex flex-wrap gap-1.5" align="block-start">
1717
{selectedSkills.map((skill) => (
18-
<Badge key={skill.name} variant="secondary" className="h-6 gap-1 rounded-md text-xs pr-0">
18+
<Badge key={skill.name} variant="secondary" className="h-6 gap-1 rounded text-xs pr-0">
1919
{skill.name}
2020
<Button
2121
variant="ghost"

packages/vscode-ide-companion/src/webview/index.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
/* editorHoverWidget is used for hover popups like HoverCard */
3030
--popover: var(--vscode-editorHoverWidget-background, var(--vscode-sideBar-background, #ffffff));
3131
--popover-foreground: var(--vscode-editorHoverWidget-foreground, var(--vscode-sideBar-foreground, #333333));
32-
--primary: var(--vscode-button-background, #0066cc);
32+
--primary: #4d6bfe;
3333
--primary-foreground: var(--vscode-button-foreground, #ffffff);
3434
--secondary: var(--vscode-toolbar-background, #e8e8e8);
3535
--secondary-foreground: var(--vscode-toolbar-foreground, #333333);
@@ -45,7 +45,7 @@
4545
--color-input: var(--vscode-input-border, var(--border));
4646
/* Input background uses editor background */
4747
--input-bg: var(--vscode-input-background, #ffffff);
48-
--ring: var(--vscode-focusBorder, #0066cc);
48+
--ring: #4d6bfe;;
4949
--chart-1: var(--vscode-charts-blue, #0066cc);
5050
--chart-2: var(--vscode-charts-orange, #cc6600);
5151
--chart-3: var(--vscode-charts-green, #22863a);
@@ -117,7 +117,7 @@
117117
/* editorHoverWidget is used for hover popups like HoverCard */
118118
--popover: var(--vscode-editorHoverWidget-background, var(--vscode-sideBar-background, #252526));
119119
--popover-foreground: var(--vscode-editorHoverWidget-foreground, var(--vscode-sideBar-foreground, #cccccc));
120-
--primary: var(--vscode-button-background, #0e639c);
120+
--primary: #4d6bfe;
121121
--primary-foreground: var(--vscode-button-foreground, #ffffff);
122122
--secondary: var(--vscode-toolbar-background, #2d2d2d);
123123
--secondary-foreground: var(--vscode-toolbar-foreground, #cccccc);
@@ -130,7 +130,7 @@
130130
--success-foreground: var(--vscode-editor-background, #1e1e1e);
131131
--border: var(--vscode-panel-border, #3c3c3c);
132132
--input: var(--vscode-input-background, #3c3c3c);
133-
--ring: var(--vscode-focusBorder, #0e639c);
133+
--ring: #4d6bfe;;
134134
--chart-1: var(--vscode-charts-blue, #75baff);
135135
--chart-2: var(--vscode-charts-orange, #d18616);
136136
--chart-3: var(--vscode-charts-green, #89d185);

0 commit comments

Comments
 (0)