diff --git a/src/annotations/autolinks.ts b/src/annotations/autolinks.ts index 627b535..cffef14 100644 --- a/src/annotations/autolinks.ts +++ b/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?: | (( diff --git a/src/webviews/apps/commitDetails/commitDetails.html b/src/webviews/apps/commitDetails/commitDetails.html index 689060c..6f2541f 100644 --- a/src/webviews/apps/commitDetails/commitDetails.html +++ b/src/webviews/apps/commitDetails/commitDetails.html @@ -172,6 +172,13 @@
+
> { 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('[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*/ ` + + `; + }) + .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*/ ` > { .map( issue => /*html*/ ` (item: HierarchicalItem, level = 0): { level: num return flattened; } +function escapeHTMLString(value: string) { + return value.replace(/"/g, '"'); +} + new CommitDetailsApp(); diff --git a/src/webviews/apps/shared/components/rich/issue-pull-request.ts b/src/webviews/apps/shared/components/rich/issue-pull-request.ts index a2b4f9a..4e37796 100644 --- a/src/webviews/apps/shared/components/rich/issue-pull-request.ts +++ b/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``; + } + 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`

${this.name}

-

- ${this.key} ${this.status} - -

+

${this.key} ${this.status === '' ? this.status : nothing} ${this.renderDate()}

`; } } diff --git a/src/webviews/commitDetails/commitDetailsWebviewView.ts b/src/webviews/commitDetails/commitDetailsWebviewView.ts index 260348e..03aba50 100644 --- a/src/webviews/commitDetails/commitDetailsWebviewView.ts +++ b/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