Skip to content

Commit 1afab52

Browse files
committed
ActivityBarService#showActivity returns a disposable, remove clearActivity, make message stack properly
1 parent b1d7c30 commit 1afab52

6 files changed

Lines changed: 72 additions & 47 deletions

File tree

src/vs/workbench/browser/parts/activitybar/activitybarPart.ts

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
2626
import { Scope as MementoScope } from 'vs/workbench/common/memento';
2727
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
2828
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
29-
import { dispose } from 'vs/base/common/lifecycle';
29+
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
3030
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
3131

3232
interface IViewletActivity {
@@ -49,7 +49,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
4949

5050
private viewletIdToActions: { [viewletId: string]: ActivityAction; };
5151
private viewletIdToActionItems: { [viewletId: string]: IActionItem; };
52-
private viewletIdToActivity: { [viewletId: string]: IViewletActivity; };
52+
private viewletIdToActivityStack: { [viewletId: string]: IViewletActivity[]; };
5353

5454
private memento: any;
5555
private pinnedViewlets: string[];
@@ -68,7 +68,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
6868

6969
this.viewletIdToActionItems = Object.create(null);
7070
this.viewletIdToActions = Object.create(null);
71-
this.viewletIdToActivity = Object.create(null);
71+
this.viewletIdToActivityStack = Object.create(null);
7272

7373
this.memento = this.getMemento(this.storageService, MementoScope.GLOBAL);
7474
this.pinnedViewlets = this.memento[ActivitybarPart.PINNED_VIEWLETS] || this.viewletService.getViewlets().map(v => v.id);
@@ -110,27 +110,51 @@ export class ActivitybarPart extends Part implements IActivityBarService {
110110
}
111111
}
112112

113-
public showActivity(viewletId: string, badge?: IBadge, clazz?: string): void {
113+
public showActivity(viewletId: string, badge: IBadge, clazz?: string): IDisposable {
114114

115-
// Update Action with activity
115+
const activity = <IViewletActivity>{ badge, clazz };
116+
const stack = this.viewletIdToActivityStack[viewletId] || (this.viewletIdToActivityStack[viewletId] = []);
117+
stack.unshift(activity);
118+
119+
this.updateActivity(viewletId);
120+
121+
return {
122+
dispose: () => {
123+
const stack = this.viewletIdToActivityStack[viewletId];
124+
if (!stack) {
125+
return;
126+
}
127+
const idx = stack.indexOf(activity);
128+
if (idx < 0) {
129+
return;
130+
}
131+
stack.splice(idx, 1);
132+
if (stack.length === 0) {
133+
delete this.viewletIdToActivityStack[viewletId];
134+
}
135+
this.updateActivity(viewletId);
136+
}
137+
};
138+
}
139+
140+
private updateActivity(viewletId: string) {
116141
const action = this.viewletIdToActions[viewletId];
117-
if (action) {
142+
if (!action) {
143+
return;
144+
}
145+
const stack = this.viewletIdToActivityStack[viewletId];
146+
if (!stack || !stack.length) {
147+
// reset
148+
action.setBadge(undefined);
149+
150+
} else {
151+
// update
152+
const [{badge, clazz}] = stack;
118153
action.setBadge(badge);
119154
if (clazz) {
120155
action.class = clazz;
121156
}
122157
}
123-
124-
// Keep for future use
125-
if (badge) {
126-
this.viewletIdToActivity[viewletId] = { badge, clazz };
127-
} else {
128-
delete this.viewletIdToActivity[viewletId];
129-
}
130-
}
131-
132-
public clearActivity(viewletId: string): void {
133-
this.showActivity(viewletId, null);
134158
}
135159

136160
public createContentArea(parent: Builder): Builder {
@@ -257,19 +281,14 @@ export class ActivitybarPart extends Part implements IActivityBarService {
257281

258282
// Make sure to restore activity
259283
Object.keys(this.viewletIdToActions).forEach(viewletId => {
260-
const activity = this.viewletIdToActivity[viewletId];
261-
if (activity) {
262-
this.showActivity(viewletId, activity.badge, activity.clazz);
263-
} else {
264-
this.showActivity(viewletId);
265-
}
284+
this.updateActivity(viewletId);
266285
});
267286
}
268287

269288
// Add overflow action as needed
270289
if (visibleViewletsChange && overflows) {
271290
this.viewletOverflowAction = this.instantiationService.createInstance(ViewletOverflowActivityAction, () => this.viewletOverflowActionItem.showMenu());
272-
this.viewletOverflowActionItem = this.instantiationService.createInstance(ViewletOverflowActivityActionItem, this.viewletOverflowAction, () => this.getOverflowingViewlets(), (viewlet: ViewletDescriptor) => this.viewletIdToActivity[viewlet.id] && this.viewletIdToActivity[viewlet.id].badge);
291+
this.viewletOverflowActionItem = this.instantiationService.createInstance(ViewletOverflowActivityActionItem, this.viewletOverflowAction, () => this.getOverflowingViewlets(), (viewlet: ViewletDescriptor) => this.viewletIdToActivityStack[viewlet.id] && this.viewletIdToActivityStack[viewlet.id][0].badge);
273292

274293
this.viewletSwitcherBar.push(this.viewletOverflowAction, { label: true, icon: true });
275294
}
@@ -449,4 +468,4 @@ export class ActivitybarPart extends Part implements IActivityBarService {
449468
// Pass to super
450469
super.shutdown();
451470
}
452-
}
471+
}

src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
422422
export class StatusUpdater implements IWorkbenchContribution {
423423

424424
private disposables: IDisposable[];
425+
private badgeHandle: IDisposable;
425426

426427
constructor(
427428
@IActivityBarService private activityBarService: IActivityBarService,
@@ -435,21 +436,23 @@ export class StatusUpdater implements IWorkbenchContribution {
435436
}
436437

437438
private onServiceChange(): void {
439+
440+
dispose(this.badgeHandle);
441+
438442
if (this.extensionsWorkbenchService.local.some(e => e.state === ExtensionState.Installing)) {
439-
this.activityBarService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', "Extensions")), 'extensions-badge progress-badge');
443+
this.badgeHandle = this.activityBarService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', "Extensions")), 'extensions-badge progress-badge');
440444
return;
441445
}
442446

443447
const outdated = this.extensionsWorkbenchService.local.reduce((r, e) => r + (e.outdated ? 1 : 0), 0);
444448
if (outdated > 0) {
445449
const badge = new NumberBadge(outdated, n => localize('outdatedExtensions', '{0} Outdated Extensions', n));
446-
this.activityBarService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge');
447-
} else {
448-
this.activityBarService.showActivity(VIEWLET_ID, null, 'extensions-badge');
450+
this.badgeHandle = this.activityBarService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge');
449451
}
450452
}
451453

452454
dispose(): void {
453455
this.disposables = dispose(this.disposables);
456+
dispose(this.badgeHandle);
454457
}
455458
}

src/vs/workbench/parts/files/electron-browser/dirtyFilesTracker.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export class DirtyFilesTracker implements IWorkbenchContribution {
2828
private toUnbind: IDisposable[];
2929
private lastDirtyCount: number;
3030
private stacks: IEditorStacksModel;
31+
private badgeHandle: IDisposable;
3132

3233
constructor(
3334
@ITextFileService private textFileService: ITextFileService,
@@ -132,10 +133,9 @@ export class DirtyFilesTracker implements IWorkbenchContribution {
132133
private updateActivityBadge(): void {
133134
const dirtyCount = this.textFileService.getDirty().length;
134135
this.lastDirtyCount = dirtyCount;
136+
dispose(this.badgeHandle);
135137
if (dirtyCount > 0) {
136-
this.activityBarService.showActivity(VIEWLET_ID, new NumberBadge(dirtyCount, num => nls.localize('dirtyFiles', "{0} unsaved files", dirtyCount)), 'explorer-viewlet-label');
137-
} else {
138-
this.activityBarService.clearActivity(VIEWLET_ID);
138+
this.badgeHandle = this.activityBarService.showActivity(VIEWLET_ID, new NumberBadge(dirtyCount, num => nls.localize('dirtyFiles', "{0} unsaved files", dirtyCount)), 'explorer-viewlet-label');
139139
}
140140
}
141141

@@ -155,4 +155,4 @@ export class DirtyFilesTracker implements IWorkbenchContribution {
155155
public dispose(): void {
156156
this.toUnbind = dispose(this.toUnbind);
157157
}
158-
}
158+
}

src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
3939
private messageService: IMessageService;
4040
private configurationService: IConfigurationService;
4141
private progressBadgeDelayer: async.Delayer<void>;
42+
private badgeHandle: lifecycle.IDisposable;
4243
private toDispose: lifecycle.IDisposable[];
4344

4445
constructor(
@@ -60,14 +61,17 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
6061
}
6162

6263
private onGitServiceChange(): void {
64+
65+
lifecycle.dispose(this.badgeHandle);
66+
6367
if (this.gitService.getState() !== git.ServiceState.OK) {
6468
this.progressBadgeDelayer.cancel();
65-
this.activityBarService.showActivity('workbench.view.git', null, 'git-viewlet-label');
69+
6670
} else if (this.gitService.isIdle()) {
6771
this.showChangesBadge();
6872
} else {
6973
this.progressBadgeDelayer.trigger(() => {
70-
this.activityBarService.showActivity('workbench.view.git', new ProgressBadge(() => nls.localize('gitProgressBadge', 'Running git status')), 'git-viewlet-label-progress');
74+
this.badgeHandle = this.activityBarService.showActivity('workbench.view.git', new ProgressBadge(() => nls.localize('gitProgressBadge', 'Running git status')), 'git-viewlet-label-progress');
7175
});
7276
}
7377
}
@@ -91,7 +95,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
9195
.filter(filter);
9296

9397
const badge = new NumberBadge(statuses.length, num => nls.localize('gitPendingChangesBadge', '{0} pending changes', num));
94-
this.activityBarService.showActivity('workbench.view.git', badge, 'git-viewlet-label');
98+
this.badgeHandle = this.activityBarService.showActivity('workbench.view.git', badge, 'git-viewlet-label');
9599
}
96100

97101
public getId(): string {
@@ -100,6 +104,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
100104

101105
public dispose(): void {
102106
this.toDispose = lifecycle.dispose(this.toDispose);
107+
lifecycle.dispose(this.badgeHandle);
103108
}
104109
}
105110

src/vs/workbench/parts/markers/browser/markersWorkbenchContributions.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class StatusUpdater implements IWorkbenchContribution {
2222
static ID = 'vs.markers.statusUpdater';
2323

2424
private toDispose: lifecycle.IDisposable[];
25+
private badgeHandle: lifecycle.IDisposable;
2526

2627
constructor(
2728
@IMarkerService private markerService: IMarkerService,
@@ -33,13 +34,14 @@ class StatusUpdater implements IWorkbenchContribution {
3334
}
3435

3536
private updateActivityBadge(): void {
37+
38+
lifecycle.dispose(this.badgeHandle);
39+
3640
const stats = this.markerService.getStatistics();
3741
const problemCount = stats.errors + stats.warnings + stats.infos + stats.unknowns;
3842
if (problemCount > 0) {
3943
const badge = new NumberBadge(problemCount, n => localize({ comment: ['Argument represents count (number) of errors and warnings.'], key: 'errorsAndWarnings' }, '{0} Errors and Warnings', n));
40-
this.activityBarService.showActivity(Constants.MARKERS_PANEL_ID, badge);
41-
} else {
42-
this.activityBarService.showActivity(Constants.MARKERS_PANEL_ID, null);
44+
this.badgeHandle = this.activityBarService.showActivity(Constants.MARKERS_PANEL_ID, badge);
4345
}
4446
}
4547

@@ -92,4 +94,4 @@ export function registerContributions(): void {
9294
(<IWorkbenchContributionsRegistry>platform.Registry.as(WorkbenchExtensions.Workbench)).registerWorkbenchContribution(
9395
StatusUpdater
9496
);
95-
}
97+
}

src/vs/workbench/services/activity/common/activityBarService.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55
'use strict';
66

7+
import { IDisposable } from 'vs/base/common/lifecycle';
78
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
89

910
export interface IBadge {
@@ -64,12 +65,7 @@ export interface IActivityBarService {
6465
/**
6566
* Show activity in the activitybar for the given viewlet.
6667
*/
67-
showActivity(viewletId: string, badge: IBadge, clazz?: string): void;
68-
69-
/**
70-
* Clears activity shown in the activitybar for the given viewlet.
71-
*/
72-
clearActivity(viewletId: string): void;
68+
showActivity(viewletId: string, badge: IBadge, clazz?: string): IDisposable;
7369

7470
/**
7571
* Unpins a viewlet from the activitybar.
@@ -90,4 +86,4 @@ export interface IActivityBarService {
9086
* Reorder viewlet ordering by moving a viewlet to the location of another viewlet.
9187
*/
9288
move(viewletId: string, toViewletId: string): void;
93-
}
89+
}

0 commit comments

Comments
 (0)