extensionsViewlet.ts 4.2 KB
Newer Older
J
Joao Moreno 已提交
1 2 3 4 5 6 7 8
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

import 'vs/css!./media/extensions-viewlet';
J
Joao Moreno 已提交
9 10
import { localize } from 'vs/nls';
import { ThrottledDelayer, always } from 'vs/base/common/async';
J
Joao Moreno 已提交
11 12 13 14
import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Builder, Dimension } from 'vs/base/browser/builder';
import { Viewlet } from 'vs/workbench/browser/viewlet';
J
Joao Moreno 已提交
15
import { append, emmet as $ } from 'vs/base/browser/dom';
J
Joao Moreno 已提交
16
import { PagedModel, mapPager } from 'vs/base/common/paging';
J
Joao Moreno 已提交
17
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
J
Joao Moreno 已提交
18 19 20 21
import { PagedList } from 'vs/base/browser/ui/list/listPaging';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IExtensionEntry, Delegate, Renderer, ExtensionState } from './extensionsList';
import { IGalleryService } from '../common/extensions';
J
Joao Moreno 已提交
22
import { ExtensionsInput } from '../common/extensionsInput';
J
Joao Moreno 已提交
23
import { IProgressService } from 'vs/platform/progress/common/progress';
J
Joao Moreno 已提交
24
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
J
Joao Moreno 已提交
25 26 27 28 29 30 31

const EmptyModel = new PagedModel({
	firstPage: [],
	total: 0,
	pageSize: 0,
	getPage: null
});
J
Joao Moreno 已提交
32 33 34 35 36

export class ExtensionsViewlet extends Viewlet {

	static ID: string = 'workbench.viewlet.extensions';

J
Joao Moreno 已提交
37
	private disposables: IDisposable[];
J
Joao Moreno 已提交
38
	private searchDelayer: ThrottledDelayer<any>;
J
Joao Moreno 已提交
39
	private root: HTMLElement;
J
Joao Moreno 已提交
40 41 42
	private searchBox: HTMLInputElement;
	private extensionsBox: HTMLElement;
	private list: PagedList<IExtensionEntry>;
J
Joao Moreno 已提交
43

J
Joao Moreno 已提交
44 45 46
	constructor(
		@ITelemetryService telemetryService: ITelemetryService,
		@IGalleryService private galleryService: IGalleryService,
J
Joao Moreno 已提交
47
		@IProgressService private progressService: IProgressService,
J
Joao Moreno 已提交
48 49
		@IInstantiationService private instantiationService: IInstantiationService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
J
Joao Moreno 已提交
50
	) {
J
Joao Moreno 已提交
51
		super(ExtensionsViewlet.ID, telemetryService);
J
Joao Moreno 已提交
52
		this.searchDelayer = new ThrottledDelayer(500);
J
Joao Moreno 已提交
53
		this.disposables = [];
J
Joao Moreno 已提交
54 55 56 57
	}

	create(parent: Builder): TPromise<void> {
		super.create(parent);
J
Joao Moreno 已提交
58 59 60 61 62 63 64 65 66 67 68
		parent.addClass('extensions-viewlet');
		this.root = parent.getHTMLElement();

		const search = append(this.root, $('.search'));
		this.searchBox = append(search, $<HTMLInputElement>('input.search-box'));
		this.searchBox.placeholder = localize('searchExtensions', "Search Extensions");
		this.extensionsBox = append(this.root, $('.extensions'));

		const delegate = new Delegate();
		const renderer = this.instantiationService.createInstance(Renderer);
		this.list = new PagedList(this.extensionsBox, delegate, [renderer]);
J
Joao Moreno 已提交
69

J
Joao Moreno 已提交
70
		this.searchBox.oninput = () => this.triggerSearch(this.searchBox.value);
J
Joao Moreno 已提交
71

J
Joao Moreno 已提交
72 73 74 75 76 77 78
		this.list.onSelectionChange(e => {
			const [entry] = e.elements;

			if (!entry) {
				return;
			}

J
Joao Moreno 已提交
79
			return this.editorService.openEditor(new ExtensionsInput(entry.extension));
J
Joao Moreno 已提交
80 81
		}, null, this.disposables);

J
Joao Moreno 已提交
82 83 84 85
		return TPromise.as(null);
	}

	setVisible(visible:boolean): TPromise<void> {
J
Joao Moreno 已提交
86 87 88 89 90 91
		return super.setVisible(visible).then(() => {
			if (visible) {
				this.searchBox.value = '';
				this.triggerSearch('', 0);
			}
		});
J
Joao Moreno 已提交
92 93 94
	}

	focus(): void {
J
Joao Moreno 已提交
95
		this.searchBox.focus();
J
Joao Moreno 已提交
96 97
	}

J
Joao Moreno 已提交
98
	layout({ height }: Dimension):void {
J
Joao Moreno 已提交
99
		this.list.layout(height - 38);
J
Joao Moreno 已提交
100 101 102 103 104 105 106
	}

	private triggerSearch(text: string = '', delay = 500): void {
		this.list.model = EmptyModel;

		const promise = this.searchDelayer.trigger(() => this.doSearch(text), delay);

J
Joao Moreno 已提交
107 108
		const progressRunner = this.progressService.show(true);
		always(promise, () => progressRunner.done());
J
Joao Moreno 已提交
109 110 111 112 113 114
	}

	private doSearch(text: string = ''): TPromise<any> {
		return this.galleryService.query({ text })
			.then(result => new PagedModel(mapPager(result, extension => ({ extension, state: ExtensionState.Installed }))))
			.then(model => this.list.model = model);
J
Joao Moreno 已提交
115 116 117
	}

	dispose(): void {
J
Joao Moreno 已提交
118
		this.disposables = dispose(this.disposables);
J
Joao Moreno 已提交
119 120 121
		super.dispose();
	}
}