Skip to content

Commit

Permalink
Splits commit sha & more action buttons
Browse files Browse the repository at this point in the history
Adds copy sha and alt+click to pick another commit for sha button
Adds keyboard up/down/enter/space support for the files list
Tweaks styling to match vscode & themes
  • Loading branch information
eamodio committed Aug 5, 2022
1 parent 27aa1e4 commit a9ef1fe
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 38 deletions.
17 changes: 13 additions & 4 deletions src/webviews/apps/commitDetails/commitDetails.html
Expand Up @@ -33,12 +33,21 @@
<a
class="commit-details__commit-action"
href="#"
data-action="commit-show-actions"
data-action="commit-actions-sha"
aria-label="Copy SHA
[⌥] Show Commit Actions"
[⌥] Pick Commit..."
title="Copy SHA
[⌥] Show Commit Actions"
><span class="commit-details__sha" data-region="shortsha"></span
[⌥] Pick Commit..."
>
<code-icon icon="git-commit"></code-icon>
<span class="commit-details__sha" data-region="shortsha"></span
></a>
<a
class="commit-details__commit-action"
href="#"
data-action="commit-actions-more"
aria-label="Show Commit Actions"
title="Show Commit Actions"
><code-icon icon="kebab-vertical"></code-icon
></a>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/webviews/apps/commitDetails/commitDetails.scss
Expand Up @@ -227,7 +227,7 @@ ul {
justify-content: center;
align-items: center;
// width: 20px;
height: 20px;
height: 21px;
border-radius: 0.25em;
color: inherit;
padding: 0.2rem;
Expand All @@ -246,7 +246,7 @@ ul {

&__sha {
// padding-top: 0.2rem;
margin: 0 0.5rem;
margin: 0 0.5rem 0 0.25rem;
}

&__authors {
Expand Down
45 changes: 32 additions & 13 deletions src/webviews/apps/commitDetails/commitDetails.ts
Expand Up @@ -58,61 +58,80 @@ export class CommitDetailsApp extends App<State> {
DOM.on<FileChangeItem, FileChangeItemEventDetail>('file-change-item', 'file-more-actions', e =>
this.onFileMoreActions(e.detail),
),
DOM.on('[data-action="commit-show-actions"]', 'click', e => this.onCommitMoreActions(e)),
DOM.on('[data-action="commit-actions-sha"]', 'click', e => this.onCommitShaActions(e)),
DOM.on('[data-action="commit-actions-more"]', 'click', e => this.onCommitMoreActions(e)),
DOM.on('[data-action="pick-commit"]', 'click', e => this.onPickCommit(e)),
DOM.on('[data-action="search-commit"]', 'click', e => this.onSearchCommit(e)),
DOM.on('[data-action="autolink-settings"]', 'click', e => this.onAutolinkSettings(e)),
DOM.on('file-change-item', 'keydown', (e, target: HTMLElement) => {
if (e.key === 'Enter' || e.key === ' ') {
(target as FileChangeItem).open(e.key === 'Enter' ? { preserveFocus: false } : undefined);
} else if (e.key === 'ArrowUp') {
const $previous: HTMLElement | null = target.parentElement?.previousElementSibling
?.firstElementChild as HTMLElement;
$previous?.focus();
} else if (e.key === 'ArrowDown') {
const $next: HTMLElement | null = target.parentElement?.nextElementSibling
?.firstElementChild as HTMLElement;
$next?.focus();
}
}),
];

return disposables;
}

onAutolinkSettings(e: MouseEvent) {
private onAutolinkSettings(e: MouseEvent) {
e.preventDefault();
this.sendCommand(AutolinkSettingsCommandType, undefined);
}

onSearchCommit(_e: MouseEvent) {
private onSearchCommit(_e: MouseEvent) {
this.sendCommand(SearchCommitCommandType, undefined);
}

onPickCommit(_e: MouseEvent) {
private onPickCommit(_e: MouseEvent) {
this.sendCommand(PickCommitCommandType, undefined);
}

onOpenFileOnRemote(e: FileChangeItemEventDetail) {
private onOpenFileOnRemote(e: FileChangeItemEventDetail) {
this.sendCommand(OpenFileOnRemoteCommandType, e);
}

onOpenFile(e: FileChangeItemEventDetail) {
private onOpenFile(e: FileChangeItemEventDetail) {
this.sendCommand(OpenFileCommandType, e);
}

onCompareFileWithWorking(e: FileChangeItemEventDetail) {
private onCompareFileWithWorking(e: FileChangeItemEventDetail) {
this.sendCommand(FileCompareWorkingCommandType, e);
}

onCompareFileWithPrevious(e: FileChangeItemEventDetail) {
private onCompareFileWithPrevious(e: FileChangeItemEventDetail) {
this.sendCommand(FileComparePreviousCommandType, e);
}

onFileMoreActions(e: FileChangeItemEventDetail) {
private onFileMoreActions(e: FileChangeItemEventDetail) {
this.sendCommand(FileMoreActionsCommandType, e);
}

onCommitMoreActions(e: MouseEvent) {
private onCommitMoreActions(e: MouseEvent) {
e.preventDefault();
if (this.state.selected === undefined) {
e.stopPropagation();
return;
}

if (e.altKey) {
this.sendCommand(CommitActionsCommandType, undefined);
this.sendCommand(CommitActionsCommandType, { action: 'more' });
}

private onCommitShaActions(e: MouseEvent) {
e.preventDefault();
if (this.state.selected === undefined) {
e.stopPropagation();
return;
}

void navigator.clipboard.writeText(this.state.selected.sha);
this.sendCommand(CommitActionsCommandType, { action: 'sha', alt: e.altKey });
}

protected override onMessageReceived(e: MessageEvent) {
Expand Down
11 changes: 8 additions & 3 deletions src/webviews/apps/shared/components/commit/commit-stats.ts
Expand Up @@ -33,6 +33,11 @@ export class CommitStats extends LitElement {
.deleted {
color: var(--vscode-gitDecoration-deletedResourceForeground);
}
.label {
flex-basis: 100%;
text-align: center;
}
}
`;

Expand All @@ -48,13 +53,13 @@ export class CommitStats extends LitElement {
override render() {
return html`
<span class="stat added" title="${this.added} added" aria-label="${this.added} added"
><code-icon icon="diff-added"></code-icon> ${this.added}</span
><code-icon icon="diff-added"></code-icon><span class="label">${this.added}</span></span
>
<span class="stat modified" title="${this.modified} modified" aria-label="${this.modified} modified"
><code-icon icon="diff-modified"></code-icon> ${this.modified}</span
><code-icon icon="diff-modified"></code-icon><span class="label">${this.modified}</span></span
>
<span class="stat deleted" title="${this.removed} removed" aria-label="${this.removed} removed"
><code-icon icon="diff-removed"></code-icon> ${this.removed}</span
><code-icon icon="diff-removed"></code-icon><span class="label">${this.removed}</span></span
>
`;
}
Expand Down
35 changes: 27 additions & 8 deletions src/webviews/apps/shared/components/commit/file-change-item.ts
@@ -1,10 +1,12 @@
import { css, html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import type { FileShowOptions } from '../../../../commitDetails/protocol';
import '../codicon';

export interface FileChangeItemEventDetail {
path: string;
repoPath: string;
showOptions?: FileShowOptions;
}

// TODO: use the model version
Expand Down Expand Up @@ -62,12 +64,15 @@ export class FileChangeItem extends LitElement {
color: var(--vscode-sideBar-foreground);
}
:host(:hover) {
color: var(--vscode-list-hoverForeground);
background-color: var(--vscode-list-hoverBackground);
}
:host(:focus-within) {
outline: 1px solid var(--vscode-list-focusOutline);
outline-offset: -1px;
color: var(--vscode-list-activeSelectionForeground);
background-color: var(--vscode-list-activeSelectionBackground);
}
* {
Expand Down Expand Up @@ -104,6 +109,11 @@ export class FileChangeItem extends LitElement {
user-select: none;
display: flex;
align-items: center;
color: var(--vscode-icon-foreground);
}
:host(:focus-within) .change-list__actions {
color: var(--vscode-list-activeSelectionIconForeground);
}
:host(:not(:hover):not(:focus-within)) .change-list__actions {
Expand All @@ -117,7 +127,7 @@ export class FileChangeItem extends LitElement {
width: 2rem;
height: 2rem;
border-radius: 0.25em;
color: var(--vscode-icon-foreground);
color: inherit;
padding: 2px;
vertical-align: text-bottom;
text-decoration: none;
Expand Down Expand Up @@ -155,14 +165,22 @@ export class FileChangeItem extends LitElement {
return html` <code-icon icon="${statusIcon}"></code-icon> `;
}

override focus(options?: FocusOptions | undefined): void {
this.shadowRoot?.getElementById('item')?.focus(options);
}

open(showOptions?: FileShowOptions): void {
this.onComparePrevious(undefined, showOptions);
}

override render() {
const statusName = this.status !== '' ? statusTextMap[this.status] : '';
const pathIndex = this.path.lastIndexOf('/');
const fileName = pathIndex > -1 ? this.path.substring(pathIndex + 1) : this.path;
const filePath = pathIndex > -1 ? this.path.substring(0, pathIndex) : '';

return html`
<a class="change-list__link" @click=${this.onComparePrevious} href="#">
<a id="item" class="change-list__link" @click=${this.onComparePrevious} href="#">
<span class="change-list__status" aria-label="${statusName}">${this.renderIcon()}</span
><span class="change-list__filename">${fileName}</span>
<small class="change-list__path">${filePath}</small>
Expand All @@ -179,8 +197,8 @@ export class FileChangeItem extends LitElement {
class="change-list__action"
@click=${this.onCompareWorking}
href="#"
title="Compare"
aria-label="Compare"
title="Open Changes with Working File"
aria-label="Open Changes with Working File"
><code-icon icon="git-compare"></code-icon></a
><a
class="change-list__action"
Expand Down Expand Up @@ -216,21 +234,22 @@ export class FileChangeItem extends LitElement {
this.fireEvent('file-compare-working');
}

private onComparePrevious(e: Event) {
e.preventDefault();
this.fireEvent('file-compare-previous');
private onComparePrevious(e?: Event, showOptions?: FileShowOptions) {
e?.preventDefault();
this.fireEvent('file-compare-previous', showOptions);
}

private onMoreActions(e: Event) {
e.preventDefault();
this.fireEvent('file-more-actions');
}

private fireEvent(eventName: string) {
private fireEvent(eventName: string, showOptions?: FileShowOptions) {
const event = new CustomEvent<FileChangeItemEventDetail>(eventName, {
detail: {
path: this.path,
repoPath: this.repoPath,
showOptions: showOptions,
},
bubbles: true,
composed: true,
Expand Down
37 changes: 30 additions & 7 deletions src/webviews/commitDetails/commitDetailsWebviewView.ts
@@ -1,4 +1,4 @@
import { Uri, window } from 'vscode';
import { env, Uri, window } from 'vscode';
import type {
DiffWithPreviousCommandArgs,
DiffWithWorkingCommandArgs,
Expand Down Expand Up @@ -29,6 +29,7 @@ import {
PickCommitCommandType,
RichCommitDetails,
RichContentNotificationType,
SearchCommitCommandType,
State,
} from './protocol';

Expand Down Expand Up @@ -78,15 +79,31 @@ export class CommitDetailsWebviewView extends WebviewViewBase<State> {
});
break;
case CommitActionsCommandType.method:
onIpc(CommitActionsCommandType, e, _params => {
this.showCommitActions();
onIpc(CommitActionsCommandType, e, params => {
switch (params.action) {
case 'more':
this.showCommitActions();
break;
case 'sha':
if (params.alt) {
this.showCommitPicker();
} else if (this.selectedCommit != null) {
void env.clipboard.writeText(this.selectedCommit.sha);
}
break;
}
});
break;
case PickCommitCommandType.method:
onIpc(PickCommitCommandType, e, _params => {
this.showCommitPicker();
});
break;
case SearchCommitCommandType.method:
onIpc(SearchCommitCommandType, e, _params => {
this.showCommitSearch();
});
break;
case AutolinkSettingsCommandType.method:
onIpc(AutolinkSettingsCommandType, e, _params => {
this.showAutolinkSettings();
Expand All @@ -104,13 +121,18 @@ export class CommitDetailsWebviewView extends WebviewViewBase<State> {
}

private showCommitSearch() {
void executeCommand(Commands.SearchCommits, {
showResultsInDetails: true,
});
void executeGitCommand({ command: 'search', state: { openPickInView: true } });
}

private showCommitPicker() {
void executeGitCommand({ command: 'log', state: { openPickInView: true } });
void executeGitCommand({
command: 'log',
state: {
reference: 'HEAD',
repo: this.selectedCommit?.repoPath,
openPickInView: true,
},
});
}

private showCommitActions() {
Expand Down Expand Up @@ -164,6 +186,7 @@ export class CommitDetailsWebviewView extends WebviewViewBase<State> {
showOptions: {
preserveFocus: true,
preview: true,
...params.showOptions,
},
});
}
Expand Down
12 changes: 11 additions & 1 deletion src/webviews/commitDetails/protocol.ts
@@ -1,6 +1,9 @@
import { TextDocumentShowOptions } from 'vscode';
import type { IssueOrPullRequest } from '../../git/models/issue';
import { IpcCommandType, IpcNotificationType } from '../protocol';

export type FileShowOptions = TextDocumentShowOptions;

export type CommitSummary = {
sha: string;
summary: string;
Expand Down Expand Up @@ -32,13 +35,20 @@ export type ShowCommitDetailsViewCommandArgs = string[];
export interface FileParams {
path: string;
repoPath: string;

showOptions?: TextDocumentShowOptions;
}

export interface ActionsParams {
action: 'sha' | 'more';
alt?: boolean;
}
export const OpenFileOnRemoteCommandType = new IpcCommandType<FileParams>('commit/file/openOnRemote');
export const OpenFileCommandType = new IpcCommandType<FileParams>('commit/file/open');
export const FileCompareWorkingCommandType = new IpcCommandType<FileParams>('commit/file/compareWorking');
export const FileComparePreviousCommandType = new IpcCommandType<FileParams>('commit/file/comparePrevious');
export const FileMoreActionsCommandType = new IpcCommandType<FileParams>('commit/file/moreActions');
export const CommitActionsCommandType = new IpcCommandType<undefined>('commit/moreActions');
export const CommitActionsCommandType = new IpcCommandType<ActionsParams>('commit/actions');
export const PickCommitCommandType = new IpcCommandType<undefined>('commit/pickCommit');
export const SearchCommitCommandType = new IpcCommandType<undefined>('commit/searchCommit');
export const AutolinkSettingsCommandType = new IpcCommandType<undefined>('commit/autolinkSettings');
Expand Down

0 comments on commit a9ef1fe

Please sign in to comment.