Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4033,6 +4033,10 @@
"fileRange": {
"type": "string",
"markdownDescription": "Specifies the format of a range in a file URL for the custom remote service\n\nAvailable tokens\\\n`${start}` — starting line\\\n`${end}` — ending line"
},
"avatar": {
"type": "string",
"markdownDescription": "Specifies the format of a avatar url for the custom remote service\n\nAvailable tokens\\\n`${email}` — contributor email\\\n`${name}` — email local-part\\\n`${domain}` — email domain\\\n`${size}` — avatar size"
}
},
"additionalProperties": false
Expand Down
29 changes: 24 additions & 5 deletions src/avatars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { GravatarDefaultStyle } from './config';
import type { StoredAvatar } from './constants.storage';
import { Container } from './container';
import type { CommitAuthor } from './git/models/author';
import { CustomRemote } from './git/remotes/custom';
import { getGitHubNoReplyAddressParts } from './git/remotes/github';
import { configuration } from './system/-webview/configuration';
import { getContext } from './system/-webview/context';
Expand Down Expand Up @@ -130,7 +131,7 @@ function getAvatarUriCore(
if (
!options?.cached &&
repoPathOrCommit != null &&
getContext('gitlens:repos:withHostingIntegrationsConnected')?.includes(
getContext('gitlens:repos:withRemotes')?.includes(
typeof repoPathOrCommit === 'string' ? repoPathOrCommit : repoPathOrCommit.repoPath,
)
) {
Expand Down Expand Up @@ -228,16 +229,34 @@ async function getAvatarUriFromRemoteProvider(
// account = await remote?.provider.getAccountForEmail(email, { avatarSize: size });
// } else {
if (typeof repoPathOrCommit !== 'string') {
const remote = await Container.instance.git
const remoteWithIntegration = await Container.instance.git
.getRepositoryService(repoPathOrCommit.repoPath)
.remotes.getBestRemoteWithIntegration();
if (remote?.supportsIntegration()) {

if (remoteWithIntegration?.supportsIntegration()) {
account = await (
await remote.getIntegration()
)?.getAccountForCommit(remote.provider.repoDesc, repoPathOrCommit.ref, {
await remoteWithIntegration.getIntegration()
)?.getAccountForCommit(remoteWithIntegration.provider.repoDesc, repoPathOrCommit.ref, {
avatarSize: size,
});
}

if (!account) {
const remoteWithProvider = await Container.instance.git
.getRepositoryService(repoPathOrCommit.repoPath)
.remotes.getBestRemoteWithProvider();

if (remoteWithProvider?.provider instanceof CustomRemote) {
const avatarUrl = remoteWithProvider.provider.getUrlForAvatar(email, size);
if (avatarUrl != null) {
avatar.uri = Uri.parse(avatarUrl);
avatar.timestamp = Date.now();
avatar.retries = 0;
avatarCache.set(`${md5(email.trim().toLowerCase())}:${size}`, { ...avatar });
return avatar.uri;
}
}
}
}

if (account?.avatarUrl == null) {
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,7 @@ export interface RemotesUrlsConfig {
readonly fileInCommit: string;
readonly fileLine: string;
readonly fileRange: string;
readonly avatar?: string;
}

interface StatusBarConfig {
Expand Down
13 changes: 13 additions & 0 deletions src/git/remotes/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ export class CustomRemote extends RemoteProvider {
return Promise.resolve(undefined);
}

getUrlForAvatar(email: string, size: number): string | undefined {
if (this.urls.avatar != null) {
const [name, domain] = email.split('@');
return this.encodeUrl(
interpolate(
this.urls.avatar,
this.getContext({ name: name, domain: domain, email: email, size: String(size) }),
),
);
}
return undefined;
}

protected override getUrlForRepository(): string {
return this.getUrl(this.urls.repository, this.getContext());
}
Expand Down