浏览代码

adds non-rich autolinks to commit details

main
Keith Daulton 2 年前
父节点
当前提交
b3cf9c3853
共有 6 个文件被更改,包括 118 次插入16 次删除
  1. +20
    -0
      src/annotations/autolinks.ts
  2. +7
    -0
      src/webviews/apps/commitDetails/commitDetails.html
  3. +58
    -5
      src/webviews/apps/commitDetails/commitDetails.ts
  4. +21
    -11
      src/webviews/apps/shared/components/rich/issue-pull-request.ts
  5. +10
    -0
      src/webviews/commitDetails/commitDetailsWebviewView.ts
  6. +2
    -0
      src/webviews/commitDetails/protocol.ts

+ 20
- 0
src/annotations/autolinks.ts 查看文件

@ -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?:
| ((

+ 7
- 0
src/webviews/apps/commitDetails/commitDetails.html 查看文件

@ -172,6 +172,13 @@
</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"
data-region="pull-request"

+ 58
- 5
src/webviews/apps/commitDetails/commitDetails.ts 查看文件

@ -572,11 +572,31 @@ export class CommitDetailsApp extends App> {
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');
@ -585,8 +605,37 @@ export class CommitDetailsApp extends App> {
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) {
@ -596,7 +645,7 @@ export class CommitDetailsApp extends App> {
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}"
@ -620,7 +669,7 @@ export class CommitDetailsApp extends App> {
.map(
issue => /*html*/ `
<issue-pull-request
name="${issue.title}"
name="${escapeHTMLString(issue.title)}"
url="${issue.url}"
key="${issue.id}"
status="${issue.closed ? 'closed' : 'opened'}"
@ -671,4 +720,8 @@ function flattenHeirarchy(item: HierarchicalItem, level = 0): { level: num
return flattened;
}
function escapeHTMLString(value: string) {
return value.replace(/"/g, '&quot;');
}
new CommitDetailsApp();

+ 21
- 11
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';
@ -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
- 0
src/webviews/commitDetails/commitDetailsWebviewView.ts 查看文件

@ -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';
@ -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';
@ -715,6 +717,13 @@ export class CommitDetailsWebviewView extends WebviewViewBase
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,
@ -740,6 +749,7 @@ export class CommitDetailsWebviewView extends WebviewViewBase
};
}),
stats: commit.stats,
autolinks: autolinks ? Array.from(autolinks.values()).map(serializeAutolink) : undefined,
};
}

+ 2
- 0
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';
@ -22,6 +23,7 @@ export type CommitSummary = {
};
export type CommitDetails = CommitSummary & {
autolinks?: Autolink[];
files?: (GitFileChangeShape & { icon: { dark: string; light: string } })[];
stats?: GitCommitStats;
};

正在加载...
取消
保存