Skip to content

Commit cd5f9e1

Browse files
committed
Improves branch status icons
1 parent bff0741 commit cd5f9e1

File tree

4 files changed

+97
-87
lines changed

4 files changed

+97
-87
lines changed

src/git/utils/icons.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ import type { Repository } from '../models/repository';
1313
import type { GitStatus } from '../models/status';
1414

1515
export function getBranchIconPath(container: Container, branch: GitBranch | undefined): IconPath {
16-
const status = branch?.status;
17-
switch (status) {
16+
switch (branch?.status) {
1817
case 'ahead':
1918
case 'behind':
2019
case 'diverged':
21-
return getIconPathUris(container, `icon-branch-${status}.svg`);
20+
return getIconPathUris(container, `icon-branch-${branch.status}.svg`);
2221
case 'upToDate':
2322
return getIconPathUris(container, `icon-branch-synced.svg`);
2423
default:
@@ -165,33 +164,44 @@ export function getRepositoryStatusIconPath(
165164
): IconPath {
166165
const type = repository.virtual ? '-cloud' : '';
167166

168-
if (status?.hasWorkingTreeChanges) {
169-
return getIconPathUris(container, `icon-repo-changes${type}.svg`);
170-
}
171-
172167
const branchStatus = status?.branchStatus;
173168
switch (branchStatus) {
174169
case 'ahead':
175170
case 'behind':
176171
case 'diverged':
177172
return getIconPathUris(container, `icon-repo-${branchStatus}${type}.svg`);
178173
case 'upToDate':
174+
if (status?.hasWorkingTreeChanges) {
175+
return getIconPathUris(container, `icon-repo-changes${type}.svg`);
176+
}
179177
return getIconPathUris(container, `icon-repo-synced${type}.svg`);
180178
default:
179+
if (status?.hasWorkingTreeChanges) {
180+
return getIconPathUris(container, `icon-repo-changes${type}.svg`);
181+
}
181182
return getIconPathUris(container, `icon-repo${type}.svg`);
182183
}
183184
}
184185

185-
export function getWorktreeBranchIconPath(container: Container, branch: GitBranch | undefined): IconPath {
186-
const status = branch?.status;
187-
switch (status) {
186+
export function getWorktreeBranchIconPath(
187+
container: Container,
188+
branch: GitBranch | undefined,
189+
status?: GitStatus,
190+
): IconPath {
191+
switch (branch?.status) {
188192
case 'ahead':
189193
case 'behind':
190194
case 'diverged':
191-
return getIconPathUris(container, `icon-repo-${status}.svg`);
195+
return getIconPathUris(container, `icon-repo-${branch.status}.svg`);
192196
case 'upToDate':
197+
if (status?.hasWorkingTreeChanges) {
198+
return getIconPathUris(container, `icon-repo-changes.svg`);
199+
}
193200
return getIconPathUris(container, `icon-repo-synced.svg`);
194201
default:
202+
if (status?.hasWorkingTreeChanges) {
203+
return getIconPathUris(container, `icon-repo-changes.svg`);
204+
}
195205
return getIconPathUris(container, `icon-repo.svg`);
196206
}
197207
}

src/quickpicks/items/gitWizard.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { createReference } from '../../git/models/reference.utils';
1414
import type { GitRemote } from '../../git/models/remote';
1515
import { getRemoteUpstreamDescription } from '../../git/models/remote';
1616
import type { Repository } from '../../git/models/repository';
17-
import { isRevisionRange , shortenRevision } from '../../git/models/revision.utils';
17+
import { isRevisionRange, shortenRevision } from '../../git/models/revision.utils';
1818
import type { GitTag } from '../../git/models/tag';
1919
import { getBranchIconPath, getWorktreeBranchIconPath } from '../../git/utils/icons';
2020
import { fromNow } from '../../system/date';

src/webviews/apps/plus/home/components/branch-card.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,6 @@ export abstract class GlBranchCardBase extends GlElement {
415415
}
416416

417417
const hasWip =
418-
!this.branch.opened &&
419418
this.wip?.workingTreeState != null &&
420419
this.wip.workingTreeState.added + this.wip.workingTreeState.changed + this.wip.workingTreeState.deleted > 0;
421420

@@ -649,9 +648,7 @@ export abstract class GlBranchCardBase extends GlElement {
649648
}
650649

651650
private renderBranchIcon() {
652-
// Don't show changes on the active branch
653651
const hasChanges =
654-
!this.branch.opened &&
655652
this.wip?.workingTreeState != null &&
656653
this.wip.workingTreeState.added + this.wip.workingTreeState.changed + this.wip.workingTreeState.deleted > 0;
657654
return html`<gl-branch-icon
Lines changed: 75 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { css, html, LitElement } from 'lit';
1+
import { css, html, LitElement, svg } from 'lit';
22
import { customElement, property } from 'lit/decorators.js';
33
import type { GitBranchStatus } from '../../../../git/models/branch';
44
import { renderBranchName } from './branch-name';
@@ -20,7 +20,7 @@ export class GlBranchIcon extends LitElement {
2020
);
2121
--gl-icon-color-status-diverged: var(--vscode-gitlens-decorations\\.branchDivergedForegroundColor, #ff5);
2222
--gl-icon-color-status-behind: var(--vscode-gitlens-decorations\\.branchBehindForegroundColor, #f05);
23-
--gl-icon-color-status-ahead: var(--vscode-gitlens-decorations\\.branchBehindForegroundColor, #0f5);
23+
--gl-icon-color-status-ahead: var(--vscode-gitlens-decorations\\.branchAheadForegroundColor, #0f5);
2424
--gl-icon-color-status-missingUpstream: var(
2525
--vscode-gitlens-decorations\\.branchMissingUpstreamForegroundColor,
2626
#c74e39
@@ -49,6 +49,8 @@ export class GlBranchIcon extends LitElement {
4949
svg {
5050
width: 100%;
5151
height: 100%;
52+
margin-top: -0.2rem;
53+
vertical-align: middle;
5254
}
5355
`;
5456

@@ -68,86 +70,108 @@ export class GlBranchIcon extends LitElement {
6870
worktree: boolean = false;
6971

7072
override render() {
71-
if (!this.status) {
72-
return html`<code-icon icon=${this.worktree ? 'gl-worktrees-view' : 'git-branch'}></code-icon>`;
73-
}
73+
return html`<gl-tooltip placement="bottom"
74+
>${this.renderIcon()}<span slot="content">${this.renderTooltipContent()}</span></gl-tooltip
75+
>`;
76+
}
7477

75-
const statusColor = this.getStatusCssColor();
78+
private renderIcon() {
79+
if (!this.worktree && (!this.status || this.status === 'local')) {
80+
return html`<code-icon icon="git-branch"></code-icon>`;
81+
} else if (this.status === 'detached') {
82+
return html`<code-icon icon="git-commit"></code-icon>`;
83+
}
7684

77-
if (this.worktree) {
78-
return html`<gl-tooltip placement="bottom">
79-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16">
80-
<path
81-
fill="var(--gl-icon-color-foreground)"
82-
fill-rule="evenodd"
83-
d="M13.5 4h.501v1.003h-.2a5.5 5.5 0 0 1 1.2.755V3.5l-.5-.5H13.5v1zm-4 0V3H7.713l-.852-.854L6.507 2H1.511l-.5.5v3.996L1 6.507v6.995l.5.5h6.227a5.528 5.528 0 0 1-.836-1H2V7.496h.01v-.489h4.486l.354-.146.858-.858h.014a5.51 5.51 0 0 1 1.477-1H7.5l-.353.147-.858.857H2.011V3H6.3l.853.853.353.146H9.5z"
84-
clip-rule="evenodd"
85-
/>
86-
<path
87-
fill="${statusColor}"
88-
stroke="var(--gl-icon-color-foreground)"
89-
stroke-linejoin="bevel"
90-
stroke-width=".5"
91-
d="M11.5 6.75a3.25 3.25 0 1 1 0 6.5 3.25 3.25 0 0 1 0-6.5z"
92-
/>
93-
<path stroke="var(--gl-icon-color-foreground)" d="M11.5 13v3M11.5 1v6" />
94-
</svg>
95-
<div slot="content">${this.statusTooltip}</div>
96-
</gl-tooltip>`;
85+
let cssColor;
86+
let strokeWidth = '0.5';
87+
switch (this.status) {
88+
case 'diverged':
89+
cssColor = 'var(--gl-icon-color-status-diverged)';
90+
break;
91+
case 'behind':
92+
cssColor = 'var(--gl-icon-color-status-behind)';
93+
break;
94+
case 'ahead':
95+
cssColor = 'var(--gl-icon-color-status-ahead)';
96+
break;
97+
case 'missingUpstream':
98+
cssColor = 'var(--gl-icon-color-status-missingUpstream)';
99+
break;
100+
case 'upToDate':
101+
cssColor = `var(--gl-icon-color-status-${this.hasChanges ? 'changes' : 'synced'})`;
102+
break;
103+
default:
104+
if (this.hasChanges) {
105+
cssColor = 'var(--gl-icon-color-status-changes)';
106+
} else {
107+
cssColor = 'transparent';
108+
strokeWidth = '1';
109+
}
110+
break;
97111
}
98112

99-
return html`<gl-tooltip placement="bottom">
100-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16">
113+
if (this.worktree) {
114+
return svg`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16">
101115
<path
102-
fill="${statusColor}"
103-
stroke="var(--gl-icon-color-foreground)"
104-
stroke-linejoin="bevel"
105-
stroke-width=".5"
106-
d="M12 10.25a2.75 2.75 0 1 1 0 5.5 2.75 2.75 0 0 1 0-5.5z"
116+
fill="var(--gl-icon-color-foreground, #c5c5c5)"
117+
d="M13.5 4h.501v1.003h-.2a5.5 5.5 0 0 1 1.2.755V3.5l-.5-.5H13.5v1zm-4 0V3H7.713l-.852-.854L6.507 2H1.511l-.5.5v3.996L1 6.507v6.995l.5.5h6.227a5.528 5.528 0 0 1-.836-1H2V7.496h.01v-.489h4.486l.354-.146.858-.858h.014a5.51 5.51 0 0 1 1.477-1H7.5l-.353.147-.858.857H2.011V3H6.3l.853.853.353.146H9.5z"
107118
/>
108119
<path
109-
fill="var(--gl-icon-color-foreground)"
110-
fill-rule="evenodd"
111-
d="M6 3.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zM5 5.95a2.5 2.5 0 1 0-1 0v4.1a2.5 2.5 0 1 0 1.165.04c.168-.38.383-.622.61-.78.327-.227.738-.32 1.214-.31H7c.387 0 .76.03 1.124.059l.026.002c.343.027.694.055 1.003.046.313-.01.661-.06.954-.248.29-.185.466-.466.544-.812a.756.756 0 0 1 .046-.055 2.5 2.5 0 1 0-1.03-.134c-.028.108-.07.14-.1.16-.063.04-.191.08-.446.089a8.783 8.783 0 0 1-.917-.045A14.886 14.886 0 0 0 7.005 8c-.61-.013-1.249.105-1.8.488-.07.05-.14.102-.205.159V5.95zm7-.45a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm-9 7a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0z"
112-
clip-rule="evenodd"
120+
fill="${cssColor}"
121+
stroke="var(--gl-icon-color-foreground, #c5c5c5)"
122+
stroke-width="${strokeWidth}"
123+
d="M11.5 6.75a3.25 3.25 0 1 1 0 6.5 3.25 3.25 0 0 1 0-6.5z"
113124
/>
114-
</svg>
115-
<div slot="content">${this.statusTooltip}</div>
116-
</gl-tooltip>`;
125+
<path stroke="var(--gl-icon-color-foreground, #c5c5c5)" d="M11.5 13v3M11.5 1v6" />
126+
</svg>`;
127+
}
128+
129+
return svg`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16">
130+
<path
131+
fill="${cssColor}"
132+
stroke="var(--gl-icon-color-foreground, #c5c5c5)"
133+
stroke-width="${strokeWidth}"
134+
d="M12 10.25a2.75 2.75 0 1 1 0 5.5 2.75 2.75 0 0 1 0-5.5z"
135+
/>
136+
<path
137+
fill="var(--gl-icon-color-foreground, #c5c5c5)"
138+
d="M6 3.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zM5 5.95a2.5 2.5 0 1 0-1 0v4.1a2.5 2.5 0 1 0 1.165.04c.168-.38.383-.622.61-.78.327-.227.738-.32 1.214-.31H7c.387 0 .76.03 1.124.059l.026.002c.343.027.694.055 1.003.046.313-.01.661-.06.954-.248.29-.185.466-.466.544-.812a.756.756 0 0 1 .046-.055 2.5 2.5 0 1 0-1.03-.134c-.028.108-.07.14-.1.16-.063.04-.191.08-.446.089a8.783 8.783 0 0 1-.917-.045A14.886 14.886 0 0 0 7.005 8c-.61-.013-1.249.105-1.8.488-.07.05-.14.102-.205.159V5.95zm7-.45a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm-9 7a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0z"
139+
/>
140+
</svg>`;
117141
}
118142

119-
private get statusTooltip() {
120-
const branchOrWorktree = this.branch ? renderBranchName(this.branch) : 'Branch';
143+
private renderTooltipContent() {
144+
const branchName = this.branch ? renderBranchName(this.branch) : 'Branch';
121145

122146
let tooltip;
123147
const upstream = this.upstream ? renderBranchName(this.upstream) : 'its upstream';
124148
switch (this.status) {
125149
case 'diverged':
126-
tooltip = html`${branchOrWorktree} has diverged from ${upstream}`;
150+
tooltip = html`${branchName} has diverged from ${upstream}`;
127151
break;
128152
case 'behind':
129-
tooltip = html`${branchOrWorktree} is behind ${upstream}`;
153+
tooltip = html`${branchName} is behind ${upstream}`;
130154
break;
131155
case 'ahead':
132-
tooltip = html`${branchOrWorktree} is ahead of ${upstream}`;
156+
tooltip = html`${branchName} is ahead of ${upstream}`;
133157
break;
134158
case 'missingUpstream':
135-
tooltip = html`${branchOrWorktree} is missing its upstream ${upstream}`;
159+
tooltip = html`${branchName} is missing its upstream ${upstream}`;
136160
break;
137161
case 'upToDate':
138-
tooltip = html`${branchOrWorktree} is up to date with ${upstream}`;
162+
tooltip = html`${branchName} is up to date with ${upstream}`;
139163
break;
140164
case 'local':
141-
tooltip = html`${branchOrWorktree} is a local branch which has't been published`;
165+
tooltip = html`${branchName} is a local branch which has't been published`;
142166
break;
143167
case 'remote':
144-
tooltip = html`${branchOrWorktree} is a remote branch`;
168+
tooltip = html`${branchName} is a remote branch`;
145169
break;
146170
case 'detached':
147-
tooltip = html`${branchOrWorktree} is in a detached state, i.e. checked out to a commit or tag`;
171+
tooltip = html`${branchName} is in a detached state, i.e. checked out to a commit or tag`;
148172
break;
149173
default:
150-
tooltip = html`${branchOrWorktree} is in an unknown state`;
174+
tooltip = html`${branchName} is in an unknown state`;
151175
break;
152176
}
153177

@@ -166,25 +190,4 @@ export class GlBranchIcon extends LitElement {
166190
}
167191
return tooltip;
168192
}
169-
170-
private getStatusCssColor(): string {
171-
if (this.hasChanges) {
172-
return 'var(--gl-icon-color-status-changes)';
173-
}
174-
175-
switch (this.status) {
176-
case 'diverged':
177-
return 'var(--gl-icon-color-status-diverged)';
178-
case 'behind':
179-
return 'var(--gl-icon-color-status-behind)';
180-
case 'ahead':
181-
return 'var(--gl-icon-color-status-ahead)';
182-
case 'missingUpstream':
183-
return 'var(--gl-icon-color-status-missingUpstream)';
184-
case 'upToDate':
185-
return 'var(--gl-icon-color-status-synced)';
186-
default:
187-
return 'transparent';
188-
}
189-
}
190193
}

0 commit comments

Comments
 (0)