129 lines
5.0 KiB
TypeScript
129 lines
5.0 KiB
TypeScript
import * as vscode from 'vscode';
|
|
import { GitService } from './GitService';
|
|
|
|
export class CommitPanel {
|
|
public static currentPanel: CommitPanel | undefined;
|
|
private readonly _panel: vscode.WebviewPanel;
|
|
private readonly _extensionPath: string;
|
|
private readonly _gitService: GitService;
|
|
private _disposables: vscode.Disposable[] = [];
|
|
|
|
public static show(extensionContext: vscode.ExtensionContext, gitService: GitService) {
|
|
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
|
|
|
|
if (CommitPanel.currentPanel) {
|
|
CommitPanel.currentPanel._panel.reveal(column);
|
|
return;
|
|
}
|
|
|
|
const panel = vscode.window.createWebviewPanel(
|
|
'commitPanel',
|
|
'Git Commits',
|
|
column || vscode.ViewColumn.One,
|
|
{
|
|
enableScripts: true
|
|
}
|
|
);
|
|
|
|
// 修正:传递正确的参数
|
|
CommitPanel.currentPanel = new CommitPanel(panel, extensionContext, gitService);
|
|
}
|
|
|
|
constructor(panel: vscode.WebviewPanel, extensionContext: vscode.ExtensionContext, gitService: GitService) {
|
|
this._panel = panel;
|
|
this._extensionPath = extensionContext.extensionPath;
|
|
this._gitService = gitService;
|
|
|
|
this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
|
|
this._panel.onDidChangeViewState(e => {
|
|
if (this._panel.visible) {
|
|
this._update();
|
|
}
|
|
}, null, this._disposables);
|
|
|
|
this._panel.webview.onDidReceiveMessage(message => {
|
|
switch (message.command) {
|
|
case 'filterCommits':
|
|
this._filterCommits(message.filter);
|
|
return;
|
|
case 'showCommitFiles':
|
|
this._showCommitFiles(message.commit);
|
|
return;
|
|
}
|
|
}, null, this._disposables);
|
|
|
|
this._update();
|
|
}
|
|
|
|
public dispose() {
|
|
CommitPanel.currentPanel = undefined;
|
|
|
|
this._panel.dispose();
|
|
|
|
while (this._disposables.length) {
|
|
const x = this._disposables.pop();
|
|
if (x) {
|
|
x.dispose();
|
|
}
|
|
}
|
|
}
|
|
|
|
private async _update() {
|
|
const commits = await this._gitService.getCommits();
|
|
this._panel.webview.html = this._getHtmlForWebview(commits);
|
|
}
|
|
|
|
private async _filterCommits(filter: string) {
|
|
const commits = await this._gitService.getCommits(filter);
|
|
this._panel.webview.postMessage({ command: 'updateCommits', commits });
|
|
}
|
|
|
|
private async _showCommitFiles(commit: string) {
|
|
const files = await this._gitService.getCommitFiles(commit);
|
|
this._panel.webview.postMessage({ command: 'showCommitFiles', files });
|
|
}
|
|
|
|
private _getHtmlForWebview(commits: any[]) {
|
|
const commitListHtml = commits.map(commit => `<li data-commit="${commit.hash}">${commit.message}</li>`).join('');
|
|
return `
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Git Commits</title>
|
|
</head>
|
|
<body>
|
|
<input type="text" id="filterInput" placeholder="Filter commits...">
|
|
<ul id="commitList">
|
|
${commitListHtml}
|
|
</ul>
|
|
<div id="commitFiles"></div>
|
|
<script>
|
|
const vscode = acquireVsCodeApi();
|
|
document.getElementById('filterInput').addEventListener('input', (e) => {
|
|
vscode.postMessage({ command: 'filterCommits', filter: e.target.value });
|
|
});
|
|
document.getElementById('commitList').addEventListener('click', (e) => {
|
|
if (e.target && e.target.nodeName === 'LI') {
|
|
vscode.postMessage({ command: 'showCommitFiles', commit: e.target.getAttribute('data-commit') });
|
|
}
|
|
});
|
|
window.addEventListener('message', event => {
|
|
const message = event.data;
|
|
switch (message.command) {
|
|
case 'updateCommits':
|
|
const commitList = document.getElementById('commitList');
|
|
commitList.innerHTML = message.commits.map(commit => \`<li data-commit=\"\${commit.hash}">\${commit.message}</li>\`).join('');
|
|
break;
|
|
case 'showCommitFiles':
|
|
const commitFiles = document.getElementById('commitFiles');
|
|
commitFiles.innerHTML = message.files.map(file => \`<p>\${file}</p>\`).join('');
|
|
break;
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
} |