提交 1afab52e 编写于 作者: J Johannes Rieken

ActivityBarService#showActivity returns a disposable, remove clearActivity,...

ActivityBarService#showActivity returns a disposable, remove clearActivity, make message stack properly
上级 b1d7c308
...@@ -26,7 +26,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; ...@@ -26,7 +26,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
import { Scope as MementoScope } from 'vs/workbench/common/memento'; import { Scope as MementoScope } from 'vs/workbench/common/memento';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { dispose } from 'vs/base/common/lifecycle'; import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility'; import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
interface IViewletActivity { interface IViewletActivity {
...@@ -49,7 +49,7 @@ export class ActivitybarPart extends Part implements IActivityBarService { ...@@ -49,7 +49,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
private viewletIdToActions: { [viewletId: string]: ActivityAction; }; private viewletIdToActions: { [viewletId: string]: ActivityAction; };
private viewletIdToActionItems: { [viewletId: string]: IActionItem; }; private viewletIdToActionItems: { [viewletId: string]: IActionItem; };
private viewletIdToActivity: { [viewletId: string]: IViewletActivity; }; private viewletIdToActivityStack: { [viewletId: string]: IViewletActivity[]; };
private memento: any; private memento: any;
private pinnedViewlets: string[]; private pinnedViewlets: string[];
...@@ -68,7 +68,7 @@ export class ActivitybarPart extends Part implements IActivityBarService { ...@@ -68,7 +68,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
this.viewletIdToActionItems = Object.create(null); this.viewletIdToActionItems = Object.create(null);
this.viewletIdToActions = Object.create(null); this.viewletIdToActions = Object.create(null);
this.viewletIdToActivity = Object.create(null); this.viewletIdToActivityStack = Object.create(null);
this.memento = this.getMemento(this.storageService, MementoScope.GLOBAL); this.memento = this.getMemento(this.storageService, MementoScope.GLOBAL);
this.pinnedViewlets = this.memento[ActivitybarPart.PINNED_VIEWLETS] || this.viewletService.getViewlets().map(v => v.id); 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 { ...@@ -110,27 +110,51 @@ export class ActivitybarPart extends Part implements IActivityBarService {
} }
} }
public showActivity(viewletId: string, badge?: IBadge, clazz?: string): void { public showActivity(viewletId: string, badge: IBadge, clazz?: string): IDisposable {
// Update Action with activity const activity = <IViewletActivity>{ badge, clazz };
const stack = this.viewletIdToActivityStack[viewletId] || (this.viewletIdToActivityStack[viewletId] = []);
stack.unshift(activity);
this.updateActivity(viewletId);
return {
dispose: () => {
const stack = this.viewletIdToActivityStack[viewletId];
if (!stack) {
return;
}
const idx = stack.indexOf(activity);
if (idx < 0) {
return;
}
stack.splice(idx, 1);
if (stack.length === 0) {
delete this.viewletIdToActivityStack[viewletId];
}
this.updateActivity(viewletId);
}
};
}
private updateActivity(viewletId: string) {
const action = this.viewletIdToActions[viewletId]; const action = this.viewletIdToActions[viewletId];
if (action) { if (!action) {
return;
}
const stack = this.viewletIdToActivityStack[viewletId];
if (!stack || !stack.length) {
// reset
action.setBadge(undefined);
} else {
// update
const [{badge, clazz}] = stack;
action.setBadge(badge); action.setBadge(badge);
if (clazz) { if (clazz) {
action.class = clazz; action.class = clazz;
} }
} }
// Keep for future use
if (badge) {
this.viewletIdToActivity[viewletId] = { badge, clazz };
} else {
delete this.viewletIdToActivity[viewletId];
}
}
public clearActivity(viewletId: string): void {
this.showActivity(viewletId, null);
} }
public createContentArea(parent: Builder): Builder { public createContentArea(parent: Builder): Builder {
...@@ -257,19 +281,14 @@ export class ActivitybarPart extends Part implements IActivityBarService { ...@@ -257,19 +281,14 @@ export class ActivitybarPart extends Part implements IActivityBarService {
// Make sure to restore activity // Make sure to restore activity
Object.keys(this.viewletIdToActions).forEach(viewletId => { Object.keys(this.viewletIdToActions).forEach(viewletId => {
const activity = this.viewletIdToActivity[viewletId]; this.updateActivity(viewletId);
if (activity) {
this.showActivity(viewletId, activity.badge, activity.clazz);
} else {
this.showActivity(viewletId);
}
}); });
} }
// Add overflow action as needed // Add overflow action as needed
if (visibleViewletsChange && overflows) { if (visibleViewletsChange && overflows) {
this.viewletOverflowAction = this.instantiationService.createInstance(ViewletOverflowActivityAction, () => this.viewletOverflowActionItem.showMenu()); this.viewletOverflowAction = this.instantiationService.createInstance(ViewletOverflowActivityAction, () => this.viewletOverflowActionItem.showMenu());
this.viewletOverflowActionItem = this.instantiationService.createInstance(ViewletOverflowActivityActionItem, this.viewletOverflowAction, () => this.getOverflowingViewlets(), (viewlet: ViewletDescriptor) => this.viewletIdToActivity[viewlet.id] && this.viewletIdToActivity[viewlet.id].badge); this.viewletOverflowActionItem = this.instantiationService.createInstance(ViewletOverflowActivityActionItem, this.viewletOverflowAction, () => this.getOverflowingViewlets(), (viewlet: ViewletDescriptor) => this.viewletIdToActivityStack[viewlet.id] && this.viewletIdToActivityStack[viewlet.id][0].badge);
this.viewletSwitcherBar.push(this.viewletOverflowAction, { label: true, icon: true }); this.viewletSwitcherBar.push(this.viewletOverflowAction, { label: true, icon: true });
} }
...@@ -449,4 +468,4 @@ export class ActivitybarPart extends Part implements IActivityBarService { ...@@ -449,4 +468,4 @@ export class ActivitybarPart extends Part implements IActivityBarService {
// Pass to super // Pass to super
super.shutdown(); super.shutdown();
} }
} }
\ No newline at end of file
...@@ -422,6 +422,7 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet { ...@@ -422,6 +422,7 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
export class StatusUpdater implements IWorkbenchContribution { export class StatusUpdater implements IWorkbenchContribution {
private disposables: IDisposable[]; private disposables: IDisposable[];
private badgeHandle: IDisposable;
constructor( constructor(
@IActivityBarService private activityBarService: IActivityBarService, @IActivityBarService private activityBarService: IActivityBarService,
...@@ -435,21 +436,23 @@ export class StatusUpdater implements IWorkbenchContribution { ...@@ -435,21 +436,23 @@ export class StatusUpdater implements IWorkbenchContribution {
} }
private onServiceChange(): void { private onServiceChange(): void {
dispose(this.badgeHandle);
if (this.extensionsWorkbenchService.local.some(e => e.state === ExtensionState.Installing)) { if (this.extensionsWorkbenchService.local.some(e => e.state === ExtensionState.Installing)) {
this.activityBarService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', "Extensions")), 'extensions-badge progress-badge'); this.badgeHandle = this.activityBarService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', "Extensions")), 'extensions-badge progress-badge');
return; return;
} }
const outdated = this.extensionsWorkbenchService.local.reduce((r, e) => r + (e.outdated ? 1 : 0), 0); const outdated = this.extensionsWorkbenchService.local.reduce((r, e) => r + (e.outdated ? 1 : 0), 0);
if (outdated > 0) { if (outdated > 0) {
const badge = new NumberBadge(outdated, n => localize('outdatedExtensions', '{0} Outdated Extensions', n)); const badge = new NumberBadge(outdated, n => localize('outdatedExtensions', '{0} Outdated Extensions', n));
this.activityBarService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge'); this.badgeHandle = this.activityBarService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge');
} else {
this.activityBarService.showActivity(VIEWLET_ID, null, 'extensions-badge');
} }
} }
dispose(): void { dispose(): void {
this.disposables = dispose(this.disposables); this.disposables = dispose(this.disposables);
dispose(this.badgeHandle);
} }
} }
...@@ -28,6 +28,7 @@ export class DirtyFilesTracker implements IWorkbenchContribution { ...@@ -28,6 +28,7 @@ export class DirtyFilesTracker implements IWorkbenchContribution {
private toUnbind: IDisposable[]; private toUnbind: IDisposable[];
private lastDirtyCount: number; private lastDirtyCount: number;
private stacks: IEditorStacksModel; private stacks: IEditorStacksModel;
private badgeHandle: IDisposable;
constructor( constructor(
@ITextFileService private textFileService: ITextFileService, @ITextFileService private textFileService: ITextFileService,
...@@ -132,10 +133,9 @@ export class DirtyFilesTracker implements IWorkbenchContribution { ...@@ -132,10 +133,9 @@ export class DirtyFilesTracker implements IWorkbenchContribution {
private updateActivityBadge(): void { private updateActivityBadge(): void {
const dirtyCount = this.textFileService.getDirty().length; const dirtyCount = this.textFileService.getDirty().length;
this.lastDirtyCount = dirtyCount; this.lastDirtyCount = dirtyCount;
dispose(this.badgeHandle);
if (dirtyCount > 0) { if (dirtyCount > 0) {
this.activityBarService.showActivity(VIEWLET_ID, new NumberBadge(dirtyCount, num => nls.localize('dirtyFiles', "{0} unsaved files", dirtyCount)), 'explorer-viewlet-label'); this.badgeHandle = this.activityBarService.showActivity(VIEWLET_ID, new NumberBadge(dirtyCount, num => nls.localize('dirtyFiles', "{0} unsaved files", dirtyCount)), 'explorer-viewlet-label');
} else {
this.activityBarService.clearActivity(VIEWLET_ID);
} }
} }
...@@ -155,4 +155,4 @@ export class DirtyFilesTracker implements IWorkbenchContribution { ...@@ -155,4 +155,4 @@ export class DirtyFilesTracker implements IWorkbenchContribution {
public dispose(): void { public dispose(): void {
this.toUnbind = dispose(this.toUnbind); this.toUnbind = dispose(this.toUnbind);
} }
} }
\ No newline at end of file
...@@ -39,6 +39,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution { ...@@ -39,6 +39,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
private messageService: IMessageService; private messageService: IMessageService;
private configurationService: IConfigurationService; private configurationService: IConfigurationService;
private progressBadgeDelayer: async.Delayer<void>; private progressBadgeDelayer: async.Delayer<void>;
private badgeHandle: lifecycle.IDisposable;
private toDispose: lifecycle.IDisposable[]; private toDispose: lifecycle.IDisposable[];
constructor( constructor(
...@@ -60,14 +61,17 @@ export class StatusUpdater implements ext.IWorkbenchContribution { ...@@ -60,14 +61,17 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
} }
private onGitServiceChange(): void { private onGitServiceChange(): void {
lifecycle.dispose(this.badgeHandle);
if (this.gitService.getState() !== git.ServiceState.OK) { if (this.gitService.getState() !== git.ServiceState.OK) {
this.progressBadgeDelayer.cancel(); this.progressBadgeDelayer.cancel();
this.activityBarService.showActivity('workbench.view.git', null, 'git-viewlet-label');
} else if (this.gitService.isIdle()) { } else if (this.gitService.isIdle()) {
this.showChangesBadge(); this.showChangesBadge();
} else { } else {
this.progressBadgeDelayer.trigger(() => { this.progressBadgeDelayer.trigger(() => {
this.activityBarService.showActivity('workbench.view.git', new ProgressBadge(() => nls.localize('gitProgressBadge', 'Running git status')), 'git-viewlet-label-progress'); this.badgeHandle = this.activityBarService.showActivity('workbench.view.git', new ProgressBadge(() => nls.localize('gitProgressBadge', 'Running git status')), 'git-viewlet-label-progress');
}); });
} }
} }
...@@ -91,7 +95,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution { ...@@ -91,7 +95,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
.filter(filter); .filter(filter);
const badge = new NumberBadge(statuses.length, num => nls.localize('gitPendingChangesBadge', '{0} pending changes', num)); const badge = new NumberBadge(statuses.length, num => nls.localize('gitPendingChangesBadge', '{0} pending changes', num));
this.activityBarService.showActivity('workbench.view.git', badge, 'git-viewlet-label'); this.badgeHandle = this.activityBarService.showActivity('workbench.view.git', badge, 'git-viewlet-label');
} }
public getId(): string { public getId(): string {
...@@ -100,6 +104,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution { ...@@ -100,6 +104,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
public dispose(): void { public dispose(): void {
this.toDispose = lifecycle.dispose(this.toDispose); this.toDispose = lifecycle.dispose(this.toDispose);
lifecycle.dispose(this.badgeHandle);
} }
} }
......
...@@ -22,6 +22,7 @@ class StatusUpdater implements IWorkbenchContribution { ...@@ -22,6 +22,7 @@ class StatusUpdater implements IWorkbenchContribution {
static ID = 'vs.markers.statusUpdater'; static ID = 'vs.markers.statusUpdater';
private toDispose: lifecycle.IDisposable[]; private toDispose: lifecycle.IDisposable[];
private badgeHandle: lifecycle.IDisposable;
constructor( constructor(
@IMarkerService private markerService: IMarkerService, @IMarkerService private markerService: IMarkerService,
...@@ -33,13 +34,14 @@ class StatusUpdater implements IWorkbenchContribution { ...@@ -33,13 +34,14 @@ class StatusUpdater implements IWorkbenchContribution {
} }
private updateActivityBadge(): void { private updateActivityBadge(): void {
lifecycle.dispose(this.badgeHandle);
const stats = this.markerService.getStatistics(); const stats = this.markerService.getStatistics();
const problemCount = stats.errors + stats.warnings + stats.infos + stats.unknowns; const problemCount = stats.errors + stats.warnings + stats.infos + stats.unknowns;
if (problemCount > 0) { if (problemCount > 0) {
const badge = new NumberBadge(problemCount, n => localize({ comment: ['Argument represents count (number) of errors and warnings.'], key: 'errorsAndWarnings' }, '{0} Errors and Warnings', n)); const badge = new NumberBadge(problemCount, n => localize({ comment: ['Argument represents count (number) of errors and warnings.'], key: 'errorsAndWarnings' }, '{0} Errors and Warnings', n));
this.activityBarService.showActivity(Constants.MARKERS_PANEL_ID, badge); this.badgeHandle = this.activityBarService.showActivity(Constants.MARKERS_PANEL_ID, badge);
} else {
this.activityBarService.showActivity(Constants.MARKERS_PANEL_ID, null);
} }
} }
...@@ -92,4 +94,4 @@ export function registerContributions(): void { ...@@ -92,4 +94,4 @@ export function registerContributions(): void {
(<IWorkbenchContributionsRegistry>platform.Registry.as(WorkbenchExtensions.Workbench)).registerWorkbenchContribution( (<IWorkbenchContributionsRegistry>platform.Registry.as(WorkbenchExtensions.Workbench)).registerWorkbenchContribution(
StatusUpdater StatusUpdater
); );
} }
\ No newline at end of file
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import { IDisposable } from 'vs/base/common/lifecycle';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface IBadge { export interface IBadge {
...@@ -64,12 +65,7 @@ export interface IActivityBarService { ...@@ -64,12 +65,7 @@ export interface IActivityBarService {
/** /**
* Show activity in the activitybar for the given viewlet. * Show activity in the activitybar for the given viewlet.
*/ */
showActivity(viewletId: string, badge: IBadge, clazz?: string): void; showActivity(viewletId: string, badge: IBadge, clazz?: string): IDisposable;
/**
* Clears activity shown in the activitybar for the given viewlet.
*/
clearActivity(viewletId: string): void;
/** /**
* Unpins a viewlet from the activitybar. * Unpins a viewlet from the activitybar.
...@@ -90,4 +86,4 @@ export interface IActivityBarService { ...@@ -90,4 +86,4 @@ export interface IActivityBarService {
* Reorder viewlet ordering by moving a viewlet to the location of another viewlet. * Reorder viewlet ordering by moving a viewlet to the location of another viewlet.
*/ */
move(viewletId: string, toViewletId: string): void; move(viewletId: string, toViewletId: string): void;
} }
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册