From 89a79eebc15c684e7ce3d73fce25eb1c59034ad1 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Mon, 18 Dec 2017 03:26:38 -0500 Subject: [PATCH] Adds gravatarsDefault setting for gravatar fallback --- CHANGELOG.md | 3 +++ README.md | 2 ++ package.json | 28 ++++++++++++++++++++++++++ src/configuration.ts | 12 +++++++++++ src/git/models/logCommit.ts | 47 ++++++++++++++++++++++++-------------------- src/views/commitFileNode.ts | 3 ++- src/views/commitNode.ts | 4 ++-- src/views/gitExplorer.ts | 6 +++++- src/views/resultsExplorer.ts | 6 +++++- 9 files changed, 85 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04c2a5c..3893573 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Only visible if there is more than 1 repository within the workspace - Adds [Gravatar](https://en.gravatar.com/) support to the `GitLens` view - Adds `gitlens.gitExplorer.gravatars` setting to specify whether or not to show gravatar images instead of commit (or status) icons in the `GitLens` view + - Adds `gitlens.gitExplorer.gravatarsDefault` setting to specify the style of the gravatar default (fallback) images in the `GitLens` view
`identicon` - a geometric pattern
`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)
`monsterid` - a monster with different colors, faces, etc
`retro` - 8-bit arcade-style pixelated faces
`robohash` - a robot with different colors, faces, etc
`wavatar` - faces with differing features and backgrounds + - Adds `gitlens.resultsExplorer.gravatars` setting to specify whether or not to show gravatar images instead of commit (or status) icons in the `GitLens Results` view + - Adds `gitlens.resultsExplorer.gravatarsDefault` setting to specify the style of the gravatar default (fallback) images in the `GitLens Results` view
`identicon` - a geometric pattern
`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)
`monsterid` - a monster with different colors, faces, etc
`retro` - 8-bit arcade-style pixelated faces
`robohash` - a robot with different colors, faces, etc
`wavatar` - faces with differing features and backgrounds - Adds `Select for Compare` command (`gitlens.explorers.selectForCompare`) to branch and revision (commit) nodes in the `GitLens` view to mark the base revision of a comparision - Adds `Compare with Selected` command (`gitlens.explorers.compareWithSelected`) to branch and revision (commit) nodes in the `GitLens` view once another branch or revision (commit) node within the same repository has been selected to compare the current selection with the previously selected revision (branch or commit) - Adds `Apply Changes` option to the commit/stash file quick pick menu -- closes [#232](https://github.com/eamodio/vscode-gitlens/issues/232) diff --git a/README.md b/README.md index 8af94cb..dada21b 100644 --- a/README.md +++ b/README.md @@ -441,6 +441,7 @@ GitLens is highly customizable and provides many configuration settings to allow |`gitlens.gitExplorer.commitFormat`|Specifies the format of committed changes in the `GitLens` view
Available tokens
${id} - commit id
${author} - commit author
${message} - commit message
${ago} - relative commit date (e.g. 1 day ago)
${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)
${authorAgo} - commit author, relative commit date
See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting |`gitlens.gitExplorer.commitFileFormat`|Specifies the format of a committed file in the `GitLens` view
Available tokens
${directory} - directory name
${file} - file name
${filePath} - formatted file name and path
${path} - full file path |`gitlens.gitExplorer.gravatars`|Specifies whether or not to show gravatar images instead of commit (or status) icons in the `GitLens` view +|`gitlens.gitExplorer.gravatarsDefault`|Specifies the style of the gravatar default (fallback) images in the `GitLens` view
`identicon` - a geometric pattern
`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)
`monsterid` - a monster with different colors, faces, etc
`retro` - 8-bit arcade-style pixelated faces
`robohash` - a robot with different colors, faces, etc
`wavatar` - faces with differing features and backgrounds |`gitlens.gitExplorer.includeWorkingTree`|Specifies whether or not to include working tree files inside the `Repository Status` node of the `GitLens` view |`gitlens.gitExplorer.showTrackingBranch`|Specifies whether or not to show the tracking branch when displaying local branches in the `GitLens` view" |`gitlens.gitExplorer.stashFormat`|Specifies the format of stashed changes in the `GitLens` view
Available tokens
${id} - commit id
${author} - commit author
${message} - commit message
${ago} - relative commit date (e.g. 1 day ago)
${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)
${authorAgo} - commit author, relative commit date
See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting @@ -457,6 +458,7 @@ GitLens is highly customizable and provides many configuration settings to allow |`gitlens.resultsExplorer.commitFormat`|Specifies the format of committed changes in the `GitLens Results` view
Available tokens
${id} - commit id
${author} - commit author
${message} - commit message
${ago} - relative commit date (e.g. 1 day ago)
${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)
${authorAgo} - commit author, relative commit date
See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting |`gitlens.resultsExplorer.commitFileFormat`|Specifies the format of a committed file in the `GitLens Results` view
Available tokens
${directory} - directory name
${file} - file name
${filePath} - formatted file name and path
${path} - full file path |`gitlens.resultsExplorer.gravatars`|Specifies whether or not to show gravatar images instead of commit (or status) icons in the `GitLens Results` view +|`gitlens.resultsExplorer.gravatarsDefault`|Specifies the style of the gravatar default (fallback) images in the `GitLens Results` view
`identicon` - a geometric pattern
`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)
`monsterid` - a monster with different colors, faces, etc
`retro` - 8-bit arcade-style pixelated faces
`robohash` - a robot with different colors, faces, etc
`wavatar` - faces with differing features and backgrounds |`gitlens.resultsExplorer.showTrackingBranch`|Specifies whether or not to show the tracking branch when displaying local branches in the `GitLens Results` view" |`gitlens.resultsExplorer.stashFormat`|Specifies the format of stashed changes in the `GitLens Results` view
Available tokens
${id} - commit id
${author} - commit author
${message} - commit message
${ago} - relative commit date (e.g. 1 day ago)
${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)
${authorAgo} - commit author, relative commit date
See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting |`gitlens.resultsExplorer.stashFileFormat`|Specifies the format of a stashed file in the `GitLens Results` view
Available tokens
${directory} - directory name
${file} - file name
${filePath} - formatted file name and path
${path} - full file path diff --git a/package.json b/package.json index 0ed4d7f..6a4e0b6 100644 --- a/package.json +++ b/package.json @@ -528,6 +528,20 @@ "description": "Specifies whether or not to show gravatar images instead of commit (or status) icons in the `GitLens` view", "scope": "window" }, + "gitlens.gitExplorer.gravatarsDefault": { + "type": "string", + "default": "robohash", + "enum": [ + "identicon", + "mm", + "monsterid", + "retro", + "robohash", + "wavatar" + ], + "description": "Specifies the style of the gravatar default (fallback) images in the `GitLens` view\n `identicon` - a geometric pattern\n `mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)\n `monsterid` - a monster with different colors, faces, etc\n `retro` - 8-bit arcade-style pixelated faces\n `robohash` - a robot with different colors, faces, etc\n `wavatar` - faces with differing features and backgrounds", + "scope": "window" + }, "gitlens.gitExplorer.includeWorkingTree": { "type": "boolean", "default": true, @@ -703,6 +717,20 @@ "description": "Specifies whether or not to show gravatar images instead of commit (or status) icons in the `GitLens Results` view", "scope": "window" }, + "gitlens.resultsExplorer.gravatarsDefault": { + "type": "string", + "default": "robohash", + "enum": [ + "identicon", + "mm", + "monsterid", + "retro", + "robohash", + "wavatar" + ], + "description": "Specifies the style of the gravatar default (fallback) images in the `GitLens Results` view\n `identicon` - a geometric pattern\n `mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)\n `monsterid` - a monster with different colors, faces, etc\n `retro` - 8-bit arcade-style pixelated faces\n `robohash` - a robot with different colors, faces, etc\n `wavatar` - faces with differing features and backgrounds", + "scope": "window" + }, "gitlens.resultsExplorer.showTrackingBranch": { "type": "boolean", "default": true, diff --git a/src/configuration.ts b/src/configuration.ts index e3dbf05..2554eb7 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -44,6 +44,15 @@ export enum ExplorerFilesLayout { Tree = 'tree' } +export enum GravatarDefault { + Faces = 'wavatar', + Geometric = 'identicon', + Monster = 'monsterid', + MysteryMan = 'mm', + Retro = 'retro', + Robot = 'robohash' +} + export enum KeyMap { Standard = 'standard', Chorded = 'chorded', @@ -147,6 +156,7 @@ export interface IExplorerConfig { commitFileFormat: string; // dateFormat: string | null; gravatars: boolean; + gravatarsDefault: GravatarDefault; showTrackingBranch: boolean; stashFormat: string; stashFileFormat: string; @@ -395,6 +405,7 @@ const emptyConfig: IConfig = { commitFileFormat: '', // dateFormat: string | null; gravatars: false, + gravatarsDefault: 'robohash' as GravatarDefault, includeWorkingTree: false, showTrackingBranch: false, stashFormat: '', @@ -414,6 +425,7 @@ const emptyConfig: IConfig = { commitFileFormat: '', // dateFormat: string | null; gravatars: false, + gravatarsDefault: 'robohash' as GravatarDefault, showTrackingBranch: false, stashFormat: '', stashFileFormat: '', diff --git a/src/git/models/logCommit.ts b/src/git/models/logCommit.ts index aabb3b4..d42765c 100644 --- a/src/git/models/logCommit.ts +++ b/src/git/models/logCommit.ts @@ -2,12 +2,17 @@ import { Strings } from '../../system'; import { Uri } from 'vscode'; import { GitCommit, GitCommitType } from './commit'; +import { GravatarDefault } from '../../configuration'; import { Git } from '../git'; import { GitStatusFileStatus, IGitStatusFile } from './status'; import * as path from 'path'; const gravatarCache: Map = new Map(); +export function clearGravatarCache() { + gravatarCache.clear(); +} + export class GitLogCommit extends GitCommit { nextSha?: string; @@ -43,27 +48,6 @@ export class GitLogCommit extends GitCommit { ); } - get gravatarUri(): Uri { - const key = this.email - ? this.email.trim().toLowerCase() - : ''; - - let gravatar = gravatarCache.get(key); - if (gravatar !== undefined) return gravatar; - - gravatar = Uri.parse(`https://www.gravatar.com/avatar/${this.email ? Strings.md5(this.email) : '00000000000000000000000000000000'}.jpg?s=22&d=retro`); - - // HACK: Monkey patch Uri.toString to avoid the unwanted query string encoding - const originalToStringFn = gravatar.toString; - gravatar.toString = function(skipEncoding?: boolean | undefined) { - return originalToStringFn.call(gravatar, true); - }; - - gravatarCache.set(key, gravatar); - - return gravatar; - } - get isMerge() { return this.parentShas && this.parentShas.length > 1; } @@ -107,6 +91,27 @@ export class GitLogCommit extends GitCommit { return `+${added} ~${changed} -${deleted}`; } + getGravatarUri(fallback: GravatarDefault): Uri { + const key = this.email + ? `${ this.email.trim().toLowerCase() }` + : ''; + + let gravatar = gravatarCache.get(key); + if (gravatar !== undefined) return gravatar; + + gravatar = Uri.parse(`https://www.gravatar.com/avatar/${this.email ? Strings.md5(this.email) : '00000000000000000000000000000000'}.jpg?s=22&d=${fallback}`); + + // HACK: Monkey patch Uri.toString to avoid the unwanted query string encoding + const originalToStringFn = gravatar.toString; + gravatar.toString = function(skipEncoding?: boolean | undefined) { + return originalToStringFn.call(gravatar, true); + }; + + gravatarCache.set(key, gravatar); + + return gravatar; + } + toFileCommit(fileName: string): GitLogCommit | undefined; toFileCommit(status: IGitStatusFile): GitLogCommit; toFileCommit(fileNameOrStatus: string | IGitStatusFile): GitLogCommit | undefined { diff --git a/src/views/commitFileNode.ts b/src/views/commitFileNode.ts index f806ddb..c7dfdd6 100644 --- a/src/views/commitFileNode.ts +++ b/src/views/commitFileNode.ts @@ -1,6 +1,7 @@ 'use strict'; import { Command, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Commands, DiffWithPreviousCommandArgs } from '../commands'; +import { GravatarDefault } from '../configuration'; import { Explorer, ExplorerNode, ResourceType } from './explorerNode'; import { CommitFormatter, getGitStatusIcon, GitBranch, GitLogCommit, GitUri, ICommitFormatOptions, IGitStatusFile, IStatusFormatOptions, StatusFileFormatter } from '../gitService'; import * as path from 'path'; @@ -68,7 +69,7 @@ export class CommitFileNode extends ExplorerNode { }; } else if ((this.displayAs & CommitFileNodeDisplayAs.Gravatar) === CommitFileNodeDisplayAs.Gravatar) { - item.iconPath = this.commit.gravatarUri; + item.iconPath = this.commit.getGravatarUri(this.explorer.config.gravatarsDefault || GravatarDefault.Robot); } item.command = this.getCommand(); diff --git a/src/views/commitNode.ts b/src/views/commitNode.ts index 0179665..103e402 100644 --- a/src/views/commitNode.ts +++ b/src/views/commitNode.ts @@ -3,7 +3,7 @@ import { Arrays, Iterables } from '../system'; import { Command, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Commands, DiffWithPreviousCommandArgs } from '../commands'; import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode'; -import { ExplorerFilesLayout } from '../configuration'; +import { ExplorerFilesLayout, GravatarDefault } from '../configuration'; import { FolderNode, IFileExplorerNode } from './folderNode'; import { Explorer, ExplorerNode, ExplorerRefNode, ResourceType } from './explorerNode'; import { CommitFormatter, GitBranch, GitLogCommit, GitService, ICommitFormatOptions } from '../gitService'; @@ -60,7 +60,7 @@ export class CommitNode extends ExplorerRefNode { : ResourceType.Commit; if (this.explorer.config.gravatars) { - item.iconPath = this.commit.gravatarUri; + item.iconPath = this.commit.getGravatarUri(this.explorer.config.gravatarsDefault || GravatarDefault.Robot); } else { item.iconPath = { dark: this.explorer.context.asAbsolutePath('images/dark/icon-commit.svg'), diff --git a/src/views/gitExplorer.ts b/src/views/gitExplorer.ts index 90a849e..1135d2e 100644 --- a/src/views/gitExplorer.ts +++ b/src/views/gitExplorer.ts @@ -6,7 +6,7 @@ import { configuration, ExplorerFilesLayout, IGitExplorerConfig } from '../confi import { CommandContext, GlyphChars, setCommandContext, WorkspaceState } from '../constants'; import { ExplorerCommands, RefreshNodeCommandArgs } from './explorerCommands'; import { ExplorerNode, HistoryNode, MessageNode, RefreshReason, RepositoriesNode, RepositoryNode } from './explorerNodes'; -import { GitChangeEvent, GitChangeReason, GitContextTracker, GitService, GitUri } from '../gitService'; +import { clearGravatarCache, GitChangeEvent, GitChangeReason, GitContextTracker, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; export * from './explorerNodes'; @@ -80,6 +80,10 @@ export class GitExplorer implements TreeDataProvider { const cfg = configuration.get(section.value); + if (!initializing && (configuration.changed(e, section('gravatars').value) || configuration.changed(e, section('gravatarsDefault').value))) { + clearGravatarCache(); + } + if (initializing || configuration.changed(e, section('autoRefresh').value)) { this.setAutoRefresh(cfg.autoRefresh); } diff --git a/src/views/resultsExplorer.ts b/src/views/resultsExplorer.ts index 6bb6c9c..f624813 100644 --- a/src/views/resultsExplorer.ts +++ b/src/views/resultsExplorer.ts @@ -5,7 +5,7 @@ import { configuration, ExplorerFilesLayout, IExplorerConfig } from '../configur import { CommandContext, setCommandContext, WorkspaceState } from '../constants'; import { ExplorerCommands, RefreshNodeCommandArgs } from './explorerCommands'; import { CommitsResultsNode, ComparisionResultsNode, ExplorerNode, MessageNode, RefreshReason, ResourceType } from './explorerNodes'; -import { GitLog, GitService } from '../gitService'; +import { clearGravatarCache, GitLog, GitService } from '../gitService'; import { Logger } from '../logger'; export * from './explorerNodes'; @@ -58,6 +58,10 @@ export class ResultsExplorer implements TreeDataProvider { const section = configuration.name('resultsExplorer'); if (!initializing && !configuration.changed(e, section.value)) return; + if (!initializing && (configuration.changed(e, section('gravatars').value) || configuration.changed(e, section('gravatarsDefault').value))) { + clearGravatarCache(); + } + const cfg = configuration.get(section.value); if (!initializing && this._roots.length !== 0) {