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();
S
Sandeep Somavarapu 已提交
96
		this.onDidRegisterViewlets(viewletService.getAllViewlets());
E
Erich Gamma 已提交
97 98 99
	}

	private registerListeners(): void {
100

S
Sandeep Somavarapu 已提交
101
		this._register(this.viewletService.onDidViewletRegister(viewlet => this.onDidRegisterViewlets([viewlet])));
102

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

		// Deactivate viewlet action on close
B
Benjamin Pasero 已提交
107 108
		this._register(this.viewletService.onDidViewletClose(viewlet => this.compositeBar.deactivateComposite(viewlet.getId())));
		this._register(this.viewletService.onDidViewletEnablementChange(({ id, enabled }) => {
109
			if (enabled) {
S
Sandeep Somavarapu 已提交
110
				this.compositeBar.addComposite(this.viewletService.getViewlet(id));
111
			} else {
S
Sandeep Somavarapu 已提交
112
				this.removeComposite(id, true);
113 114
			}
		}));
B
Benjamin Pasero 已提交
115

116 117 118 119 120 121 122 123
		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 已提交
124 125
	}

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

	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 已提交
149
		// Update the composite bar by adding
S
Sandeep Somavarapu 已提交
150 151
		this.compositeBar.addComposite(this.viewletService.getViewlet(viewlet.getId()));
		this.compositeBar.activateComposite(viewlet.getId());
S
Sandeep Somavarapu 已提交
152 153 154 155 156 157
		const viewletDescriptor = this.viewletService.getViewlet(viewlet.getId());
		const viewContainer = this.getViewContainer(viewletDescriptor.id);
		if (viewContainer && this.viewsService.getViewDescriptors(viewContainer).activeViewDescriptors.length === 0) {
			// Update the composite bar by hiding
			this.removeComposite(viewletDescriptor.id, true);
		}
E
Erich Gamma 已提交
158 159
	}

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

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

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

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

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

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

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

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

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

		this.createGlobalActivityActionBar(globalActivities);
197

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

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

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

209
		const borderColor = this.getColor(ACTIVITY_BAR_BORDER) || this.getColor(contrastBorder);
210
		const isPositionLeft = this.partService.getSideBarPosition() === SideBarPosition.LEFT;
B
Benjamin Pasero 已提交
211 212 213 214 215 216 217
		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;
218 219
	}

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

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

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

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

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

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

271 272 273
		return compositeActions;
	}

S
Sandeep Somavarapu 已提交
274
	private onDidRegisterViewlets(viewlets: ViewletDescriptor[]): void {
275
		for (const viewlet of viewlets) {
S
Sandeep Somavarapu 已提交
276 277 278
			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 已提交
279

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

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

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

S
Sandeep Somavarapu 已提交
295 296 297 298 299 300
	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 已提交
301 302
	private removeNotExistingComposites(): void {
		const viewlets = this.viewletService.getAllViewlets();
303
		for (const { id } of this.cachedViewlets) {
304
			if (viewlets.every(viewlet => viewlet.id !== id)) {
S
Sandeep Somavarapu 已提交
305
				this.removeComposite(id, false);
306 307 308 309
			}
		}
	}

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

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

P
Pine Wu 已提交
334 335 336 337 338 339
	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);
340 341
	}

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

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

		this.dimension = sizes[1];

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

		return sizes;
	}
B
Benjamin Pasero 已提交
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 392
	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);
		}
393 394 395
	}

	private saveCachedViewlets(): void {
S
Sandeep Somavarapu 已提交
396
		const state: ICachedViewlet[] = [];
397
		const compositeItems = this.compositeBar.getCompositeBarItems();
398 399 400 401 402 403 404 405
		const allViewlets = this.viewletService.getAllViewlets();
		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) {
					for (const { when } of this.viewsService.getViewDescriptors(viewContainer).allViewDescriptors) {
R
Rob Lourens 已提交
406
						views.push({ when: when ? when.serialize() : undefined });
407
					}
S
Sandeep Somavarapu 已提交
408
				}
R
Rob Lourens 已提交
409
				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 已提交
410 411
			}
		}
412
		this.cachedViewletsValue = JSON.stringify(state);
413
	}
B
Benjamin Pasero 已提交
414

415 416
	private getCachedViewlets(): ICachedViewlet[] {
		const storedStates = <Array<string | ICachedViewlet>>JSON.parse(this.cachedViewletsValue);
417
		const cachedViewlets = <ICachedViewlet[]>storedStates.map(c => {
R
Rob Lourens 已提交
418
			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;
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
			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 已提交
437
	}
S
Sandeep Somavarapu 已提交
438

439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
	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 已提交
462 463 464 465 466 467 468 469
	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);
	}
470
}