gitcommitfilter/src/CommitPanel.ts

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>`;
}
}