Browse Source

Graph: add rich scrollbar support (#2489)

* Setup hard-coded colors for scrollbar markers

* Add upstream for local refs and current for upstream remote

* Add setting to toggle the feature

* Removes tag markers and sets selection color

* Updates marker names

* Pluralizes some marker names

* Remove redundant css properties

* Use markers in settings

* Match minimap hues

* Restore space

* Fix typo

* Bump graph dependency

* Avoids extra array copying

---------

Co-authored-by: Eric Amodio <eamodio@gmail.com>
main
Ramin Tadayon 2 years ago
committed by GitHub
parent
commit
5b6be2a64c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 130 additions and 10 deletions
  1. +38
    -1
      package.json
  2. +14
    -0
      src/config.ts
  3. +4
    -0
      src/env/node/git/localGitProvider.ts
  4. +2
    -0
      src/plus/github/githubGitProvider.ts
  5. +22
    -0
      src/plus/webviews/graph/graphWebview.ts
  6. +12
    -0
      src/plus/webviews/graph/protocol.ts
  7. +2
    -4
      src/webviews/apps/plus/graph/GraphWrapper.tsx
  8. +20
    -1
      src/webviews/apps/plus/graph/graph.tsx
  9. +12
    -0
      src/webviews/apps/settings/partials/commit-graph.html
  10. +4
    -4
      yarn.lock

+ 38
- 1
package.json View File

@ -2216,6 +2216,43 @@
"scope": "window",
"order": 12
},
"gitlens.graph.scrollMarkers.enabled": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to show markers on the scrollbar in the _Commit Graph_",
"scope": "window",
"order": 13
},
"gitlens.graph.scrollMarkers.additionalTypes": {
"type": "array",
"default": [
"head",
"localBranches"
],
"items": {
"type": "string",
"enum": [
"head",
"localBranches",
"remoteBranches",
"tags",
"stashes"
],
"enumDescriptions": [
"Marks the location of the current HEAD and its upstream",
"Marks the location of local branches",
"Marks the location of remote branches",
"Marks the location of tags",
"Marks the location of stashes"
]
},
"minItems": 0,
"maxItems": 5,
"uniqueItems": true,
"markdownDescription": "Specifies additional markers to show in the _Commit Graph_",
"scope": "window",
"order": 14
},
"gitlens.graph.scrollRowPadding": {
"type": "number",
"default": 0,
@ -13048,7 +13085,7 @@
"vscode:prepublish": "yarn run bundle"
},
"dependencies": {
"@gitkraken/gitkraken-components": "4.0.0",
"@gitkraken/gitkraken-components": "5.0.0",
"@microsoft/fast-element": "1.11.0",
"@microsoft/fast-react-wrapper": "0.3.16-0",
"@octokit/core": "4.2.0",

+ 14
- 0
src/config.ts View File

@ -289,6 +289,16 @@ export const enum GitCommandSorting {
Usage = 'usage',
}
export const enum GraphScrollMarkerTypes {
Selection = 'selection',
Head = 'head',
LocalBranches = 'localBranches',
RemoteBranches = 'remoteBranches',
Highlights = 'highlights',
Stashes = 'stashes',
Tags = 'tags',
}
export const enum GravatarDefaultStyle {
Faces = 'wavatar',
Geometric = 'identicon',
@ -402,6 +412,10 @@ export interface GraphConfig {
scrollRowPadding: number;
showDetailsView: 'open' | 'selection' | false;
showGhostRefsOnRowHover: boolean;
scrollMarkers: {
enabled: boolean;
additionalTypes: GraphScrollMarkerTypes[];
};
pullRequests: {
enabled: boolean;
};

+ 4
- 0
src/env/node/git/localGitProvider.ts View File

@ -1709,6 +1709,8 @@ export class LocalGitProvider implements GitProvider, Disposable {
const branches = getSettledValue(branchesResult)?.values;
const branchMap = branches != null ? new Map(branches.map(r => [r.name, r])) : new Map<string, GitBranch>();
const headBranch = branches?.find(b => b.current);
const headRefUpstreamName = headBranch?.upstream?.name;
const currentUser = getSettledValue(currentUserResult);
@ -1940,6 +1942,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
url: remote.url,
avatarUrl: avatarUrl,
context: serializeWebviewItemContext<GraphItemRefContext>(context),
current: tip === headRefUpstreamName,
};
refRemoteHeads.push(refRemoteHead);
@ -1980,6 +1983,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
name: tip,
isCurrentHead: head,
context: serializeWebviewItemContext<GraphItemRefContext>(context),
upstream: branch?.upstream?.name,
};
refHeads.push(refHead);

+ 2
- 0
src/plus/github/githubGitProvider.ts View File

@ -1217,6 +1217,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
}),
},
}),
upstream: branch.upstream?.name,
},
];
refRemoteHeads = [
@ -1241,6 +1242,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
}),
},
}),
current: true,
},
];
} else {

+ 22
- 0
src/plus/webviews/graph/graphWebview.ts View File

@ -146,6 +146,7 @@ import {
GetMissingRefsMetadataCommandType,
GetMoreRowsCommandType,
GraphRefMetadataTypes,
GraphScrollMarkerTypes,
SearchCommandType,
SearchOpenInViewCommandType,
supportedRefMetadataTypes,
@ -602,6 +603,8 @@ export class GraphWebview extends WebviewBase {
configuration.changed(e, 'graph.dimMergeCommits') ||
configuration.changed(e, 'graph.highlightRowsOnRefHover') ||
configuration.changed(e, 'graph.scrollRowPadding') ||
configuration.changed(e, 'graph.scrollMarkers.enabled') ||
configuration.changed(e, 'graph.scrollMarkers.additionalTypes') ||
configuration.changed(e, 'graph.showGhostRefsOnRowHover') ||
configuration.changed(e, 'graph.pullRequests.enabled') ||
configuration.changed(e, 'graph.showRemoteNames') ||
@ -1652,6 +1655,7 @@ export class GraphWebview extends WebviewBase {
highlightRowsOnRefHover: configuration.get('graph.highlightRowsOnRefHover'),
minimap: configuration.get('graph.experimental.minimap.enabled'),
scrollRowPadding: configuration.get('graph.scrollRowPadding'),
enabledScrollMarkerTypes: this.getEnabledGraphScrollMarkers(),
showGhostRefsOnRowHover: configuration.get('graph.showGhostRefsOnRowHover'),
showRemoteNamesOnRefs: configuration.get('graph.showRemoteNames'),
idLength: configuration.get('advanced.abbreviatedShaLength'),
@ -1659,6 +1663,24 @@ export class GraphWebview extends WebviewBase {
return config;
}
private getEnabledGraphScrollMarkers(): GraphScrollMarkerTypes[] {
const markersEnabled = configuration.get('graph.scrollMarkers.enabled');
if (!markersEnabled) return [];
const markers: GraphScrollMarkerTypes[] = [
GraphScrollMarkerTypes.Selection,
GraphScrollMarkerTypes.Highlights,
...(configuration.get('graph.scrollMarkers.additionalTypes') as unknown as GraphScrollMarkerTypes[]),
];
// Head and upstream are under the same setting, but separate markers in the component
if (markers.includes(GraphScrollMarkerTypes.Head)) {
markers.push(GraphScrollMarkerTypes.Upstream);
}
return markers;
}
private getEnabledRefMetadataTypes(): GraphRefMetadataType[] {
const types: GraphRefMetadataType[] = [];
if (configuration.get('graph.pullRequests.enabled')) {

+ 12
- 0
src/plus/webviews/graph/protocol.ts View File

@ -50,6 +50,17 @@ export enum GraphRefMetadataTypes {
PullRequest = 'pullRequest',
}
export const enum GraphScrollMarkerTypes {
Selection = 'selection',
Head = 'head',
Highlights = 'highlights',
LocalBranches = 'localBranches',
RemoteBranches = 'remoteBranches',
Stashes = 'stashes',
Tags = 'tags',
Upstream = 'upstream',
}
export const supportedRefMetadataTypes: GraphRefMetadataType[] = Object.values(GraphRefMetadataTypes);
export type GraphCommitDateTimeSource = CommitDateTimeSource;
@ -139,6 +150,7 @@ export interface GraphComponentConfig {
highlightRowsOnRefHover?: boolean;
minimap?: boolean;
scrollRowPadding?: number;
enabledScrollMarkerTypes?: GraphScrollMarkerTypes[];
showGhostRefsOnRowHover?: boolean;
showRemoteNamesOnRefs?: boolean;
idLength?: number;

+ 2
- 4
src/webviews/apps/plus/graph/GraphWrapper.tsx View File

@ -8,7 +8,6 @@ import type {
GraphRefOptData,
GraphRow,
GraphZoneType,
Head,
OnFormatCommitDateTime,
} from '@gitkraken/gitkraken-components';
import GraphContainer, { GRAPH_ZONE_TYPE, REF_ZONE_TYPE } from '@gitkraken/gitkraken-components';
@ -367,7 +366,6 @@ export function GraphWrapper({
let day;
let prevDay;
let head: Head | undefined;
let markers;
let headMarkers;
let remoteMarkers;
@ -398,7 +396,6 @@ export function GraphWrapper({
// eslint-disable-next-line no-loop-func
headMarkers = row.heads.map<GraphMinimapMarker>(h => {
if (h.isCurrentHead) {
head = h;
rankedShas.head = row.sha;
}
@ -423,7 +420,7 @@ export function GraphWrapper({
// eslint-disable-next-line no-loop-func
remoteMarkers = row.remotes.map<GraphMinimapMarker>(r => {
let current = false;
if (r.name === head?.name) {
if (r.current) {
rankedShas.remote = row.sha;
current = true;
}
@ -1265,6 +1262,7 @@ export function GraphWrapper({
cssVariables={styleProps?.cssVariables}
dimMergeCommits={graphConfig?.dimMergeCommits}
enabledRefMetadataTypes={graphConfig?.enabledRefMetadataTypes}
enabledScrollMarkerTypes={graphConfig?.enabledScrollMarkerTypes}
enableMultiSelection={graphConfig?.enableMultiSelection}
excludeRefsById={excludeRefsById}
excludeByType={excludeTypes}

+ 20
- 1
src/webviews/apps/plus/graph/graph.tsx View File

@ -381,12 +381,13 @@ export class GraphApp extends App {
bodyStyle.setProperty('--color-graph-text-secondary', opacity(e.colors.foreground, 65));
bodyStyle.setProperty('--color-graph-text-disabled', opacity(e.colors.foreground, 50));
// minimap
// minimap and scroll markers
const resultColor = Color.fromHex('#ffff00');
const headColor = Color.fromHex('#00ff00');
const branchColor = Color.fromHex('#ff7f50');
const tagColor = Color.fromHex('#15a0bf');
const stashColor = Color.fromHex('#800080');
color = e.computedStyle.getPropertyValue('--vscode-progressBar-background').trim();
const activityColor = Color.from(color);
@ -419,12 +420,17 @@ export class GraphApp extends App {
.toString();
// color = e.computedStyle.getPropertyValue('--vscode-editorCursor-foreground').trim();
bodyStyle.setProperty('--color-graph-minimap-selectedMarker', color);
bodyStyle.setProperty('--color-graph-scroll-marker-selection', color);
bodyStyle.setProperty('--color-graph-minimap-highlightedMarker', opacity(color, 60));
bodyStyle.setProperty(
'--color-graph-minimap-resultMarker',
resultColor.luminance(themeLuminance(0.6)).toString(),
);
bodyStyle.setProperty(
'--color-graph-scroll-marker-highlights',
resultColor.luminance(themeLuminance(0.6)).toString(),
);
const pillLabel = foregroundColor.luminance(themeLuminance(e.isLightTheme ? 0 : 1)).toString();
const headBackground = headColor.luminance(themeLuminance(e.isLightTheme ? 0.9 : 0.2)).toString();
@ -435,11 +441,13 @@ export class GraphApp extends App {
bodyStyle.setProperty('--color-graph-minimap-headBorder', headBorder);
bodyStyle.setProperty('--color-graph-minimap-headForeground', pillLabel);
bodyStyle.setProperty('--color-graph-minimap-headMarker', opacity(headMarker, 80));
bodyStyle.setProperty('--color-graph-scroll-marker-head', opacity(headMarker, 90));
bodyStyle.setProperty('--color-graph-minimap-upstreamBackground', headBackground);
bodyStyle.setProperty('--color-graph-minimap-upstreamBorder', headBorder);
bodyStyle.setProperty('--color-graph-minimap-upstreamForeground', pillLabel);
bodyStyle.setProperty('--color-graph-minimap-upstreamMarker', opacity(headMarker, 60));
bodyStyle.setProperty('--color-graph-scroll-marker-upstream', opacity(headMarker, 60));
const branchBackground = branchColor.luminance(themeLuminance(e.isLightTheme ? 0.8 : 0.3)).toString();
const branchBorder = branchColor.luminance(themeLuminance(e.isLightTheme ? 0.2 : 0.4)).toString();
@ -449,11 +457,13 @@ export class GraphApp extends App {
bodyStyle.setProperty('--color-graph-minimap-branchBorder', branchBorder);
bodyStyle.setProperty('--color-graph-minimap-branchForeground', pillLabel);
bodyStyle.setProperty('--color-graph-minimap-branchMarker', opacity(branchMarker, 70));
bodyStyle.setProperty('--color-graph-scroll-marker-local-branches', opacity(branchMarker, 90));
bodyStyle.setProperty('--color-graph-minimap-remoteBackground', opacity(branchBackground, 80));
bodyStyle.setProperty('--color-graph-minimap-remoteBorder', opacity(branchBorder, 80));
bodyStyle.setProperty('--color-graph-minimap-remoteForeground', pillLabel);
bodyStyle.setProperty('--color-graph-minimap-remoteMarker', opacity(branchMarker, 30));
bodyStyle.setProperty('--color-graph-scroll-marker-remote-branches', opacity(branchMarker, 60));
bodyStyle.setProperty(
'--color-graph-minimap-tagBackground',
@ -468,6 +478,15 @@ export class GraphApp extends App {
'--color-graph-minimap-tagMarker',
opacity(tagColor.luminance(themeLuminance(0.5)).toString(), 60),
);
bodyStyle.setProperty(
'--color-graph-scroll-marker-tags',
opacity(tagColor.luminance(themeLuminance(0.9)).toString(), 90),
);
bodyStyle.setProperty(
'--color-graph-scroll-marker-stashes',
opacity(stashColor.luminance(themeLuminance(0.9)).toString(), 90),
);
if (e.isInitializing) return;

+ 12
- 0
src/webviews/apps/settings/partials/commit-graph.html View File

@ -80,6 +80,18 @@
</div>
<div class="setting">
<div class="setting__input">
<input
id="graph.scrollMarkers.enabled"
name="graph.scrollMarkers.enabled"
type="checkbox"
data-setting
/>
<label for="graph.scrollMarkers.enabled">Show markers on the Commit Graph scrollbar</label>
</div>
</div>
<div class="setting">
<div class="setting__input setting__input--inner-select">
<input
id="graph.showDetailsView"

+ 4
- 4
yarn.lock View File

@ -185,10 +185,10 @@
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
"@gitkraken/gitkraken-components@4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@gitkraken/gitkraken-components/-/gitkraken-components-4.0.0.tgz#dbb18b69accc424b3c3703db5d4f327d5d2ba72b"
integrity sha512-lt6Gf9goQaJvIG+Rga/R41OpvYmIA+aoq6aHu184SrJLlpqYbKp/B3u+91CBqghP6DnKbAaDJbTUaBImg2oEHA==
"@gitkraken/gitkraken-components@5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@gitkraken/gitkraken-components/-/gitkraken-components-5.0.0.tgz#2898918a9c83c01941251eb738c28d54c39d7b7f"
integrity sha512-S3mavyTM/M5VOn+eUYy/BRGHF8rK3n0s6x2/i+OCilUobchXh5T4NvnDvAQ2cQgkb0Yv9UtiwO/mjsgq5PvKYQ==
dependencies:
"@axosoft/react-virtualized" "9.22.3-gitkraken.3"
classnames "2.3.2"

Loading…
Cancel
Save