From ad00951633e7acbd4175fad0e0fc7f67e11c1a3f Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Thu, 4 Aug 2022 17:25:09 -0400 Subject: [PATCH] Improves details commit picking Removes commit details webview (tab-based) --- package.json | 7 +- src/commands/git/log.ts | 31 ++-- src/commands/git/search.ts | 35 ++-- src/commands/gitCommands.actions.ts | 2 +- src/commands/searchCommits.ts | 4 +- src/commands/showView.ts | 3 + src/constants.ts | 2 +- src/container.ts | 23 +-- src/webviews/commitDetails/commitDetailsWebview.ts | 198 --------------------- .../commitDetails/commitDetailsWebviewView.ts | 11 +- src/webviews/commitDetails/protocol.ts | 2 +- 11 files changed, 60 insertions(+), 258 deletions(-) delete mode 100644 src/webviews/commitDetails/commitDetailsWebview.ts diff --git a/package.json b/package.json index fa4db16..371f067 100644 --- a/package.json +++ b/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" }, { diff --git a/src/commands/git/log.ts b/src/commands/git/log.ts index 8414f2b..83ed40a 100644 --- a/src/commands/git/log.ts +++ b/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 = 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>; + 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); diff --git a/src/commands/git/search.ts b/src/commands/git/search.ts index 3339f14..1d60be8 100644 --- a/src/commands/git/search.ts +++ b/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 { 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>; + 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); diff --git a/src/commands/gitCommands.actions.ts b/src/commands/gitCommands.actions.ts index ebc5046..205af2b 100644 --- a/src/commands/gitCommands.actions.ts +++ b/src/commands/gitCommands.actions.ts @@ -584,7 +584,7 @@ export namespace GitActions { } export async function openDetails(commit: GitCommit): Promise { - void (await Container.instance.commitDetailsWebviewView.show({ commit: commit })); + void (await Container.instance.commitDetailsView.show({ commit: commit })); } export async function openFiles(commit: GitCommit): Promise; diff --git a/src/commands/searchCommits.ts b/src/commands/searchCommits.ts index 7cdfc3c..66b679b 100644 --- a/src/commands/searchCommits.ts +++ b/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, }, })); } diff --git a/src/commands/showView.ts b/src/commands/showView.ts index 06ae257..cab5f48 100644 --- a/src/commands/showView.ts +++ b/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: diff --git a/src/constants.ts b/src/constants.ts index 74fe602..6d41021 100644 --- a/src/constants.ts +++ b/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', diff --git a/src/container.ts b/src/container.ts index 4c1213f..c6861c1 100644 --- a/src/container.ts +++ b/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; diff --git a/src/webviews/commitDetails/commitDetailsWebview.ts b/src/webviews/commitDetails/commitDetailsWebview.ts deleted file mode 100644 index 5616748..0000000 --- a/src/webviews/commitDetails/commitDetailsWebview.ts +++ /dev/null @@ -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 { - 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, - ): Promise { - 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> { - const pullRequest = selected != null ? await selected.getAssociatedPullRequest() : undefined; - console.log('CommitDetailsWebview pullRequest', pullRequest); - - const issues: Record[] = []; - 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 { - 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[] = []; - // 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 { - 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 { - 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, - }; -} diff --git a/src/webviews/commitDetails/commitDetailsWebviewView.ts b/src/webviews/commitDetails/commitDetailsWebviewView.ts index 56cd2a1..3fc8af1 100644 --- a/src/webviews/commitDetails/commitDetailsWebviewView.ts +++ b/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() { diff --git a/src/webviews/commitDetails/protocol.ts b/src/webviews/commitDetails/protocol.ts index 7d05b8f..b1e2f2f 100644 --- a/src/webviews/commitDetails/protocol.ts +++ b/src/webviews/commitDetails/protocol.ts @@ -25,7 +25,7 @@ export type State = { commits?: CommitSummary[]; } & Record; -export type ShowCommitDetailsPageCommandArgs = string[]; +export type ShowCommitDetailsViewCommandArgs = string[]; // COMMANDS export interface FileParams {