Skip to content

Commit 7bc0db6

Browse files
Copilotalexr00
andauthored
Show empty commits with centered webview instead of notification (#8103)
* Initial plan * Initial planning for empty commit display feature Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> * Add EmptyCommitFileSystemProvider for displaying empty commits Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> * Replace file system provider with webview for empty commits - Removed EmptyCommitFileSystemProvider and related URI scheme - Created showEmptyCommitWebview() function with centered message - Updated openCommitChanges() to accept extensionUri and show webview - Styled webview to display message centered similar to GitHub.com Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> * Update empty commit webview styling to match design - Added SVG document icon above the message - Split message into title and subtitle with different styling - Title: "No changes to show." in regular foreground color - Subtitle: "This commit has no content." in muted description color - Adjusted spacing and font sizes to match GitHub.com design Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> * 💄 * clean up * Add icon path to empty commit webview panel - Set git-commit icon for the webview panel tab - Icon appears in both light and dark themes - Uses codicons/git-commit.svg from resources Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> * more clean up --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent 0023b44 commit 7bc0db6

File tree

5 files changed

+106
-4
lines changed

5 files changed

+106
-4
lines changed

src/@types/vscode.proposed.chatParticipantAdditions.d.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,14 @@ declare module 'vscode' {
167167
constructor(value: ChatResponseDiffEntry[], title: string, readOnly?: boolean);
168168
}
169169

170-
export type ExtendedChatResponsePart = ChatResponsePart | ChatResponseTextEditPart | ChatResponseNotebookEditPart | ChatResponseConfirmationPart | ChatResponseCodeCitationPart | ChatResponseReferencePart2 | ChatResponseMovePart | ChatResponseExtensionsPart | ChatResponsePullRequestPart | ChatPrepareToolInvocationPart | ChatToolInvocationPart | ChatResponseMultiDiffPart | ChatResponseThinkingProgressPart;
170+
export class ChatResponseExternalEditPart {
171+
uris: Uri[];
172+
callback: () => Thenable<unknown>;
173+
applied: Thenable<void>;
174+
constructor(uris: Uri[], callback: () => Thenable<unknown>);
175+
}
176+
177+
export type ExtendedChatResponsePart = ChatResponsePart | ChatResponseTextEditPart | ChatResponseNotebookEditPart | ChatResponseConfirmationPart | ChatResponseCodeCitationPart | ChatResponseReferencePart2 | ChatResponseMovePart | ChatResponseExtensionsPart | ChatResponsePullRequestPart | ChatPrepareToolInvocationPart | ChatToolInvocationPart | ChatResponseMultiDiffPart | ChatResponseThinkingProgressPart | ChatResponseExternalEditPart;
171178
export class ChatResponseWarningPart {
172179
value: MarkdownString;
173180
constructor(value: string | MarkdownString);
@@ -301,6 +308,14 @@ declare module 'vscode' {
301308

302309
notebookEdit(target: Uri, isDone: true): void;
303310

311+
/**
312+
* Makes an external edit to one or more resources. Changes to the
313+
* resources made within the `callback` and before it resolves will be
314+
* tracked as agent edits. This can be used to track edits made from
315+
* external tools that don't generate simple {@link textEdit textEdits}.
316+
*/
317+
externalEdit<T>(target: Uri | Uri[], callback: () => Thenable<T>): Thenable<T>;
318+
304319
markdownWithVulnerabilities(value: string | MarkdownString, vulnerabilities: ChatVulnerability[]): void;
305320
codeblockUri(uri: Uri, isEdit?: boolean): void;
306321
push(part: ChatResponsePart | ChatResponseTextEditPart | ChatResponseWarningPart | ChatResponseProgressPart2): void;

src/@types/vscode.proposed.chatParticipantPrivate.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ declare module 'vscode' {
8787
* Events for edited files in this session collected since the last request.
8888
*/
8989
readonly editedFileEvents?: ChatRequestEditedFileEvent[];
90+
91+
readonly isSubagent?: boolean;
9092
}
9193

9294
export enum ChatRequestEditedFileEventKind {

src/github/emptyCommitWebview.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
8+
/**
9+
* Opens a webview panel to display a message for an empty commit.
10+
* The message is centered and styled similar to GitHub.com.
11+
*/
12+
export function showEmptyCommitWebview(extensionUri: vscode.Uri, commitSha: string): void {
13+
const panel = vscode.window.createWebviewPanel(
14+
'emptyCommit',
15+
vscode.l10n.t('Commit {0}', commitSha.substring(0, 7)),
16+
vscode.ViewColumn.Active,
17+
{
18+
enableScripts: false,
19+
localResourceRoots: []
20+
}
21+
);
22+
23+
panel.iconPath = {
24+
light: vscode.Uri.joinPath(extensionUri, 'resources', 'icons', 'codicons', 'git-commit.svg'),
25+
dark: vscode.Uri.joinPath(extensionUri, 'resources', 'icons', 'codicons', 'git-commit.svg')
26+
};
27+
28+
panel.webview.html = getEmptyCommitHtml();
29+
}
30+
31+
function getEmptyCommitHtml(): string {
32+
return `<!DOCTYPE html>
33+
<html lang="en">
34+
<head>
35+
<meta charset="UTF-8">
36+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
37+
<title>Empty Commit</title>
38+
<style>
39+
body {
40+
margin: 0;
41+
padding: 0;
42+
height: 100vh;
43+
display: flex;
44+
align-items: center;
45+
justify-content: center;
46+
}
47+
.container {
48+
text-align: center;
49+
padding: 2rem;
50+
max-width: 600px;
51+
}
52+
.icon {
53+
margin-bottom: 1.5rem;
54+
opacity: 0.6;
55+
}
56+
.icon svg {
57+
width: 64px;
58+
height: 64px;
59+
fill: currentColor;
60+
}
61+
.title {
62+
font-size: 1.25rem;
63+
font-weight: 400;
64+
margin-bottom: 0.5rem;
65+
color: var(--vscode-foreground);
66+
}
67+
.subtitle {
68+
font-size: 0.95rem;
69+
color: var(--vscode-descriptionForeground);
70+
}
71+
</style>
72+
</head>
73+
<body>
74+
<div class="container">
75+
<div class="icon">
76+
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M9.99994 11.999H4.99994V10.999H9.99994V11.999Z"/><path d="M7.99994 5.99902H9.99994V6.99902H7.99994V9H6.99994V6.99902H4.99994V5.99902H6.99994V4H7.99994V5.99902Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M10.7099 1.28906L13.7099 4.28906L13.9999 4.99902V13.999L12.9999 14.999H2.99994L1.99994 13.999V1.99902L2.99994 0.999023H9.99994L10.7099 1.28906ZM2.99994 13.999H12.9999V4.99902L9.99994 1.99902H2.99994V13.999Z"/></svg>
77+
</div>
78+
<div class="title">No changes to show.</div>
79+
<div class="subtitle">This commit has no content.</div>
80+
</div>
81+
</body>
82+
</html>`;
83+
}

src/github/pullRequestModel.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as vscode from 'vscode';
1111
import { OctokitCommon } from './common';
1212
import { ConflictResolutionModel } from './conflictResolutionModel';
1313
import { CredentialStore } from './credentials';
14+
import { showEmptyCommitWebview } from './emptyCommitWebview';
1415
import { FolderRepositoryManager } from './folderRepositoryManager';
1516
import { GitHubRepository, GraphQLError, GraphQLErrorType } from './githubRepository';
1617
import {
@@ -1465,7 +1466,7 @@ export class PullRequestModel extends IssueModel<PullRequest> implements IPullRe
14651466
return vscode.commands.executeCommand('vscode.changes', vscode.l10n.t('Changes in Pull Request #{0}', pullRequestModel.number), args);
14661467
}
14671468

1468-
static async openCommitChanges(githubRepository: GitHubRepository, commitSha: string) {
1469+
static async openCommitChanges(extensionUri: vscode.Uri, githubRepository: GitHubRepository, commitSha: string) {
14691470
try {
14701471
const parentCommit = await githubRepository.getCommitParent(commitSha);
14711472
if (!parentCommit) {
@@ -1475,7 +1476,8 @@ export class PullRequestModel extends IssueModel<PullRequest> implements IPullRe
14751476

14761477
const changes = await githubRepository.compareCommits(parentCommit, commitSha);
14771478
if (!changes?.files || changes.files.length === 0) {
1478-
vscode.window.showInformationMessage(vscode.l10n.t('No changes found in commit {0}', commitSha.substring(0, 7)));
1479+
// Show a webview with the empty commit message instead of a notification
1480+
showEmptyCommitWebview(extensionUri, commitSha);
14791481
return;
14801482
}
14811483

src/github/pullRequestOverview.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel<PullRequestMode
554554
private async openCommitChanges(message: IRequestMessage<OpenCommitChangesArgs>): Promise<void> {
555555
try {
556556
const { commitSha } = message.args;
557-
await PullRequestModel.openCommitChanges(this._item.githubRepository, commitSha);
557+
await PullRequestModel.openCommitChanges(this._extensionUri, this._item.githubRepository, commitSha);
558558
this._replyMessage(message, {});
559559
} catch (error) {
560560
Logger.error(`Failed to open commit changes: ${formatError(error)}`, PullRequestOverviewPanel.ID);

0 commit comments

Comments
 (0)