Skip to content

Commit 192a040

Browse files
authored
improvements to new chat sessions window (#296858)
* refactor chat widget attachment handling for clarity and improved functionality * refactor chat toolbar styles for improved consistency and visual clarity * enhance send button functionality with disabled state management * enhance NewChatWidget to update send button state based on editor content * enhance loading state management for branch and isolation mode pickers * enhance branch loading logic with error handling and loading state management * enhance repository loading with cancellation support and error handling * enhance send button implementation with Button widget and state management * Copilot CLI session 7c14814b-d36c-4bf5-8b17-d78ee84df3a3 changes * clear branch picker when loading a new repository in NewChatWidget * enhance loading indicator for chat input area with CSS animations * fix loading progress bar position in chat input area * add loading state handling to BranchPicker and NewChatWidget * add loading state management for repository and branch in NewChatWidget * remove loading class toggle from slot element in BranchPicker * add focus management for editor in NewChatWidget interactions * add loading spinner to toolbar and remove input area loading progress bar * reduce size of loading spinner in toolbar to improve UI consistency * add margin to loading spinner and set up hover management in NewChatWidget * layout editor after input slot fade-in animation in NewChatWidget * hide focus outline in chat editor for improved UI * update input area border color and remove focus outline in chat editor for improved UI * add loading delay for spinner visibility in NewChatWidget to enhance user experience * update border color for focused input area in chat editor for improved accessibility * update input area border color for improved accessibility * refactor loading delay handling in NewChatWidget for improved resource management * refactor toolbar creation in NewChatWidget to ensure attach button is consistently added
1 parent d8c97ea commit 192a040

File tree

5 files changed

+242
-53
lines changed

5 files changed

+242
-53
lines changed

src/vs/sessions/contrib/chat/browser/branchPicker.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ export class BranchPicker extends Disposable {
3737
private readonly _onDidChange = this._register(new Emitter<string | undefined>());
3838
readonly onDidChange: Event<string | undefined> = this._onDidChange.event;
3939

40+
private readonly _onDidChangeLoading = this._register(new Emitter<boolean>());
41+
readonly onDidChangeLoading: Event<boolean> = this._onDidChangeLoading.event;
42+
4043
private readonly _renderDisposables = this._register(new DisposableStore());
4144
private _slotElement: HTMLElement | undefined;
4245
private _triggerElement: HTMLElement | undefined;
@@ -68,26 +71,32 @@ export class BranchPicker extends Disposable {
6871

6972
if (!repository) {
7073
this._newSession?.setBranch(undefined);
74+
this._setLoading(false);
7175
this._updateTriggerLabel();
7276
return;
7377
}
7478

75-
const refs = await repository.getRefs({ pattern: 'refs/heads' });
76-
this._branches = refs
77-
.map(ref => ref.name)
78-
.filter((name): name is string => !!name)
79-
.filter(name => !name.includes(COPILOT_WORKTREE_PATTERN));
80-
81-
// Select active branch, main, master, or the first branch by default
82-
const defaultBranch = this._branches.find(b => b === repository.state.get().HEAD?.name)
83-
?? this._branches.find(b => b === 'main')
84-
?? this._branches.find(b => b === 'master')
85-
?? this._branches[0];
86-
if (defaultBranch) {
87-
this._selectBranch(defaultBranch);
79+
this._setLoading(true);
80+
81+
try {
82+
const refs = await repository.getRefs({ pattern: 'refs/heads' });
83+
this._branches = refs
84+
.map(ref => ref.name)
85+
.filter((name): name is string => !!name)
86+
.filter(name => !name.includes(COPILOT_WORKTREE_PATTERN));
87+
88+
// Select active branch, main, master, or the first branch by default
89+
const defaultBranch = this._branches.find(b => b === repository.state.get().HEAD?.name)
90+
?? this._branches.find(b => b === 'main')
91+
?? this._branches.find(b => b === 'master')
92+
?? this._branches[0];
93+
if (defaultBranch) {
94+
this._selectBranch(defaultBranch);
95+
}
96+
} finally {
97+
this._setLoading(false);
98+
this._updateTriggerLabel();
8899
}
89-
90-
this._updateTriggerLabel();
91100
}
92101

93102
/**
@@ -195,4 +204,8 @@ export class BranchPicker extends Disposable {
195204
dom.append(this._triggerElement, renderIcon(Codicon.chevronDown));
196205
this._slotElement?.classList.toggle('disabled', isDisabled);
197206
}
207+
208+
private _setLoading(loading: boolean): void {
209+
this._onDidChangeLoading.fire(loading);
210+
}
198211
}

src/vs/sessions/contrib/chat/browser/media/chatWelcomePart.css

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,33 @@
309309
color: var(--vscode-descriptionForeground);
310310
}
311311

312+
.sessions-chat-picker-slot.loading .action-label {
313+
opacity: 0.5;
314+
cursor: default;
315+
pointer-events: none;
316+
}
317+
318+
.sessions-chat-picker-slot.loading .action-label .codicon-chevron-down {
319+
display: none;
320+
}
321+
322+
.sessions-chat-picker-slot.loading .action-label::after {
323+
content: '';
324+
display: inline-block;
325+
width: 12px;
326+
height: 12px;
327+
margin-left: 4px;
328+
border: 1.5px solid var(--vscode-descriptionForeground);
329+
border-top-color: transparent;
330+
border-radius: 50%;
331+
animation: sessions-chat-picker-spin 0.8s linear infinite;
332+
flex-shrink: 0;
333+
}
334+
335+
@keyframes sessions-chat-picker-spin {
336+
to { transform: rotate(360deg); }
337+
}
338+
312339
.sessions-chat-picker-slot .action-label .codicon {
313340
font-size: 14px;
314341
flex-shrink: 0;

src/vs/sessions/contrib/chat/browser/media/chatWidget.css

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
}
3535

3636
.sessions-chat-input-area:focus-within {
37-
border-color: var(--vscode-focusBorder);
37+
border-color: var(--vscode-input-border, var(--vscode-contrastBorder, transparent));
3838
}
3939

4040
/* Editor */
@@ -57,8 +57,9 @@
5757
.sessions-chat-toolbar {
5858
display: flex;
5959
align-items: center;
60-
padding: 4px 8px;
60+
padding: 0 6px 6px 6px;
6161
gap: 4px;
62+
color: var(--vscode-icon-foreground);
6263
}
6364

6465
.sessions-chat-toolbar-spacer {
@@ -75,52 +76,73 @@
7576
display: flex;
7677
align-items: center;
7778
gap: 4px;
78-
padding: 3px 8px;
79+
height: 16px;
80+
padding: 3px 6px;
7981
border-radius: 4px;
8082
font-size: 12px;
8183
cursor: pointer;
82-
color: var(--vscode-descriptionForeground);
84+
color: var(--vscode-icon-foreground);
8385
}
8486

8587
.sessions-chat-model-picker .action-label:hover {
8688
background-color: var(--vscode-toolbar-hoverBackground);
87-
color: var(--vscode-foreground);
8889
}
8990

9091
.sessions-chat-model-picker .action-label .codicon {
9192
font-size: 12px;
9293
}
9394

94-
/* Send button */
95+
/* Send button - wraps a Button widget */
9596
.sessions-chat-send-button {
9697
display: flex;
9798
align-items: center;
99+
}
100+
101+
.sessions-chat-send-button .monaco-button {
102+
display: flex;
103+
align-items: center;
98104
justify-content: center;
99-
width: 26px;
100-
height: 26px;
105+
width: 22px;
106+
height: 22px;
107+
min-width: 22px;
108+
padding: 0;
101109
border-radius: 4px;
102-
cursor: pointer;
103-
color: var(--vscode-descriptionForeground);
104-
background: transparent;
105-
border: none;
106-
outline: none;
110+
color: var(--vscode-icon-foreground);
111+
background: transparent !important;
112+
border: none !important;
107113
}
108114

109-
.sessions-chat-send-button:hover {
110-
background-color: var(--vscode-toolbar-hoverBackground);
111-
color: var(--vscode-foreground);
115+
.sessions-chat-send-button .monaco-button:not(.disabled):hover {
116+
background-color: var(--vscode-toolbar-hoverBackground) !important;
112117
}
113118

114-
.sessions-chat-send-button:focus-visible {
115-
outline: 1px solid var(--vscode-focusBorder);
116-
outline-offset: -1px;
119+
.sessions-chat-send-button .monaco-button .codicon {
120+
font-size: 16px;
117121
}
118122

119-
.sessions-chat-send-button .codicon {
120-
font-size: 16px;
123+
/* Loading spinner in toolbar */
124+
.sessions-chat-loading-spinner {
125+
display: none;
126+
width: 12px;
127+
height: 12px;
128+
margin-right: 4px;
129+
border: 1.5px solid var(--vscode-icon-foreground);
130+
border-top-color: transparent;
131+
border-radius: 50%;
132+
animation: sessions-chat-spin 0.8s linear infinite;
133+
opacity: 0.6;
134+
flex-shrink: 0;
135+
}
136+
137+
.sessions-chat-loading-spinner.visible {
138+
display: block;
139+
}
140+
141+
@keyframes sessions-chat-spin {
142+
to { transform: rotate(360deg); }
121143
}
122144

123-
/* Attach row (above editor, inside input area) */
145+
/* Attach row (pills only, above editor, inside input area) */
124146
.sessions-chat-attach-row {
125147
display: flex;
126148
flex-wrap: wrap;
@@ -129,24 +151,27 @@
129151
padding: 4px 6px 0 6px;
130152
}
131153

154+
.sessions-chat-attach-row:has(.sessions-chat-attached-context:empty) {
155+
display: none;
156+
}
157+
132158
/* Attach context button */
133159
.sessions-chat-attach-button {
134160
display: flex;
135161
align-items: center;
136162
justify-content: center;
137-
width: 26px;
138-
height: 26px;
163+
width: 22px;
164+
height: 22px;
139165
border-radius: 4px;
140166
cursor: pointer;
141-
color: var(--vscode-descriptionForeground);
167+
color: var(--vscode-icon-foreground);
142168
background: transparent;
143169
border: none;
144170
outline: none;
145171
}
146172

147173
.sessions-chat-attach-button:hover {
148174
background-color: var(--vscode-toolbar-hoverBackground);
149-
color: var(--vscode-foreground);
150175
}
151176

152177
.sessions-chat-attach-button:focus-visible {

0 commit comments

Comments
 (0)