activitybarPart.ts 20.3 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

B
Benjamin Pasero 已提交
6
import 'vs/css!./media/activitybarpart';
7
import * as nls from 'vs/nls';
J
Johannes Rieken 已提交
8
import { illegalArgument } from 'vs/base/common/errors';
9
import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
B
Benjamin Pasero 已提交
10
import { GlobalActivityExtensions, IGlobalActivityRegistry } from 'vs/workbench/common/activity';
11
import { Registry } from 'vs/platform/registry/common/platform';
J
Johannes Rieken 已提交
12
import { Part } from 'vs/workbench/browser/part';
13
import { GlobalActivityActionItem, GlobalActivityAction, ViewletActivityAction, ToggleViewletAction, PlaceHolderToggleCompositePinnedAction, PlaceHolderViewletActivityAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
B
Benjamin Pasero 已提交
14
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
I
isidor 已提交
15
import { IBadge } from 'vs/workbench/services/activity/common/activity';
I
isidor 已提交
16
import { IPartService, Parts, Position as SideBarPosition } from 'vs/workbench/services/part/common/partService';
J
Johannes Rieken 已提交
17
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
18
import { IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle';
19
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
20
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
21
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND, ACTIVITY_BAR_INACTIVE_FOREGROUND } from 'vs/workbench/common/theme';
22
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
23
import { CompositeBar, ICompositeBarItem } from 'vs/workbench/browser/parts/compositeBar';
24
import { Dimension, addClass } from 'vs/base/browser/dom';
25
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
26
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
27
import { URI, UriComponents } from 'vs/base/common/uri';
28
import { ToggleCompositePinnedAction, ICompositeBarColors } from 'vs/workbench/browser/parts/compositeBarActions';
29
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
S
Sandeep Somavarapu 已提交
30
import { IViewsService, IViewContainersRegistry, Extensions as ViewContainerExtensions, ViewContainer, TEST_VIEW_CONTAINER_ID, IViewDescriptorCollection } from 'vs/workbench/common/views';
S
Sandeep Somavarapu 已提交
31
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
S
Sandeep Somavarapu 已提交
32
import { IViewlet } from 'vs/workbench/common/viewlet';
33
import { isUndefinedOrNull } from 'vs/base/common/types';
34

S
Sandeep Somavarapu 已提交
35 36 37
const SCM_VIEWLET_ID = 'workbench.view.scm';

interface ICachedViewlet {
38
	id: string;
39 40 41 42
	iconUrl: UriComponents;
	pinned: boolean;
	order: number;
	visible: boolean;
S
Sandeep Somavarapu 已提交
43
	views?: { when: string }[];
S
Sandeep Somavarapu 已提交
44 45
}

I
isidor 已提交
46
export class ActivitybarPart extends Part {
47

B
Benjamin Pasero 已提交
48
	private static readonly ACTION_HEIGHT = 50;
49
	private static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets';
P
Pine Wu 已提交
50

51 52
	private dimension: Dimension;

53
	private globalActionBar: ActionBar;
B
Benjamin Pasero 已提交
54
	private globalActivityIdToActions: { [globalActivityId: string]: GlobalActivityAction; } = Object.create(null);
55

S
Sandeep Somavarapu 已提交
56
	private cachedViewlets: ICachedViewlet[] = [];
57
	private compositeBar: CompositeBar;
B
Benjamin Pasero 已提交
58
	private compositeActions: { [compositeId: string]: { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } } = Object.create(null);
59

E
Erich Gamma 已提交
60
	constructor(
61
		id: string,
62 63 64
		@IViewletService private readonly viewletService: IViewletService,
		@IInstantiationService private readonly instantiationService: IInstantiationService,
		@IPartService private readonly partService: IPartService,
65
		@IThemeService themeService: IThemeService,
66 67 68 69
		@IStorageService private readonly storageService: IStorageService,
		@IExtensionService private readonly extensionService: IExtensionService,
		@IViewsService private readonly viewsService: IViewsService,
		@IContextKeyService private readonly contextKeyService: IContextKeyService
E
Erich Gamma 已提交
70
	) {
71
		super(id, { hasTitle: false }, themeService, storageService);
E
Erich Gamma 已提交
72

73
		this.cachedViewlets = this.getCachedViewlets();
74 75 76 77 78 79
		for (const cachedViewlet of this.cachedViewlets) {
			if (this.shouldBeHidden(cachedViewlet.id, cachedViewlet)) {
				cachedViewlet.visible = false;
			}
		}

R
Rob Lourens 已提交
80
		this.compositeBar = this._register(this.instantiationService.createInstance(CompositeBar, this.cachedViewlets.map(v => (<ICompositeBarItem>{ id: v.id, name: undefined, visible: v.visible, order: v.order, pinned: v.pinned })), {
I
isidor 已提交
81
			icon: true,
82
			orientation: ActionsOrientation.VERTICAL,
83
			openComposite: (compositeId: string) => this.viewletService.openViewlet(compositeId, true),
84 85
			getActivityAction: (compositeId: string) => this.getCompositeActions(compositeId).activityAction,
			getCompositePinnedAction: (compositeId: string) => this.getCompositeActions(compositeId).pinnedAction,
86
			getOnCompositeClickAction: (compositeId: string) => this.instantiationService.createInstance(ToggleViewletAction, this.viewletService.getViewlet(compositeId)),
87
			getContextMenuActions: () => [this.instantiationService.createInstance(ToggleActivityBarVisibilityAction, ToggleActivityBarVisibilityAction.ID, nls.localize('hideActivitBar', "Hide Activity Bar"))],
88
			getDefaultCompositeId: () => this.viewletService.getDefaultViewletId(),
I
isidor 已提交
89
			hidePart: () => this.partService.setSideBarHidden(true),
90
			compositeSize: 50,
91
			colors: theme => this.getActivitybarItemColors(theme),
I
isidor 已提交
92
			overflowActionSize: ActivitybarPart.ACTION_HEIGHT
B
Benjamin Pasero 已提交
93 94
		}));

E
Erich Gamma 已提交
95
		this.registerListeners();
96
		this.onDidRegisterViewlets(viewletService.getViewlets());
E
Erich Gamma 已提交
97 98 99
	}

	private registerListeners(): void {
100

S
Sandeep Somavarapu 已提交
101
		this._register(this.viewletService.onDidViewletRegister(viewlet => this.onDidRegisterViewlets([viewlet])));
102
		this._register(this.viewletService.onDidViewletDeregister(({ id }) => this.removeComposite(id, true)));
103

E
Erich Gamma 已提交
104
		// Activate viewlet action on opening of a viewlet
S
Sandeep Somavarapu 已提交
105
		this._register(this.viewletService.onDidViewletOpen(viewlet => this.onDidViewletOpen(viewlet)));
E
Erich Gamma 已提交
106 107

		// Deactivate viewlet action on close
B
Benjamin Pasero 已提交
108 109
		this._register(this.viewletService.onDidViewletClose(viewlet => this.compositeBar.deactivateComposite(viewlet.getId())));

110 111 112 113 114 115 116 117
		let disposables: IDisposable[] = [];
		this._register(this.extensionService.onDidRegisterExtensions(() => {
			disposables = dispose(disposables);
			this.onDidRegisterExtensions();
			this.compositeBar.onDidChange(() => this.saveCachedViewlets(), this, disposables);
			this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables);
		}));
		this._register(toDisposable(() => dispose(disposables)));
E
Erich Gamma 已提交
118 119
	}

B
Benjamin Pasero 已提交
120
	private onDidRegisterExtensions(): void {
S
Sandeep Somavarapu 已提交
121
		this.removeNotExistingComposites();
122
		for (const viewlet of this.viewletService.getViewlets()) {
S
Sandeep Somavarapu 已提交
123 124 125 126
			this.enableCompositeActions(viewlet);
			const viewContainer = this.getViewContainer(viewlet.id);
			if (viewContainer) {
				const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer);
S
Sandeep Somavarapu 已提交
127 128 129 130
				if (viewDescriptors) {
					this.onDidChangeActiveViews(viewlet, viewDescriptors);
					viewDescriptors.onDidChangeActiveViews(() => this.onDidChangeActiveViews(viewlet, viewDescriptors));
				}
S
Sandeep Somavarapu 已提交
131 132
			}
		}
133
		this.saveCachedViewlets();
S
Sandeep Somavarapu 已提交
134 135 136 137 138 139 140 141 142 143 144
	}

	private onDidChangeActiveViews(viewlet: ViewletDescriptor, viewDescriptors: IViewDescriptorCollection): void {
		if (viewDescriptors.activeViewDescriptors.length) {
			this.compositeBar.addComposite(viewlet);
		} else {
			this.removeComposite(viewlet.id, true);
		}
	}

	private onDidViewletOpen(viewlet: IViewlet): void {
S
Sandeep Somavarapu 已提交
145
		// Update the composite bar by adding
S
Sandeep Somavarapu 已提交
146 147
		this.compositeBar.addComposite(this.viewletService.getViewlet(viewlet.getId()));
		this.compositeBar.activateComposite(viewlet.getId());
S
Sandeep Somavarapu 已提交
148 149
		const viewletDescriptor = this.viewletService.getViewlet(viewlet.getId());
		const viewContainer = this.getViewContainer(viewletDescriptor.id);
S
Sandeep Somavarapu 已提交
150 151 152 153 154 155
		if (viewContainer) {
			const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer);
			if (viewDescriptors && viewDescriptors.activeViewDescriptors.length === 0) {
				// Update the composite bar by hiding
				this.removeComposite(viewletDescriptor.id, true);
			}
S
Sandeep Somavarapu 已提交
156
		}
E
Erich Gamma 已提交
157 158
	}

B
Benjamin Pasero 已提交
159
	showActivity(viewletOrActionId: string, badge: IBadge, clazz?: string, priority?: number): IDisposable {
B
Benjamin Pasero 已提交
160
		if (this.viewletService.getViewlet(viewletOrActionId)) {
J
Joao Moreno 已提交
161
			return this.compositeBar.showActivity(viewletOrActionId, badge, clazz, priority);
B
Benjamin Pasero 已提交
162 163
		}

164
		return this.showGlobalActivity(viewletOrActionId, badge, clazz);
B
Benjamin Pasero 已提交
165 166
	}

167
	private showGlobalActivity(globalActivityId: string, badge: IBadge, clazz?: string): IDisposable {
J
Joao Moreno 已提交
168 169 170 171 172 173 174 175 176
		if (!badge) {
			throw illegalArgument('badge');
		}

		const action = this.globalActivityIdToActions[globalActivityId];
		if (!action) {
			throw illegalArgument('globalActivityId');
		}

177
		action.setBadge(badge, clazz);
B
Benjamin Pasero 已提交
178

J
Joao Moreno 已提交
179 180 181
		return toDisposable(() => action.setBadge(undefined));
	}

B
Benjamin Pasero 已提交
182
	createContentArea(parent: HTMLElement): HTMLElement {
B
Benjamin Pasero 已提交
183 184 185
		const content = document.createElement('div');
		addClass(content, 'content');
		parent.appendChild(content);
E
Erich Gamma 已提交
186 187

		// Top Actionbar with action items for each viewlet action
B
Benjamin Pasero 已提交
188
		this.compositeBar.create(content);
E
Erich Gamma 已提交
189

190
		// Top Actionbar with action items for each viewlet action
B
Benjamin Pasero 已提交
191 192 193 194 195
		const globalActivities = document.createElement('div');
		addClass(globalActivities, 'global-activity');
		content.appendChild(globalActivities);

		this.createGlobalActivityActionBar(globalActivities);
196

B
Benjamin Pasero 已提交
197
		return content;
E
Erich Gamma 已提交
198 199
	}

B
Benjamin Pasero 已提交
200
	updateStyles(): void {
201 202 203
		super.updateStyles();

		// Part container
B
Benjamin Pasero 已提交
204
		const container = this.getContainer();
205
		const background = this.getColor(ACTIVITY_BAR_BACKGROUND);
B
Benjamin Pasero 已提交
206
		container.style.backgroundColor = background;
207

208
		const borderColor = this.getColor(ACTIVITY_BAR_BORDER) || this.getColor(contrastBorder);
209
		const isPositionLeft = this.partService.getSideBarPosition() === SideBarPosition.LEFT;
B
Benjamin Pasero 已提交
210 211 212 213 214 215 216
		container.style.boxSizing = borderColor && isPositionLeft ? 'border-box' : null;
		container.style.borderRightWidth = borderColor && isPositionLeft ? '1px' : null;
		container.style.borderRightStyle = borderColor && isPositionLeft ? 'solid' : null;
		container.style.borderRightColor = isPositionLeft ? borderColor : null;
		container.style.borderLeftWidth = borderColor && !isPositionLeft ? '1px' : null;
		container.style.borderLeftStyle = borderColor && !isPositionLeft ? 'solid' : null;
		container.style.borderLeftColor = !isPositionLeft ? borderColor : null;
217 218
	}

219 220
	private getActivitybarItemColors(theme: ITheme): ICompositeBarColors {
		return <ICompositeBarColors>{
221
			activeForegroundColor: theme.getColor(ACTIVITY_BAR_FOREGROUND),
222
			inactiveForegroundColor: theme.getColor(ACTIVITY_BAR_INACTIVE_FOREGROUND),
223 224
			badgeBackground: theme.getColor(ACTIVITY_BAR_BADGE_BACKGROUND),
			badgeForeground: theme.getColor(ACTIVITY_BAR_BADGE_FOREGROUND),
225
			dragAndDropBackground: theme.getColor(ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND),
S
Sandeep Somavarapu 已提交
226
			activeBackgroundColor: null, inactiveBackgroundColor: null, activeBorderBottomColor: null,
227 228 229
		};
	}

J
Joao Moreno 已提交
230
	private createGlobalActivityActionBar(container: HTMLElement): void {
J
Joao Moreno 已提交
231
		const activityRegistry = Registry.as<IGlobalActivityRegistry>(GlobalActivityExtensions);
232 233 234 235 236
		const descriptors = activityRegistry.getActivities();
		const actions = descriptors
			.map(d => this.instantiationService.createInstance(d))
			.map(a => new GlobalActivityAction(a));

B
Benjamin Pasero 已提交
237
		this.globalActionBar = this._register(new ActionBar(container, {
238
			actionItemProvider: a => this.instantiationService.createInstance(GlobalActivityActionItem, a, theme => this.getActivitybarItemColors(theme)),
239 240 241
			orientation: ActionsOrientation.VERTICAL,
			ariaLabel: nls.localize('globalActions', "Global Actions"),
			animated: false
B
Benjamin Pasero 已提交
242
		}));
243

J
Joao Moreno 已提交
244 245
		actions.forEach(a => {
			this.globalActivityIdToActions[a.id] = a;
246
			this.globalActionBar.push(a);
J
Joao Moreno 已提交
247
		});
248 249
	}

250 251 252
	private getCompositeActions(compositeId: string): { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } {
		let compositeActions = this.compositeActions[compositeId];
		if (!compositeActions) {
253 254 255 256 257 258 259
			const viewlet = this.viewletService.getViewlet(compositeId);
			if (viewlet) {
				compositeActions = {
					activityAction: this.instantiationService.createInstance(ViewletActivityAction, viewlet),
					pinnedAction: new ToggleCompositePinnedAction(viewlet, this.compositeBar)
				};
			} else {
S
Sandeep Somavarapu 已提交
260
				const cachedComposite = this.cachedViewlets.filter(c => c.id === compositeId)[0];
261
				compositeActions = {
R
Rob Lourens 已提交
262
					activityAction: this.instantiationService.createInstance(PlaceHolderViewletActivityAction, compositeId, cachedComposite ? URI.revive(cachedComposite.iconUrl) : undefined),
263
					pinnedAction: new PlaceHolderToggleCompositePinnedAction(compositeId, this.compositeBar)
264 265
				};
			}
B
Benjamin Pasero 已提交
266

267 268
			this.compositeActions[compositeId] = compositeActions;
		}
B
Benjamin Pasero 已提交
269

270 271 272
		return compositeActions;
	}

S
Sandeep Somavarapu 已提交
273
	private onDidRegisterViewlets(viewlets: ViewletDescriptor[]): void {
274
		for (const viewlet of viewlets) {
S
Sandeep Somavarapu 已提交
275 276 277
			const cachedViewlet = this.cachedViewlets.filter(({ id }) => id === viewlet.id)[0];
			const activeViewlet = this.viewletService.getActiveViewlet();
			const isActive = activeViewlet && activeViewlet.getId() === viewlet.id;
S
Sandeep Somavarapu 已提交
278

S
Sandeep Somavarapu 已提交
279 280
			if (isActive || !this.shouldBeHidden(viewlet.id, cachedViewlet)) {
				this.compositeBar.addComposite(viewlet);
S
Sandeep Somavarapu 已提交
281

S
Sandeep Somavarapu 已提交
282 283 284 285 286 287 288 289
				// Pin it by default if it is new
				if (!cachedViewlet) {
					this.compositeBar.pin(viewlet.id);
				}

				if (isActive) {
					this.compositeBar.activateComposite(viewlet.id);
				}
290 291 292 293
			}
		}
	}

S
Sandeep Somavarapu 已提交
294 295 296 297 298 299
	private shouldBeHidden(viewletId: string, cachedViewlet: ICachedViewlet): boolean {
		return cachedViewlet && cachedViewlet.views && cachedViewlet.views.length
			? cachedViewlet.views.every(({ when }) => when && !this.contextKeyService.contextMatchesRules(ContextKeyExpr.deserialize(when)))
			: viewletId === TEST_VIEW_CONTAINER_ID /* Hide Test viewlet for the first time or it had no views registered before */;
	}

S
Sandeep Somavarapu 已提交
300
	private removeNotExistingComposites(): void {
301
		const viewlets = this.viewletService.getViewlets();
302
		for (const { id } of this.cachedViewlets) {
303
			if (viewlets.every(viewlet => viewlet.id !== id)) {
S
Sandeep Somavarapu 已提交
304
				this.removeComposite(id, false);
305 306 307 308
			}
		}
	}

S
Sandeep Somavarapu 已提交
309 310 311 312 313 314
	private removeComposite(compositeId: string, hide: boolean): void {
		if (hide) {
			this.compositeBar.hideComposite(compositeId);
		} else {
			this.compositeBar.removeComposite(compositeId);
		}
315 316 317 318 319 320 321 322
		const compositeActions = this.compositeActions[compositeId];
		if (compositeActions) {
			compositeActions.activityAction.dispose();
			compositeActions.pinnedAction.dispose();
			delete this.compositeActions[compositeId];
		}
	}

323 324
	private enableCompositeActions(viewlet: ViewletDescriptor): void {
		const { activityAction, pinnedAction } = this.getCompositeActions(viewlet.id);
325
		if (activityAction instanceof PlaceHolderViewletActivityAction) {
S
Sandeep Somavarapu 已提交
326
			activityAction.setActivity(viewlet);
327
		}
328
		if (pinnedAction instanceof PlaceHolderToggleCompositePinnedAction) {
S
Sandeep Somavarapu 已提交
329
			pinnedAction.setActivity(viewlet);
330 331 332
		}
	}

P
Pine Wu 已提交
333 334 335 336 337 338
	getPinnedViewletIds(): string[] {
		const pinnedCompositeIds = this.compositeBar.getPinnedComposites().map(v => v.id);
		return this.viewletService.getViewlets()
			.filter(v => this.compositeBar.isPinned(v.id))
			.sort((v1, v2) => pinnedCompositeIds.indexOf(v1.id) - pinnedCompositeIds.indexOf(v2.id))
			.map(v => v.id);
339 340
	}

B
Benjamin Pasero 已提交
341
	layout(dimension: Dimension): Dimension[] {
I
isidor 已提交
342 343 344
		if (!this.partService.isVisible(Parts.ACTIVITYBAR_PART)) {
			return [dimension];
		}
345 346 347 348 349 350

		// Pass to super
		const sizes = super.layout(dimension);

		this.dimension = sizes[1];

351 352 353
		let availableHeight = this.dimension.height;
		if (this.globalActionBar) {
			// adjust height for global actions showing
I
isidor 已提交
354
			availableHeight -= (this.globalActionBar.items.length * ActivitybarPart.ACTION_HEIGHT);
355 356
		}
		this.compositeBar.layout(new Dimension(dimension.width, availableHeight));
357 358 359

		return sizes;
	}
B
Benjamin Pasero 已提交
360

361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
	private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
		if (e.key === ActivitybarPart.PINNED_VIEWLETS && e.scope === StorageScope.GLOBAL
			&& this.cachedViewletsValue !== this.getStoredCachedViewletsValue() /* This checks if current window changed the value or not */) {
			this._cachedViewletsValue = null;
			const newCompositeItems: ICompositeBarItem[] = [];
			const compositeItems = this.compositeBar.getCompositeBarItems();
			const cachedViewlets = this.getCachedViewlets();

			for (const cachedViewlet of cachedViewlets) {
				// Add and update existing items
				const existingItem = compositeItems.filter(({ id }) => id === cachedViewlet.id)[0];
				if (existingItem) {
					newCompositeItems.push({
						id: existingItem.id,
						name: existingItem.name,
						order: existingItem.order,
						pinned: cachedViewlet.pinned,
						visible: existingItem.visible
					});
				}
			}

			for (let index = 0; index < compositeItems.length; index++) {
				// Add items currently exists but does not exist in new.
				if (!newCompositeItems.some(({ id }) => id === compositeItems[index].id)) {
					newCompositeItems.splice(index, 0, compositeItems[index]);
				}
			}

			this.compositeBar.setCompositeBarItems(newCompositeItems);
		}
392 393 394
	}

	private saveCachedViewlets(): void {
S
Sandeep Somavarapu 已提交
395
		const state: ICachedViewlet[] = [];
396
		const compositeItems = this.compositeBar.getCompositeBarItems();
397
		const allViewlets = this.viewletService.getViewlets();
398 399 400 401 402 403
		for (const compositeItem of compositeItems) {
			const viewContainer = this.getViewContainer(compositeItem.id);
			const viewlet = allViewlets.filter(({ id }) => id === compositeItem.id)[0];
			if (viewlet) {
				const views: { when: string }[] = [];
				if (viewContainer) {
S
Sandeep Somavarapu 已提交
404 405 406 407 408
					const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer);
					if (viewDescriptors) {
						for (const { when } of viewDescriptors.allViewDescriptors) {
							views.push({ when: when ? when.serialize() : undefined });
						}
409
					}
S
Sandeep Somavarapu 已提交
410
				}
R
Rob Lourens 已提交
411
				state.push({ id: compositeItem.id, iconUrl: viewlet.iconUrl, views, pinned: compositeItem && compositeItem.pinned, order: compositeItem ? compositeItem.order : undefined, visible: compositeItem && compositeItem.visible });
S
Sandeep Somavarapu 已提交
412 413
			}
		}
414
		this.cachedViewletsValue = JSON.stringify(state);
415
	}
B
Benjamin Pasero 已提交
416

417 418
	private getCachedViewlets(): ICachedViewlet[] {
		const storedStates = <Array<string | ICachedViewlet>>JSON.parse(this.cachedViewletsValue);
419
		const cachedViewlets = <ICachedViewlet[]>storedStates.map(c => {
R
Rob Lourens 已提交
420
			const serialized: ICachedViewlet = typeof c === 'string' /* migration from pinned states to composites states */ ? <ICachedViewlet>{ id: c, pinned: true, order: undefined, visible: true, iconUrl: undefined, views: undefined } : c;
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
			serialized.visible = isUndefinedOrNull(serialized.visible) ? true : serialized.visible;
			return serialized;
		});
		for (const old of this.loadOldCachedViewlets()) {
			const cachedViewlet = cachedViewlets.filter(cached => cached.id === old.id)[0];
			if (cachedViewlet) {
				cachedViewlet.iconUrl = old.iconUrl;
				cachedViewlet.views = old.views;
			}
		}
		return cachedViewlets;
	}

	private loadOldCachedViewlets(): ICachedViewlet[] {
		const previousState = this.storageService.get('workbench.activity.placeholderViewlets', StorageScope.GLOBAL, '[]');
		const result = (<ICachedViewlet[]>JSON.parse(previousState));
		this.storageService.remove('workbench.activity.placeholderViewlets', StorageScope.GLOBAL);
		return result;
B
Benjamin Pasero 已提交
439
	}
S
Sandeep Somavarapu 已提交
440

441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
	private _cachedViewletsValue: string;
	private get cachedViewletsValue(): string {
		if (!this._cachedViewletsValue) {
			this._cachedViewletsValue = this.getStoredCachedViewletsValue();
		}
		return this._cachedViewletsValue;
	}

	private set cachedViewletsValue(cachedViewletsValue: string) {
		if (this.cachedViewletsValue !== cachedViewletsValue) {
			this._cachedViewletsValue = cachedViewletsValue;
			this.setStoredCachedViewletsValue(cachedViewletsValue);
		}
	}

	private getStoredCachedViewletsValue(): string {
		return this.storageService.get(ActivitybarPart.PINNED_VIEWLETS, StorageScope.GLOBAL, '[]');
	}

	private setStoredCachedViewletsValue(value: string): void {
		this.storageService.store(ActivitybarPart.PINNED_VIEWLETS, value, StorageScope.GLOBAL);
	}

S
Sandeep Somavarapu 已提交
464 465 466 467 468 469 470 471
	private getViewContainer(viewletId: string): ViewContainer | undefined {
		// TODO: @Joao Remove this after moving SCM Viewlet to ViewContainerViewlet - https://github.com/Microsoft/vscode/issues/49054
		if (viewletId === SCM_VIEWLET_ID) {
			return null;
		}
		const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
		return viewContainerRegistry.get(viewletId);
	}
472
}