Skip to content

Commit

Permalink
adds non-rich autolinks to commit details
Browse files Browse the repository at this point in the history
  • Loading branch information
d13 committed Nov 16, 2022
1 parent 307c7b6 commit b3cf9c3
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 16 deletions.
20 changes: 20 additions & 0 deletions src/annotations/autolinks.ts
Expand Up @@ -31,6 +31,26 @@ export interface Autolink {
description?: string;
}

export function serializeAutolink(value: Autolink): Autolink {
const serialized: Autolink = {
provider: value.provider
? {
id: value.provider.id,
name: value.provider.name,
domain: value.provider.domain,
icon: value.provider.icon,
}
: undefined,
id: value.id,
prefix: value.prefix,
title: value.title,
url: value.url,
type: value.type,
description: value.description,
};
return serialized;
}

export interface CacheableAutolinkReference extends AutolinkReference {
tokenize?:
| ((
Expand Down
7 changes: 7 additions & 0 deletions src/webviews/apps/commitDetails/commitDetails.html
Expand Up @@ -171,6 +171,13 @@ <h2>Move into Secondary Side Bar</h2>
</p>
</div>
<div class="commit-details__rich" data-region="autolinks">
<section
class="commit-details__autolinks"
aria-label="Custom Autolinks"
data-region="custom-autolinks"
>
<skeleton-loader lines="2"></skeleton-loader>
</section>
<section
class="commit-details__pull-request"
aria-label="Pull request"
Expand Down
63 changes: 58 additions & 5 deletions src/webviews/apps/commitDetails/commitDetails.ts
Expand Up @@ -572,11 +572,31 @@ export class CommitDetailsApp extends App<Serialized<State>> {

const $info = $el.querySelector('[data-region="rich-info"]');
const $autolinks = $el.querySelector('[data-region="autolinks"]');
if (state.pullRequest != null || state.autolinkedIssues?.length) {
const autolinkedIssuesCount = state.autolinkedIssues?.length ?? 0;
let autolinksCount = state.selected.autolinks?.length ?? 0;
let count = autolinksCount;
if (state.pullRequest != null || autolinkedIssuesCount || autolinksCount) {
let dedupedAutolinks = state.selected.autolinks;
if (dedupedAutolinks?.length && autolinkedIssuesCount) {
dedupedAutolinks = dedupedAutolinks.filter(
autolink => !state.autolinkedIssues?.some(issue => issue.url === autolink.url),
);
}

$autolinks?.setAttribute('aria-hidden', 'false');
$info?.setAttribute('aria-hidden', 'true');
this.renderAutolinks({
...state,
selected: {
...state.selected,
autolinks: dedupedAutolinks,
},
});
this.renderPullRequest(state);
this.renderIssues(state);

autolinksCount = dedupedAutolinks?.length ?? 0;
count = (state.pullRequest != null ? 1 : 0) + autolinkedIssuesCount + autolinksCount;
} else {
$autolinks?.setAttribute('aria-hidden', 'true');
$info?.setAttribute('aria-hidden', 'false');
Expand All @@ -585,8 +605,37 @@ export class CommitDetailsApp extends App<Serialized<State>> {
const $count = $el.querySelector('[data-region="autolink-count"]');
if ($count == null) return;

const count = (state.pullRequest != null ? 1 : 0) + (state.autolinkedIssues?.length ?? 0);
$count.innerHTML = state.includeRichContent ? `${count} found` : '…';
$count.innerHTML = `${state.includeRichContent || autolinksCount ? `${count} found ` : ''}${
state.includeRichContent ? '' : '…'
}`;
}

renderAutolinks(state: CommitState) {
const $el = document.querySelector<HTMLElement>('[data-region="custom-autolinks"]');
if ($el == null) return;

if (state.selected.autolinks?.length) {
$el.innerHTML = state.selected.autolinks
.map(autolink => {
let name = autolink.description ?? autolink.title;
if (name === undefined) {
name = `Custom Autolink ${autolink.prefix}${autolink.id}`;
}
return /*html*/ `
<issue-pull-request
name="${name ? escapeHTMLString(name) : ''}"
url="${autolink.url}"
key="${autolink.prefix}${autolink.id}"
status=""
></issue-pull-request>
`;
})
.join('');
$el.setAttribute('aria-hidden', 'false');
} else {
$el.innerHTML = '';
$el.setAttribute('aria-hidden', 'true');
}
}

renderPullRequest(state: CommitState) {
Expand All @@ -596,7 +645,7 @@ export class CommitDetailsApp extends App<Serialized<State>> {
if (state.pullRequest != null) {
$el.innerHTML = /*html*/ `
<issue-pull-request
name="${state.pullRequest.title}"
name="${escapeHTMLString(state.pullRequest.title)}"
url="${state.pullRequest.url}"
key="#${state.pullRequest.id}"
status="${state.pullRequest.state}"
Expand All @@ -620,7 +669,7 @@ export class CommitDetailsApp extends App<Serialized<State>> {
.map(
issue => /*html*/ `
<issue-pull-request
name="${issue.title}"
name="${escapeHTMLString(issue.title)}"
url="${issue.url}"
key="${issue.id}"
status="${issue.closed ? 'closed' : 'opened'}"
Expand Down Expand Up @@ -671,4 +720,8 @@ function flattenHeirarchy<T>(item: HierarchicalItem<T>, level = 0): { level: num
return flattened;
}

function escapeHTMLString(value: string) {
return value.replace(/"/g, '&quot;');
}

new CommitDetailsApp();
32 changes: 21 additions & 11 deletions src/webviews/apps/shared/components/rich/issue-pull-request.ts
@@ -1,4 +1,4 @@
import { css, html, LitElement } from 'lit';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import '../formatted-date';
import '../code-icon';
Expand Down Expand Up @@ -55,23 +55,33 @@ export class IssuePullRequest extends LitElement {
@property()
key = '#1999';

renderDate() {
if (this.date === '') {
return nothing;
}
return html`<formatted-date date="${this.date}"></formatted-date>`;
}

override render() {
const icon =
this.status.toLowerCase() === 'merged'
? 'git-merge'
: this.status.toLowerCase() === 'closed'
? 'pass'
: 'issues';
let icon = 'issues';
switch (this.status.toLowerCase()) {
case '':
icon = 'link';
break;
case 'merged':
icon = 'git-merge';
break;
case 'closed':
icon = 'pass';
break;
}

return html`
<span class="icon"><code-icon icon=${icon}></code-icon></span>
<p class="title">
<a href="${this.url}">${this.name}</a>
</p>
<p class="date">
${this.key} ${this.status}
<formatted-date date="${this.date}"></formatted-date>
</p>
<p class="date">${this.key} ${this.status === '' ? this.status : nothing} ${this.renderDate()}</p>
`;
}
}
10 changes: 10 additions & 0 deletions src/webviews/commitDetails/commitDetailsWebviewView.ts
Expand Up @@ -5,6 +5,7 @@ import type {
TreeViewVisibilityChangeEvent,
} from 'vscode';
import { CancellationTokenSource, Disposable, Uri, window } from 'vscode';
import { serializeAutolink } from '../../annotations/autolinks';
import type { CopyShaToClipboardCommandArgs } from '../../commands';
import { executeGitCommand, GitActions } from '../../commands/gitCommands.actions';
import { configuration } from '../../configuration';
Expand All @@ -30,6 +31,7 @@ import type { DateTimeFormat } from '../../system/date';
import { debug, getLogScope } from '../../system/decorators/log';
import type { Deferrable } from '../../system/function';
import { debounce } from '../../system/function';
import { union } from '../../system/iterable';
import type { PromiseCancelledError } from '../../system/promise';
import { getSettledValue } from '../../system/promise';
import type { Serialized } from '../../system/serialize';
Expand Down Expand Up @@ -715,6 +717,13 @@ export class CommitDetailsWebviewView extends WebviewViewBase<State, Serialized<
formattedMessage = this.getFormattedMessage(commit, remote);
}

let autolinks;
if (commit.message != null) {
const customAutolinks = this.container.autolinks.getAutolinks(commit.message);
const providerAutolinks = this.container.autolinks.getAutolinks(commit.message, remote);
autolinks = new Map(union(customAutolinks, providerAutolinks));
}

return {
sha: commit.sha,
shortSha: commit.shortSha,
Expand All @@ -740,6 +749,7 @@ export class CommitDetailsWebviewView extends WebviewViewBase<State, Serialized<
};
}),
stats: commit.stats,
autolinks: autolinks ? Array.from(autolinks.values()).map(serializeAutolink) : undefined,
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/webviews/commitDetails/protocol.ts
@@ -1,4 +1,5 @@
import type { TextDocumentShowOptions } from 'vscode';
import type { Autolink } from '../../annotations/autolinks';
import type { Config } from '../../config';
import type { GitCommitIdentityShape, GitCommitStats } from '../../git/models/commit';
import type { GitFileChangeShape } from '../../git/models/file';
Expand All @@ -22,6 +23,7 @@ export type CommitSummary = {
};

export type CommitDetails = CommitSummary & {
autolinks?: Autolink[];
files?: (GitFileChangeShape & { icon: { dark: string; light: string } })[];
stats?: GitCommitStats;
};
Expand Down

0 comments on commit b3cf9c3

Please sign in to comment.