Skip to content

Commit 1888236

Browse files
committed
Fixes context/tooltip/action based on view/state
1 parent 441f3f3 commit 1888236

File tree

1 file changed

+52
-32
lines changed

1 file changed

+52
-32
lines changed

src/views/nodes/common.ts

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { createDirectiveQuickPickItem, Directive } from '../../quickpicks/items/
88
import { showRepositoryPicker2 } from '../../quickpicks/repositoryPicker';
99
import { configuration } from '../../system/-webview/configuration';
1010
import { getScopedCounter } from '../../system/counter';
11-
import { isPromise } from '../../system/promise';
11+
import { getSettledValue, isPromise } from '../../system/promise';
1212
import { compareSubstringIgnoreCase, equalsIgnoreCase, pluralize } from '../../system/string';
1313
import type { View } from '../viewBase';
1414
import type { PageableViewNode } from './abstract/viewNode';
@@ -153,15 +153,20 @@ export class GroupedHeaderNode extends ActionMessageNodeBase {
153153
parent,
154154
view.grouped ? view.name.toLocaleUpperCase() : 'Showing',
155155
view.grouped ? view.description : undefined,
156+
undefined,
157+
undefined,
158+
view.grouped ? `gitlens:views:${view.type}` : undefined,
156159
);
157160
}
158161

159162
override async action(): Promise<void> {
160-
const { openRepositories: repositories } = this.view.container.git;
161-
if (repositories.length <= 1) return;
163+
if (!this.view.supportsRepositoryFilter) return;
164+
165+
const { openRepositories: repos } = this.view.container.git;
166+
if (repos.length <= 1) return;
162167

163168
if (this.view.supportsWorktreeCollapsing) {
164-
const grouped = await groupRepositories(repositories);
169+
const grouped = await groupRepositories(repos);
165170
if (grouped.size <= 1) return;
166171
}
167172

@@ -171,7 +176,7 @@ export class GroupedHeaderNode extends ActionMessageNodeBase {
171176
this.view.container,
172177
`Select Repository or Worktree to Show`,
173178
`Choose a repository or worktree to show`,
174-
repositories,
179+
repos,
175180
{
176181
picked: isFiltered ? (await this.view.getFilteredRepositories())?.[0] : undefined,
177182
additionalItem: createDirectiveQuickPickItem(Directive.ReposAll, !isFiltered),
@@ -188,9 +193,16 @@ export class GroupedHeaderNode extends ActionMessageNodeBase {
188193
}
189194

190195
override async getTreeItem(): Promise<TreeItem> {
191-
const item = await super.getTreeItem();
192-
item.description = await this.getDescription();
193-
item.tooltip = await this.getTooltip();
196+
const [itemResult, reposResult] = await Promise.allSettled([
197+
super.getTreeItem(),
198+
this.view.getFilteredRepositories(),
199+
]);
200+
201+
const item = getSettledValue(itemResult)!;
202+
const repos = getSettledValue(reposResult) ?? [];
203+
204+
item.description = this.getDescription(repos);
205+
item.tooltip = this.getTooltip(repos);
194206
if (!this.view.grouped) {
195207
item.iconPath = this.view.isRepositoryFilterActive()
196208
? new ThemeIcon('filter-filled')
@@ -199,41 +211,35 @@ export class GroupedHeaderNode extends ActionMessageNodeBase {
199211
return item;
200212
}
201213

202-
private async getDescription(): Promise<string | undefined> {
214+
private getDescription(repos: Repository[]): string | undefined {
203215
const description = this.getViewDescription();
204-
const label = this.getRepositoryFilterLabel(await this.view.getFilteredRepositories(), true);
216+
const label = this.getRepositoryFilterLabel(repos, true);
205217
return label
206218
? description
207219
? `${description} ${GlyphChars.Space}${GlyphChars.Dot}${GlyphChars.Space} ${label}`
208220
: label
209221
: description;
210222
}
211223

212-
private getViewDescription(): string | undefined {
213-
let description = this.view.grouped ? this.view.description : undefined;
214-
if (description && !equalsIgnoreCase(this.view.name, description)) {
215-
const index = compareSubstringIgnoreCase(description, this.view.name, 0, this.view.name.length);
216-
description = index === 0 ? description.substring(this.view.name.length).trimStart() : description;
217-
if (description.startsWith(':')) {
218-
description = description.substring(1).trimStart();
219-
}
220-
return description;
221-
}
222-
223-
return undefined;
224-
}
225-
226-
private async getTooltip(): Promise<MarkdownString> {
224+
private getTooltip(repos: Repository[]): MarkdownString {
227225
const tooltip = new MarkdownString();
228226
if (this.view.grouped) {
229227
tooltip.appendText(this.view.name);
230228
const description = this.getViewDescription();
231229
if (description) {
232-
tooltip.appendMarkdown(` ${description}`);
230+
// TODO: This is so hacky
231+
if (description.startsWith('(')) {
232+
tooltip.appendMarkdown(` ${description}`);
233+
} else if (description.startsWith(GlyphChars.Dot)) {
234+
tooltip.appendMarkdown(` ${GlyphChars.Space}${description}`);
235+
} else {
236+
tooltip.appendMarkdown(`: ${description}`);
237+
}
233238
}
234239
}
235240

236-
const repos = await this.view.getFilteredRepositories();
241+
if (!this.view.supportsRepositoryFilter || repos.length <= 1) return tooltip;
242+
237243
tooltip.appendMarkdown(`\n\nShowing ${this.getRepositoryFilterLabel(repos, false)}`);
238244
if (this.view.isRepositoryFilterActive()) {
239245
tooltip.appendMarkdown('\\\nClick to change filtering');
@@ -244,26 +250,40 @@ export class GroupedHeaderNode extends ActionMessageNodeBase {
244250
return tooltip;
245251
}
246252

247-
private getRepositoryFilterLabel(repositories?: Repository[], addSuffix?: boolean): string | undefined {
253+
private getRepositoryFilterLabel(repos?: Repository[], addSuffix?: boolean): string | undefined {
248254
if (!this.view.supportsRepositoryFilter) return undefined;
249-
if (!repositories?.length) return undefined;
255+
if (!repos?.length) return undefined;
250256

251257
const prefix = this.view.grouped ? 'showing ' : '';
252258

253-
if (repositories.length === 1) {
259+
if (repos.length === 1) {
254260
if (this.view.repositoryFilter?.length) {
255-
return addSuffix ? `${prefix}${repositories[0].name} — click to change` : repositories[0].name;
261+
return addSuffix ? `${prefix}${repos[0].name} — click to change` : repos[0].name;
256262
}
257263
return undefined;
258264
}
259265

260266
const mixed = !this.view.supportsWorktreeCollapsing;
261267

262-
const label = pluralize(mixed ? 'repo / worktree' : 'repo', repositories.length, {
268+
const label = pluralize(mixed ? 'repo / worktree' : 'repo', repos.length, {
263269
plural: mixed ? 'repos / worktrees' : 'repos',
264270
});
265271
return addSuffix ? `${prefix}${label} — click to filter` : label;
266272
}
273+
274+
private getViewDescription(): string | undefined {
275+
let description = this.view.grouped ? this.view.description : undefined;
276+
if (description && !equalsIgnoreCase(this.view.name, description)) {
277+
const index = compareSubstringIgnoreCase(description, this.view.name, 0, this.view.name.length);
278+
description = index === 0 ? description.substring(this.view.name.length).trimStart() : description;
279+
if (description.startsWith(':')) {
280+
description = description.substring(1).trimStart();
281+
}
282+
return description;
283+
}
284+
285+
return undefined;
286+
}
267287
}
268288

269289
export abstract class PagerNode extends ViewNode<'pager'> {

0 commit comments

Comments
 (0)