Просмотр исходного кода

Improves details commit picking

Removes commit details webview (tab-based)
main
Eric Amodio 2 лет назад
Родитель
Сommit
ad00951633
11 измененных файлов: 60 добавлений и 258 удалений
  1. +3
    -4
      package.json
  2. +20
    -11
      src/commands/git/log.ts
  3. +18
    -17
      src/commands/git/search.ts
  4. +1
    -1
      src/commands/gitCommands.actions.ts
  5. +2
    -2
      src/commands/searchCommits.ts
  6. +3
    -0
      src/commands/showView.ts
  7. +1
    -1
      src/constants.ts
  8. +6
    -17
      src/container.ts
  9. +0
    -198
      src/webviews/commitDetails/commitDetailsWebview.ts
  10. +5
    -6
      src/webviews/commitDetails/commitDetailsWebviewView.ts
  11. +1
    -1
      src/webviews/commitDetails/protocol.ts

+ 3
- 4
package.json Просмотреть файл

@ -66,7 +66,6 @@
"onView:gitlens.views.commitDetails",
"onWebviewPanel:gitlens.welcome",
"onWebviewPanel:gitlens.settings",
"onWebviewPanel:gitlens.commitDetails",
"onCommand:gitlens.plus.learn",
"onCommand:gitlens.plus.loginOrSignUp",
"onCommand:gitlens.plus.logout",
@ -101,7 +100,7 @@
"onCommand:gitlens.showStashesView",
"onCommand:gitlens.showTagsView",
"onCommand:gitlens.showTimelineView",
"onCommand:gitlens.showCommitDetailsPage",
"onCommand:gitlens.showCommitDetailsView",
"onCommand:gitlens.showWorktreesView",
"onCommand:gitlens.compareWith",
"onCommand:gitlens.compareHeadWith",
@ -3935,7 +3934,7 @@
"category": "GitLens"
},
{
"command": "gitlens.showCommitDetailsPage",
"command": "gitlens.showCommitDetailsView",
"title": "Show Commit Details View",
"category": "GitLens"
},
@ -6239,7 +6238,7 @@
"when": "gitlens:enabled"
},
{
"command": "gitlens.showCommitDetailsPage",
"command": "gitlens.showCommitDetailsView",
"when": "gitlens:enabled"
},
{

+ 20
- 11
src/commands/git/log.ts Просмотреть файл

@ -4,6 +4,7 @@ import { GitCommit, GitLog, GitReference, Repository } from '../../git/models';
import { formatPath } from '../../system/formatPath';
import { pad } from '../../system/string';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { GitActions } from '../gitCommands.actions';
import { getSteps } from '../gitCommands.utils';
import {
PartialStepState,
@ -28,6 +29,7 @@ interface State {
reference: GitReference | 'HEAD';
fileName?: string;
openPickInView?: boolean;
}
type RepositoryStepState<T extends State = State> = SomeNonNullable<
@ -191,18 +193,25 @@ export class LogGitCommand extends QuickCommand {
state.reference = await this.container.git.getCommit(state.repo.path, state.reference.ref);
}
const result = yield* getSteps(
this.container,
{
command: 'show',
state: {
repo: state.repo,
reference: state.reference,
fileName: state.fileName,
let result: StepResult<ReturnType<typeof getSteps>>;
if (state.openPickInView) {
void GitActions.Commit.openDetails(state.reference as GitCommit);
result = StepResult.Break;
} else {
result = yield* getSteps(
this.container,
{
command: 'show',
state: {
repo: state.repo,
reference: state.reference,
fileName: state.fileName,
},
},
},
this.pickedVia,
);
this.pickedVia,
);
}
state.counter--;
if (result === StepResult.Break) {
QuickCommand.endSteps(state);

+ 18
- 17
src/commands/git/search.ts Просмотреть файл

@ -8,6 +8,7 @@ import { ActionQuickPickItem, QuickPickItemOfT } from '../../quickpicks/items/co
import { pluralize } from '../../system/string';
import { SearchResultsNode } from '../../views/nodes';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { GitActions } from '../gitCommands.actions';
import { getSteps } from '../gitCommands.utils';
import {
appendReposToTitle,
@ -35,8 +36,8 @@ interface Context {
interface State extends Required<SearchPattern> {
repo: string | Repository;
openPickInView?: boolean;
showResultsInSideBar: boolean | SearchResultsNode;
showResultsInDetails?: boolean;
}
export interface SearchGitCommandArgs {
@ -243,24 +244,24 @@ export class SearchGitCommand extends QuickCommand {
context.commit = result;
}
if (state.showResultsInDetails) {
void this.container.commitDetailsWebviewView.show({
commit: context.commit,
});
break;
let result: StepResult<ReturnType<typeof getSteps>>;
if (state.openPickInView) {
void GitActions.Commit.openDetails(context.commit);
result = StepResult.Break;
} else {
result = yield* getSteps(
this.container,
{
command: 'show',
state: {
repo: state.repo,
reference: context.commit,
},
},
this.pickedVia,
);
}
const result = yield* getSteps(
this.container,
{
command: 'show',
state: {
repo: state.repo,
reference: context.commit,
},
},
this.pickedVia,
);
state.counter--;
if (result === StepResult.Break) {
QuickCommand.endSteps(state);

+ 1
- 1
src/commands/gitCommands.actions.ts Просмотреть файл

@ -584,7 +584,7 @@ export namespace GitActions {
}
export async function openDetails(commit: GitCommit): Promise<void> {
void (await Container.instance.commitDetailsWebviewView.show({ commit: commit }));
void (await Container.instance.commitDetailsView.show({ commit: commit }));
}
export async function openFiles(commit: GitCommit): Promise<void>;

+ 2
- 2
src/commands/searchCommits.ts Просмотреть файл

@ -13,7 +13,7 @@ export interface SearchCommitsCommandArgs {
prefillOnly?: boolean;
showResultsInDetails?: boolean;
openPickInView?: boolean;
showResultsInSideBar?: boolean;
}
@ -54,7 +54,7 @@ export class SearchCommitsCommand extends Command {
...args?.search,
showResultsInSideBar:
configuration.get('gitCommands.search.showResultsInSideBar') ?? args?.showResultsInSideBar,
showResultsInDetails: args?.showResultsInDetails ?? false,
openPickInView: args?.openPickInView ?? false,
},
}));
}

+ 3
- 0
src/commands/showView.ts Просмотреть файл

@ -8,6 +8,7 @@ export class ShowViewCommand extends Command {
constructor(private readonly container: Container) {
super([
Commands.ShowBranchesView,
Commands.ShowCommitDetailsView,
Commands.ShowCommitsView,
Commands.ShowContributorsView,
Commands.ShowFileHistoryView,
@ -31,6 +32,8 @@ export class ShowViewCommand extends Command {
switch (command) {
case Commands.ShowBranchesView:
return this.container.branchesView.show();
case Commands.ShowCommitDetailsView:
return this.container.commitDetailsView.show();
case Commands.ShowCommitsView:
return this.container.commitsView.show();
case Commands.ShowContributorsView:

+ 1
- 1
src/constants.ts Просмотреть файл

@ -199,7 +199,7 @@ export const enum Commands {
ShowTagsView = 'gitlens.showTagsView',
ShowWorktreesView = 'gitlens.showWorktreesView',
RefreshTimelinePage = 'gitlens.refreshTimelinePage',
ShowCommitDetailsPage = 'gitlens.showCommitDetailsPage',
ShowCommitDetailsView = 'gitlens.showCommitDetailsView',
ShowTimelinePage = 'gitlens.showTimelinePage',
ShowTimelineView = 'gitlens.showTimelineView',
ShowWelcomePage = 'gitlens.showWelcomePage',

+ 6
- 17
src/container.ts Просмотреть файл

@ -50,7 +50,6 @@ import { ViewCommands } from './views/viewCommands';
import { ViewFileDecorationProvider } from './views/viewDecorationProvider';
import { WorktreesView } from './views/worktreesView';
import { VslsController } from './vsls/vsls';
import { CommitDetailsWebview } from './webviews/commitDetails/commitDetailsWebview';
import { CommitDetailsWebviewView } from './webviews/commitDetails/commitDetailsWebviewView';
import { HomeWebviewView } from './webviews/home/homeWebviewView';
import { RebaseEditorProvider } from './webviews/rebase/rebaseEditor';
@ -177,12 +176,11 @@ export class Container {
context.subscriptions.push((this._timelineWebview = new TimelineWebview(this)));
context.subscriptions.push((this._welcomeWebview = new WelcomeWebview(this)));
context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider(this)));
context.subscriptions.push((this._commitDetailsWebview = new CommitDetailsWebview(this)));
context.subscriptions.push((this._commitDetailsWebviewView = new CommitDetailsWebviewView(this)));
context.subscriptions.push(new ViewFileDecorationProvider());
context.subscriptions.push((this._repositoriesView = new RepositoriesView(this)));
context.subscriptions.push((this._commitDetailsView = new CommitDetailsWebviewView(this)));
context.subscriptions.push((this._commitsView = new CommitsView(this)));
context.subscriptions.push((this._fileHistoryView = new FileHistoryView(this)));
context.subscriptions.push((this._lineHistoryView = new LineHistoryView(this)));
@ -290,22 +288,13 @@ export class Container {
return this._commitsView;
}
private _commitDetailsWebview: CommitDetailsWebview | undefined;
get commitDetailsWebview() {
if (this._commitDetailsWebview == null) {
this._context.subscriptions.push((this._commitDetailsWebview = new CommitDetailsWebview(this)));
private _commitDetailsView: CommitDetailsWebviewView | undefined;
get commitDetailsView() {
if (this._commitDetailsView == null) {
this._context.subscriptions.push((this._commitDetailsView = new CommitDetailsWebviewView(this)));
}
return this._commitDetailsWebview;
}
private _commitDetailsWebviewView: CommitDetailsWebviewView | undefined;
get commitDetailsWebviewView() {
if (this._commitDetailsWebviewView == null) {
this._context.subscriptions.push((this._commitDetailsWebviewView = new CommitDetailsWebviewView(this)));
}
return this._commitDetailsWebviewView;
return this._commitDetailsView;
}
private readonly _context: ExtensionContext;

+ 0
- 198
src/webviews/commitDetails/commitDetailsWebview.ts Просмотреть файл

@ -1,198 +0,0 @@
import { ProgressLocation, window } from 'vscode';
import { Commands } from '../../constants';
import type { Container } from '../../container';
import { GitCommit, GitRemote, IssueOrPullRequest } from '../../git/models';
import { RichRemoteProvider } from '../../git/remotes/provider';
import { debug } from '../../system/decorators/log';
import { WebviewBase } from '../webviewBase';
import type { CommitDetails, CommitSummary, ShowCommitDetailsPageCommandArgs, State } from './protocol';
export class CommitDetailsWebview extends WebviewBase<State> {
private shaList: string[] = [
'7224b547bbaa3a643e89ceb515dfb7cbad83aa26',
'f55b2ad418a05a51c381c667e5e87d0435883cfc',
];
private selectedSha: string | undefined = 'f55b2ad418a05a51c381c667e5e87d0435883cfc';
constructor(container: Container) {
super(
container,
'gitlens.commitDetails',
'commitDetails.html',
'images/gitlens-icon.png',
'Commit Details',
Commands.ShowCommitDetailsPage,
);
}
private updateShaList(refs?: string[]) {
let refsList;
if (refs?.length && refs.length > 0) {
refsList = refs;
} else {
// TODO: replace with quick pick for a commit
refsList = ['7224b547bbaa3a643e89ceb515dfb7cbad83aa26', 'f55b2ad418a05a51c381c667e5e87d0435883cfc'];
}
this.shaList = refsList;
if (this.selectedSha && !this.shaList.includes(this.selectedSha)) {
// TODO: maybe make a quick pick for the list of commits?
this.selectedSha = this.shaList[0];
}
}
protected override onShowCommand(refs?: ShowCommitDetailsPageCommandArgs): void {
// TODO: get args from command
this.updateShaList(refs);
super.onShowCommand();
}
private async getLinkedIssuesAndPullRequests(
message: string,
remote: GitRemote<RichRemoteProvider>,
): Promise<IssueOrPullRequest[] | undefined> {
try {
const issueSearch = await this.container.autolinks.getLinkedIssuesAndPullRequests(message, remote);
console.log('CommitDetailsWebview getLinkedIssuesAndPullRequests', issueSearch);
if (issueSearch != null) {
const filteredIssues = Array.from(issueSearch.values()).filter(
value => value != null,
) as IssueOrPullRequest[];
return filteredIssues;
}
return undefined;
} catch (e) {
console.error(e);
return undefined;
}
}
private async getRichContent(selected: GitCommit): Promise<Record<string, any>> {
const pullRequest = selected != null ? await selected.getAssociatedPullRequest() : undefined;
console.log('CommitDetailsWebview pullRequest', pullRequest);
const issues: Record<string, any>[] = [];
let formattedMessage;
if (selected?.message !== undefined && typeof selected.message === 'string') {
const remote = await this.container.git.getBestRemoteWithRichProvider(selected.repoPath);
console.log('CommitDetailsWebview remote', remote);
if (remote != null) {
formattedMessage = this.container.autolinks.linkify(selected.message, true, [remote]);
const issueSearch = await this.getLinkedIssuesAndPullRequests(selected.message, remote);
console.log('CommitDetailsWebview issueSearch', issueSearch);
if (issueSearch !== undefined) {
issues.push(...issueSearch);
}
}
}
return {
formattedMessage: formattedMessage,
pullRequest: pullRequest,
issues: issues?.length ? issues : undefined,
};
}
@debug({ args: false })
protected async getState(init = false): Promise<State> {
const repo = this.container.git.openRepositories?.[0];
console.log('CommitDetailsWebview repo', repo);
if (repo === undefined) {
return {
commits: [],
};
}
const commitPromises = this.shaList.map(sha => repo.getCommit(sha));
const results = await Promise.all(commitPromises);
console.log('CommitDetailsWebview results', results);
const commits = results.filter(commit => commit !== undefined) as GitCommit[];
const selected = commits.find(commit => commit.sha === this.selectedSha);
console.log('CommitDetailsWebview selected', selected);
// const pullRequest = selected != null ? await selected.getAssociatedPullRequest() : undefined;
// console.log('CommitDetailsWebview pullRequest', pullRequest);
// const issues: Record<string, any>[] = [];
// let formattedMessage;
// if (selected?.message !== undefined && typeof selected.message === 'string') {
// const remote = await this.container.git.getBestRemoteWithRichProvider(selected.repoPath);
// console.log('CommitDetailsWebview remote', remote);
// if (remote != null) {
// formattedMessage = this.container.autolinks.linkify(selected.message, true, [remote]);
// const issueSearch = await this.getLinkedIssuesAndPullRequests(selected.message, remote);
// console.log('CommitDetailsWebview issueSearch', issueSearch);
// if (issueSearch !== undefined) {
// issues.push(...issueSearch);
// }
// }
// }
const richContent = !init && selected != null ? await this.getRichContent(selected) : undefined;
let formattedCommit;
if (selected !== undefined) {
formattedCommit = await getDetailsModel(selected, richContent?.formattedMessage);
}
const commitChoices = await Promise.all(commits.map(async commit => summaryModel(commit)));
return {
// TODO: keep state of the selected commit
commits: commitChoices,
selected: formattedCommit,
pullRequest: richContent?.pullRequest,
issues: richContent?.issues,
};
}
protected override async includeBootstrap() {
return window.withProgress({ location: ProgressLocation.Window, title: 'Loading webview...' }, () =>
this.getState(true),
);
}
}
async function summaryModel(commit: GitCommit): Promise<CommitSummary> {
return {
sha: commit.sha,
shortSha: commit.shortSha,
summary: commit.summary,
message: commit.message,
author: commit.author,
avatar: (await commit.getAvatarUri())?.toString(true),
};
}
async function getDetailsModel(commit: GitCommit, formattedMessage?: string): Promise<CommitDetails | undefined> {
if (commit === undefined) {
return;
}
const authorAvatar = await commit.author?.getAvatarUri(commit);
const committerAvatar = await commit.committer?.getAvatarUri(commit);
return {
sha: commit.sha,
shortSha: commit.shortSha,
summary: commit.summary,
message: formattedMessage ?? commit.message,
author: { ...commit.author, avatar: authorAvatar?.toString(true) },
committer: { ...commit.committer, avatar: committerAvatar?.toString(true) },
files: commit.files?.map(({ repoPath, path, status }) => ({ repoPath: repoPath, path: path, status: status })),
stats: commit.stats,
};
}

+ 5
- 6
src/webviews/commitDetails/commitDetailsWebviewView.ts Просмотреть файл

@ -4,6 +4,7 @@ import type {
DiffWithWorkingCommandArgs,
OpenFileOnRemoteCommandArgs,
} from '../../commands';
import { executeGitCommand } from '../../commands/gitCommands.actions';
import { Commands, CoreCommands } from '../../constants';
import type { Container } from '../../container';
import { GitUri } from '../../git/gitUri';
@ -83,11 +84,11 @@ export class CommitDetailsWebviewView extends WebviewViewBase {
break;
case PickCommitCommandType.method:
onIpc(PickCommitCommandType, e, _params => {
this.showCommitSearch();
this.showCommitPicker();
});
break;
case AutolinkSettingsCommandType.method:
onIpc(AutolinkSettingsCommandType, e, params => {
onIpc(AutolinkSettingsCommandType, e, _params => {
this.showAutolinkSettings();
});
break;
@ -102,10 +103,8 @@ export class CommitDetailsWebviewView extends WebviewViewBase {
void executeCommand(Commands.ShowSettingsPageAndJumpToAutolinks);
}
private showCommitSearch() {
void executeCommand(Commands.SearchCommits, {
showResultsInDetails: true,
});
private showCommitPicker() {
void executeGitCommand({ command: 'log', state: { openPickInView: true } });
}
private showCommitActions() {

+ 1
- 1
src/webviews/commitDetails/protocol.ts Просмотреть файл

@ -25,7 +25,7 @@ export type State = {
commits?: CommitSummary[];
} & Record<string, any>;
export type ShowCommitDetailsPageCommandArgs = string[];
export type ShowCommitDetailsViewCommandArgs = string[];
// COMMANDS
export interface FileParams {

Загрузка…
Отмена
Сохранить