Browse Source

Splits commit sha & more action buttons

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
main
Eric Amodio 2 years ago
parent
commit
a9ef1fec67
7 changed files with 123 additions and 38 deletions
  1. +13
    -4
      src/webviews/apps/commitDetails/commitDetails.html
  2. +2
    -2
      src/webviews/apps/commitDetails/commitDetails.scss
  3. +32
    -13
      src/webviews/apps/commitDetails/commitDetails.ts
  4. +8
    -3
      src/webviews/apps/shared/components/commit/commit-stats.ts
  5. +27
    -8
      src/webviews/apps/shared/components/commit/file-change-item.ts
  6. +30
    -7
      src/webviews/commitDetails/commitDetailsWebviewView.ts
  7. +11
    -1
      src/webviews/commitDetails/protocol.ts

+ 13
- 4
src/webviews/apps/commitDetails/commitDetails.html View File

@ -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>

+ 2
- 2
src/webviews/apps/commitDetails/commitDetails.scss View File

@ -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;
@ -246,7 +246,7 @@ ul {
&__sha {
// padding-top: 0.2rem;
margin: 0 0.5rem;
margin: 0 0.5rem 0 0.25rem;
}
&__authors {

+ 32
- 13
src/webviews/apps/commitDetails/commitDetails.ts View File

@ -58,61 +58,80 @@ export class CommitDetailsApp extends App {
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) {

+ 8
- 3
src/webviews/apps/shared/components/commit/commit-stats.ts View File

@ -33,6 +33,11 @@ export class CommitStats extends LitElement {
.deleted {
color: var(--vscode-gitDecoration-deletedResourceForeground);
}
.label {
flex-basis: 100%;
text-align: center;
}
}
`;
@ -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
>
`;
}

+ 27
- 8
src/webviews/apps/shared/components/commit/file-change-item.ts View File

@ -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
@ -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);
}
* {
@ -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 {
@ -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;
@ -155,6 +165,14 @@ 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('/');
@ -162,7 +180,7 @@ export class FileChangeItem extends LitElement {
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>
@ -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"
@ -216,9 +234,9 @@ 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) {
@ -226,11 +244,12 @@ export class FileChangeItem extends LitElement {
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,

+ 30
- 7
src/webviews/commitDetails/commitDetailsWebviewView.ts View File

@ -1,4 +1,4 @@
import { Uri, window } from 'vscode';
import { env, Uri, window } from 'vscode';
import type {
DiffWithPreviousCommandArgs,
DiffWithWorkingCommandArgs,
@ -29,6 +29,7 @@ import {
PickCommitCommandType,
RichCommitDetails,
RichContentNotificationType,
SearchCommitCommandType,
State,
} from './protocol';
@ -78,8 +79,19 @@ export class CommitDetailsWebviewView extends WebviewViewBase {
});
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:
@ -87,6 +99,11 @@ export class CommitDetailsWebviewView extends WebviewViewBase {
this.showCommitPicker();
});
break;
case SearchCommitCommandType.method:
onIpc(SearchCommitCommandType, e, _params => {
this.showCommitSearch();
});
break;
case AutolinkSettingsCommandType.method:
onIpc(AutolinkSettingsCommandType, e, _params => {
this.showAutolinkSettings();
@ -104,13 +121,18 @@ export class CommitDetailsWebviewView extends WebviewViewBase {
}
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() {
@ -164,6 +186,7 @@ export class CommitDetailsWebviewView extends WebviewViewBase {
showOptions: {
preserveFocus: true,
preview: true,
...params.showOptions,
},
});
}

+ 11
- 1
src/webviews/commitDetails/protocol.ts View File

@ -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;
@ -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');

||||||
x
 
000:0
Loading…
Cancel
Save