Skip to content

Commit 1dcbd07

Browse files
Make QuickChat styles closer to QuickPick (#190101)
* Make QuickChat styles closer to QuickPick This does two main things: * introduces a "compact" chat style that generally reduces padding and other small things like makes avatars smaller * Misc other styles to make quick chat more quick pick-y like using the same border radius and whatnot. For now, it still has the titlebar, but I'll remove that once I have a better spot for the buttons. * Rob feedback
1 parent d18b853 commit 1dcbd07

File tree

6 files changed

+112
-13
lines changed

6 files changed

+112
-13
lines changed

src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class QuickChat extends Disposable {
214214
this.widget = this._register(
215215
scopedInstantiationService.createInstance(
216216
ChatWidget,
217-
{ resource: true, renderInputOnTop: true },
217+
{ resource: true, renderInputOnTop: true, renderStyle: 'compact' },
218218
{
219219
listForeground: editorForeground,
220220
listBackground: editorBackground,

src/vs/workbench/contrib/chat/browser/chat.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,20 @@ export interface IChatCodeBlockInfo {
4747

4848
export type ChatTreeItem = IChatRequestViewModel | IChatResponseViewModel | IChatWelcomeMessageViewModel;
4949

50-
export type IChatWidgetViewContext = { viewId: string; renderInputOnTop?: false } | { resource: boolean; renderInputOnTop?: boolean };
50+
export interface IBaseChatWidgetViewContext {
51+
renderInputOnTop?: boolean;
52+
renderStyle?: 'default' | 'compact';
53+
}
54+
55+
export interface IChatViewViewContext extends IBaseChatWidgetViewContext {
56+
viewId: string;
57+
}
58+
59+
export interface IChatResourceViewContext extends IBaseChatWidgetViewContext {
60+
resource: boolean;
61+
}
62+
63+
export type IChatWidgetViewContext = IChatViewViewContext | IChatResourceViewContext;
5164

5265
export interface IChatWidget {
5366
readonly onDidChangeViewModel: Event<void>;

src/vs/workbench/contrib/chat/browser/chatInputPart.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
7878

7979
constructor(
8080
// private readonly editorOptions: ChatEditorOptions, // TODO this should be used
81-
private readonly options: { renderFollowups: boolean },
81+
private readonly options: { renderFollowups: boolean; renderStyle?: 'default' | 'compact' },
8282
@IChatWidgetHistoryService private readonly historyService: IChatWidgetHistoryService,
8383
@IModelService private readonly modelService: IModelService,
8484
@IInstantiationService private readonly instantiationService: IInstantiationService,
@@ -198,7 +198,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
198198
options.fontFamily = DEFAULT_FONT_FAMILY;
199199
options.fontSize = 13;
200200
options.lineHeight = 20;
201-
options.padding = { top: 8, bottom: 8 };
201+
options.padding = this.options.renderStyle === 'compact' ? { top: 2, bottom: 2 } : { top: 8, bottom: 8 };
202202
options.cursorWidth = 1;
203203
options.wrappingStrategy = 'advanced';
204204
options.bracketPairColorization = { enabled: false };

src/vs/workbench/contrib/chat/browser/chatListRenderer.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ export interface IChatRendererDelegate {
9898
getSlashCommands(): ISlashCommand[];
9999
}
100100

101+
export interface IChatListItemRendererOptions {
102+
readonly renderStyle?: 'default' | 'compact';
103+
}
104+
101105
export class ChatListItemRenderer extends Disposable implements ITreeRenderer<ChatTreeItem, FuzzyScore, IChatListItemTemplate> {
102106
static readonly cursorCharacter = '\u258c';
103107
static readonly ID = 'item';
@@ -122,6 +126,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
122126

123127
constructor(
124128
private readonly editorOptions: ChatEditorOptions,
129+
private readonly rendererOptions: IChatListItemRendererOptions,
125130
private readonly delegate: IChatRendererDelegate,
126131
@IInstantiationService private readonly instantiationService: IInstantiationService,
127132
@IConfigurationService private readonly configService: IConfigurationService,
@@ -198,6 +203,9 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
198203
renderTemplate(container: HTMLElement): IChatListItemTemplate {
199204
const templateDisposables = new DisposableStore();
200205
const rowContainer = dom.append(container, $('.interactive-item-container'));
206+
if (this.rendererOptions.renderStyle === 'compact') {
207+
rowContainer.classList.add('interactive-item-compact');
208+
}
201209
const header = dom.append(rowContainer, $('.header'));
202210
const user = dom.append(header, $('.user'));
203211
const avatar = dom.append(user, $('.avatar'));

src/vs/workbench/contrib/chat/browser/chatWidget.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { WorkbenchObjectTree } from 'vs/platform/list/browser/listService';
2222
import { IViewsService } from 'vs/workbench/common/views';
2323
import { ChatTreeItem, IChatAccessibilityService, IChatCodeBlockInfo, IChatWidget, IChatWidgetService, IChatWidgetViewContext } from 'vs/workbench/contrib/chat/browser/chat';
2424
import { ChatInputPart } from 'vs/workbench/contrib/chat/browser/chatInputPart';
25-
import { ChatAccessibilityProvider, ChatListDelegate, ChatListItemRenderer, IChatRendererDelegate } from 'vs/workbench/contrib/chat/browser/chatListRenderer';
25+
import { ChatAccessibilityProvider, ChatListDelegate, ChatListItemRenderer, IChatListItemRendererOptions, IChatRendererDelegate } from 'vs/workbench/contrib/chat/browser/chatListRenderer';
2626
import { ChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatOptions';
2727
import { ChatViewPane } from 'vs/workbench/contrib/chat/browser/chatViewPane';
2828
import { CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatContextKeys';
@@ -147,17 +147,18 @@ export class ChatWidget extends Disposable implements IChatWidget {
147147
const viewId = 'viewId' in this.viewContext ? this.viewContext.viewId : undefined;
148148
this.editorOptions = this._register(this.instantiationService.createInstance(ChatEditorOptions, viewId, this.styles.listForeground, this.styles.inputEditorBackground, this.styles.resultEditorBackground));
149149
const renderInputOnTop = this.viewContext.renderInputOnTop ?? false;
150+
const renderStyle = this.viewContext.renderStyle;
150151

151152
this.container = dom.append(parent, $('.interactive-session'));
152153
if (renderInputOnTop) {
153-
this.createInput(this.container, { renderFollowups: false });
154+
this.createInput(this.container, { renderFollowups: false, renderStyle });
154155
this.listContainer = dom.append(this.container, $(`.interactive-list`));
155156
} else {
156157
this.listContainer = dom.append(this.container, $(`.interactive-list`));
157158
this.createInput(this.container);
158159
}
159160

160-
this.createList(this.listContainer);
161+
this.createList(this.listContainer, { renderStyle });
161162

162163
this._register(this.editorOptions.onDidChange(() => this.onDidStyleChange()));
163164
this.onDidStyleChange();
@@ -270,14 +271,19 @@ export class ChatWidget extends Disposable implements IChatWidget {
270271
return this.slashCommandsPromise;
271272
}
272273

273-
private createList(listContainer: HTMLElement): void {
274+
private createList(listContainer: HTMLElement, options: IChatListItemRendererOptions): void {
274275
const scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection([IContextKeyService, this.contextKeyService]));
275276
const delegate = scopedInstantiationService.createInstance(ChatListDelegate);
276277
const rendererDelegate: IChatRendererDelegate = {
277278
getListLength: () => this.tree.getNode(null).visibleChildrenCount,
278279
getSlashCommands: () => this.lastSlashCommands ?? [],
279280
};
280-
this.renderer = this._register(scopedInstantiationService.createInstance(ChatListItemRenderer, this.editorOptions, rendererDelegate));
281+
this.renderer = this._register(scopedInstantiationService.createInstance(
282+
ChatListItemRenderer,
283+
this.editorOptions,
284+
options,
285+
rendererDelegate
286+
));
281287
this._register(this.renderer.onDidClickFollowup(item => {
282288
this.acceptInput(item);
283289
}));
@@ -354,8 +360,11 @@ export class ChatWidget extends Disposable implements IChatWidget {
354360
this.previousTreeScrollHeight = this.tree.scrollHeight;
355361
}
356362

357-
private createInput(container: HTMLElement, options?: { renderFollowups: boolean }): void {
358-
this.inputPart = this._register(this.instantiationService.createInstance(ChatInputPart, { renderFollowups: options?.renderFollowups ?? true }));
363+
private createInput(container: HTMLElement, options?: { renderFollowups: boolean; renderStyle?: 'default' | 'compact' }): void {
364+
this.inputPart = this._register(this.instantiationService.createInstance(ChatInputPart, {
365+
renderFollowups: options?.renderFollowups ?? true,
366+
renderStyle: options?.renderStyle,
367+
}));
359368
this.inputPart.render(container, '', this);
360369

361370
this._register(this.inputPart.onDidFocus(() => this._onDidFocus.fire()));
@@ -510,8 +519,8 @@ export class ChatWidget extends Disposable implements IChatWidget {
510519

511520
this.layout(
512521
Math.min(
513-
// we add an additional 25px in order to show that there is scrollable content
514-
inputHeight + listHeight + (totalMessages.length > 2 ? 25 : 0),
522+
// we add an additional 18px in order to show that there is scrollable content
523+
inputHeight + listHeight + (totalMessages.length > 2 ? 18 : 0),
515524
this._dynamicMessageLayoutData!.maxHeight
516525
),
517526
this.container.offsetWidth

src/vs/workbench/contrib/chat/browser/media/chat.css

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,49 @@
178178
color: var(--vscode-textPreformat-foreground);
179179
}
180180

181+
.interactive-item-container.interactive-item-compact {
182+
padding: 8px 20px 0 20px;
183+
}
184+
185+
.interactive-item-container.interactive-item-compact .header {
186+
height: 16px;
187+
}
188+
189+
.interactive-item-container.interactive-item-compact .header .avatar {
190+
width: 16px;
191+
height: 16px;
192+
}
193+
194+
.interactive-item-container.interactive-item-compact .header .avatar .icon {
195+
width: 16px;
196+
height: 16px;
197+
}
198+
199+
.interactive-item-container.interactive-item-compact .value {
200+
min-height: 0;
201+
}
202+
203+
.interactive-item-container.interactive-item-compact .value p {
204+
margin: 0 0 8px 0;
205+
}
206+
207+
.interactive-item-container.interactive-item-compact .value h1 {
208+
margin: 8px 0;
209+
210+
}
211+
212+
.interactive-item-container.interactive-item-compact .value h2 {
213+
margin: 8px 0;
214+
}
215+
216+
.interactive-item-container.interactive-item-compact .value h3 {
217+
margin: 8px 0;
218+
}
219+
220+
.interactive-item-container.interactive-item-compact .value p {
221+
margin: 0 0 8px 0;
222+
}
223+
181224
.interactive-session .interactive-input-and-toolbar {
182225
display: flex;
183226
box-sizing: border-box;
@@ -269,6 +312,10 @@
269312
border-radius: 4px;
270313
}
271314

315+
.interactive-item-container.interactive-item-compact .interactive-result-editor-wrapper {
316+
margin: 0 0 8px 0;
317+
}
318+
272319
.interactive-response .interactive-response-error-details {
273320
display: flex;
274321
align-items: start;
@@ -359,3 +406,25 @@
359406
-webkit-mask-image: linear-gradient(rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.05));
360407
mask-image: linear-gradient(rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.05));
361408
}
409+
410+
/* #region Quick Chat */
411+
412+
.quick-input-widget .interactive-session .interactive-input-part {
413+
padding: 8px 6px 6px 6px;
414+
border-top: 0;
415+
}
416+
417+
.quick-input-widget .interactive-session .interactive-input-part .interactive-execute-toolbar {
418+
bottom: 1px;
419+
}
420+
421+
.quick-input-widget .interactive-session .interactive-input-and-toolbar {
422+
margin: 0;
423+
border-radius: 2px;
424+
}
425+
426+
.quick-input-widget .interactive-session .interactive-input-and-toolbar .chat-slash-command-content-widget {
427+
top: 2px !important;
428+
}
429+
430+
/* #endregion */

0 commit comments

Comments
 (0)