Skip to content

Commit db4e98d

Browse files
Remembers the expanded/collapsed state of Launchpad View groups
1 parent de6e835 commit db4e98d

File tree

3 files changed

+58
-3
lines changed

3 files changed

+58
-3
lines changed

src/constants.storage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export type GlobalStorage = {
7272
'launchpad:groups:collapsed': StoredLaunchpadGroup[];
7373
'launchpad:indicator:hasLoaded': boolean;
7474
'launchpad:indicator:hasInteracted': string;
75+
'launchpadView:groups:expanded': StoredLaunchpadGroup[];
7576
'graph:searchMode': StoredGraphSearchMode;
7677
} & { [key in `confirm:ai:tos:${AIProviders}`]: boolean } & {
7778
[key in `provider:authentication:skip:${string}`]: boolean;

src/views/launchpadView.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import { configuration } from '../system/vscode/configuration';
1919
import { CacheableChildrenViewNode } from './nodes/abstract/cacheableChildrenViewNode';
2020
import type { ClipboardType, ViewNode } from './nodes/abstract/viewNode';
2121
import { ContextValues, getViewNodeId } from './nodes/abstract/viewNode';
22-
import { GroupingNode } from './nodes/groupingNode';
22+
import type { GroupingNode } from './nodes/groupingNode';
23+
import { LaunchpadViewGroupingNode } from './nodes/launchpadViewGroupingNode';
2324
import { getPullRequestChildren, getPullRequestTooltip } from './nodes/pullRequestNode';
2425
import { ViewBase } from './viewBase';
2526
import { registerViewCommand } from './viewCommands';
@@ -141,17 +142,25 @@ export class LaunchpadViewNode extends CacheableChildrenViewNode<
141142
}
142143

143144
const uiGroups = groupAndSortLaunchpadItems(result.items);
145+
const expanded = new Map(
146+
(
147+
(this.view.container.storage.get('launchpadView:groups:expanded') satisfies
148+
| LaunchpadGroup[]
149+
| undefined) ?? []
150+
).map(g => [g, true]),
151+
);
144152
for (const [ui, groupItems] of uiGroups) {
145153
if (!groupItems.length) continue;
146154

147155
const icon = launchpadGroupIconMap.get(ui)!;
148156

149157
children.push(
150-
new GroupingNode(
158+
new LaunchpadViewGroupingNode(
151159
this.view,
152160
launchpadGroupLabelMap.get(ui)!,
161+
ui,
153162
groupItems.map(i => new LaunchpadItemNode(this.view, this, ui, i)),
154-
TreeItemCollapsibleState.Collapsed,
163+
expanded.get(ui) ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.Collapsed,
155164
undefined,
156165
undefined,
157166
new ThemeIcon(icon.substring(2, icon.length - 1)),
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { TreeItem } from 'vscode';
2+
import { Disposable, TreeItemCollapsibleState } from 'vscode';
3+
import type { LaunchpadGroup } from '../../plus/launchpad/launchpadProvider';
4+
import type { TreeViewNodeCollapsibleStateChangeEvent, View } from '../viewBase';
5+
import type { ViewNode } from './abstract/viewNode';
6+
import { GroupingNode } from './groupingNode';
7+
8+
export class LaunchpadViewGroupingNode<TChild extends ViewNode = ViewNode> extends GroupingNode {
9+
private disposable: Disposable;
10+
11+
constructor(
12+
view: View,
13+
label: string,
14+
private readonly group: LaunchpadGroup,
15+
childrenOrFn: TChild[] | Promise<TChild[]> | (() => TChild[] | Promise<TChild[]>),
16+
collapsibleState: TreeItemCollapsibleState = TreeItemCollapsibleState.Expanded,
17+
description?: string,
18+
tooltip?: string,
19+
iconPath?: TreeItem['iconPath'],
20+
contextValue?: string,
21+
) {
22+
super(view, label, childrenOrFn, collapsibleState, description, tooltip, iconPath, contextValue);
23+
this.disposable = Disposable.from(
24+
this.view.onDidChangeNodeCollapsibleState(this.onNodeCollapsibleStateChanged, this),
25+
);
26+
}
27+
28+
override dispose() {
29+
super.dispose();
30+
this.disposable?.dispose();
31+
}
32+
33+
private onNodeCollapsibleStateChanged(e: TreeViewNodeCollapsibleStateChangeEvent<ViewNode>) {
34+
if (e.element === this) {
35+
const storedExpandedGroups = this.view.container.storage.get('launchpadView:groups:expanded') ?? [];
36+
if (e.state === TreeItemCollapsibleState.Expanded) {
37+
storedExpandedGroups.push(this.group);
38+
} else {
39+
storedExpandedGroups.splice(storedExpandedGroups.indexOf(this.group), 1);
40+
}
41+
42+
void this.view.container.storage.store('launchpadView:groups:expanded', storedExpandedGroups);
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)