From 0bccf5608baceb8fc7db0159f907e1d6f3296ad2 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Sun, 19 Jan 2025 21:53:03 +0100 Subject: [PATCH] Git - add avatar to timeline hover (#238248) --- extensions/git/src/timelineProvider.ts | 31 ++++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/extensions/git/src/timelineProvider.ts b/extensions/git/src/timelineProvider.ts index 20daaebe263..f29264e4078 100644 --- a/extensions/git/src/timelineProvider.ts +++ b/extensions/git/src/timelineProvider.ts @@ -12,7 +12,10 @@ import { CommandCenter } from './commands'; import { OperationKind, OperationResult } from './operation'; import { getCommitShortHash } from './util'; import { CommitShortStat } from './git'; -import { provideSourceControlHistoryItemHoverCommands, provideSourceControlHistoryItemMessageLinks } from './historyItemDetailsProvider'; +import { provideSourceControlHistoryItemAvatar, provideSourceControlHistoryItemHoverCommands, provideSourceControlHistoryItemMessageLinks } from './historyItemDetailsProvider'; +import { AvatarQuery, AvatarQueryCommit } from './api/git'; + +const AVATAR_SIZE = 20; export class GitTimelineItem extends TimelineItem { static is(item: TimelineItem): item is GitTimelineItem { @@ -51,16 +54,20 @@ export class GitTimelineItem extends TimelineItem { return this.shortenRef(this.previousRef); } - setItemDetails(uri: Uri, hash: string | undefined, author: string, email: string | undefined, date: string, message: string, shortStat?: CommitShortStat, remoteSourceCommands: Command[] = []): void { + setItemDetails(uri: Uri, hash: string | undefined, avatar: string | undefined, author: string, email: string | undefined, date: string, message: string, shortStat?: CommitShortStat, remoteSourceCommands: Command[] = []): void { this.tooltip = new MarkdownString('', true); this.tooltip.isTrusted = true; this.tooltip.supportHtml = true; + const avatarMarkdown = avatar + ? `![${author}](${avatar}|width=${AVATAR_SIZE},height=${AVATAR_SIZE})` + : '$(account)'; + if (email) { const emailTitle = l10n.t('Email'); - this.tooltip.appendMarkdown(`$(account) [**${author}**](mailto:${email} "${emailTitle} ${author}")`); + this.tooltip.appendMarkdown(`${avatarMarkdown} [**${author}**](mailto:${email} "${emailTitle} ${author}")`); } else { - this.tooltip.appendMarkdown(`$(account) **${author}**`); + this.tooltip.appendMarkdown(`${avatarMarkdown} **${author}**`); } this.tooltip.appendMarkdown(`, $(history) ${date}\n\n`); @@ -218,6 +225,16 @@ export class GitTimelineProvider implements TimelineProvider { const unpublishedCommits = await repo.getUnpublishedCommits(); const remoteHoverCommands = await provideSourceControlHistoryItemHoverCommands(this.model, repo); + const avatarQuery = { + commits: commits.map(c => ({ + hash: c.hash, + authorName: c.authorName, + authorEmail: c.authorEmail + }) satisfies AvatarQueryCommit), + size: 20 + } satisfies AvatarQuery; + const avatars = await provideSourceControlHistoryItemAvatar(this.model, repo, avatarQuery); + const items: GitTimelineItem[] = []; for (let index = 0; index < commits.length; index++) { const c = commits[index]; @@ -235,7 +252,7 @@ export class GitTimelineProvider implements TimelineProvider { const commitRemoteSourceCommands = !unpublishedCommits.has(c.hash) ? remoteHoverCommands : []; const messageWithLinks = await provideSourceControlHistoryItemMessageLinks(this.model, repo, message) ?? message; - item.setItemDetails(uri, c.hash, c.authorName!, c.authorEmail, dateFormatter.format(date), messageWithLinks, c.shortStat, commitRemoteSourceCommands); + item.setItemDetails(uri, c.hash, avatars?.get(c.hash), c.authorName!, c.authorEmail, dateFormatter.format(date), messageWithLinks, c.shortStat, commitRemoteSourceCommands); const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri); if (cmd) { @@ -260,7 +277,7 @@ export class GitTimelineProvider implements TimelineProvider { // TODO@eamodio: Replace with a better icon -- reflecting its status maybe? item.iconPath = new ThemeIcon('git-commit'); item.description = ''; - item.setItemDetails(uri, undefined, you, undefined, dateFormatter.format(date), Resource.getStatusText(index.type)); + item.setItemDetails(uri, undefined, undefined, you, undefined, dateFormatter.format(date), Resource.getStatusText(index.type)); const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri); if (cmd) { @@ -282,7 +299,7 @@ export class GitTimelineProvider implements TimelineProvider { const item = new GitTimelineItem('', index ? '~' : 'HEAD', l10n.t('Uncommitted Changes'), date.getTime(), 'working', 'git:file:working'); item.iconPath = new ThemeIcon('circle-outline'); item.description = ''; - item.setItemDetails(uri, undefined, you, undefined, dateFormatter.format(date), Resource.getStatusText(working.type)); + item.setItemDetails(uri, undefined, undefined, you, undefined, dateFormatter.format(date), Resource.getStatusText(working.type)); const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri); if (cmd) {