mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-23 07:16:29 +01:00
simple ext tips, contexts in extension viewlet
This commit is contained in:
@@ -200,7 +200,7 @@ export const IExtensionTipsService = createDecorator<IExtensionTipsService>('ext
|
||||
|
||||
export interface IExtensionTipsService {
|
||||
_serviceBrand: any;
|
||||
getRecommendations(): TPromise<IGalleryExtension[]>;
|
||||
getRecommendations(): string[];
|
||||
}
|
||||
|
||||
export const ExtensionsLabel = nls.localize('extensions', "Extensions");
|
||||
|
||||
@@ -10,7 +10,7 @@ import {IDisposable, dispose} from 'vs/base/common/lifecycle';
|
||||
import {TPromise as Promise} from 'vs/base/common/winjs.base';
|
||||
import {Action} from 'vs/base/common/actions';
|
||||
import {match} from 'vs/base/common/glob';
|
||||
import {IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, IGalleryExtension} from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import {IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService} from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import {IModelService} from 'vs/editor/common/services/modelService';
|
||||
import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage';
|
||||
import product from 'vs/platform/product';
|
||||
@@ -72,15 +72,8 @@ export class ExtensionTipsService implements IExtensionTipsService {
|
||||
this._modelService.getModels().forEach(model => this._suggest(model.uri));
|
||||
}
|
||||
|
||||
getRecommendations(): Promise<IGalleryExtension[]> {
|
||||
const names = Object.keys(this._recommendations);
|
||||
|
||||
if (names.length === 0) {
|
||||
return Promise.as([]);
|
||||
}
|
||||
|
||||
return this._galleryService.query({ names, pageSize: names.length })
|
||||
.then(result => result.firstPage, () => []);
|
||||
getRecommendations(): string[] {
|
||||
return Object.keys(this._recommendations);
|
||||
}
|
||||
|
||||
private _suggest(uri: URI): Promise<any> {
|
||||
|
||||
@@ -54,7 +54,6 @@ export interface IExtensionsWorkbenchService {
|
||||
local: IExtension[];
|
||||
queryLocal(): TPromise<IExtension[]>;
|
||||
queryGallery(options?: IQueryOptions): TPromise<IPager<IExtension>>;
|
||||
getRecommendations(): TPromise<IExtension[]>;
|
||||
canInstall(extension: IExtension): boolean;
|
||||
install(extension: IExtension): TPromise<void>;
|
||||
uninstall(extension: IExtension): TPromise<void>;
|
||||
|
||||
@@ -19,14 +19,14 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Viewlet } from 'vs/workbench/browser/viewlet';
|
||||
import { append, $, addStandardDisposableListener, EventType, addClass, removeClass, toggleClass } from 'vs/base/browser/dom';
|
||||
import { IPager, PagedModel } from 'vs/base/common/paging';
|
||||
import { PagedModel } from 'vs/base/common/paging';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { PagedList } from 'vs/base/browser/ui/list/listPaging';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Delegate, Renderer } from './extensionsList';
|
||||
import { IExtensionsWorkbenchService, IExtension, IExtensionsViewlet, VIEWLET_ID } from './extensions';
|
||||
import { ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowInstalledExtensionsAction, ShowOutdatedExtensionsAction, ClearExtensionsInputAction } from './extensionsActions';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, SortBy } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, SortBy, IQueryOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionsInput } from './extensionsInput';
|
||||
import { IProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
@@ -38,6 +38,54 @@ interface SearchInputEvent extends Event {
|
||||
immediate?: boolean;
|
||||
}
|
||||
|
||||
interface IContext {
|
||||
query(): TPromise<PagedModel<IExtension>>;
|
||||
}
|
||||
|
||||
class LocalContext implements IContext {
|
||||
|
||||
constructor(private value: string, private extensionsWorkbenchService: IExtensionsWorkbenchService) {}
|
||||
|
||||
query(): TPromise<PagedModel<IExtension>> {
|
||||
let local = this.extensionsWorkbenchService.queryLocal();
|
||||
|
||||
if (/@outdated/i.test(this.value)) {
|
||||
local = local.then(result => result.filter(e => e.outdated));
|
||||
}
|
||||
|
||||
return local.then(result => new PagedModel(result));
|
||||
}
|
||||
}
|
||||
|
||||
class GalleryContext implements IContext {
|
||||
|
||||
constructor(
|
||||
private value: string,
|
||||
private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
private tipsService: IExtensionTipsService
|
||||
) {}
|
||||
|
||||
query(): TPromise<PagedModel<IExtension>> {
|
||||
let options: TPromise<IQueryOptions> = null;
|
||||
|
||||
if (/@popular/i.test(this.value)) {
|
||||
options = TPromise.as({ sortBy: SortBy.InstallCount });
|
||||
} else if (/@recommended/i.test(this.value)) {
|
||||
options = this.extensionsWorkbenchService.queryLocal().then(local => {
|
||||
const names = this.tipsService.getRecommendations()
|
||||
.filter(name => local.every(ext => `${ ext.publisher }.${ ext.name }` !== name));
|
||||
|
||||
return { names, pageSize: names.length };
|
||||
});
|
||||
} else {
|
||||
options = TPromise.as({ text: this.value });
|
||||
}
|
||||
|
||||
return this.extensionsWorkbenchService.queryGallery(options)
|
||||
.then(result => new PagedModel(result));
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
|
||||
|
||||
private onSearchChange: EventOf<string>;
|
||||
@@ -58,7 +106,8 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IURLService urlService: IURLService
|
||||
@IURLService urlService: IURLService,
|
||||
@IExtensionTipsService private tipsService: IExtensionTipsService
|
||||
) {
|
||||
super(VIEWLET_ID, telemetryService);
|
||||
this.searchDelayer = new ThrottledDelayer(500);
|
||||
@@ -172,35 +221,25 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
|
||||
}
|
||||
|
||||
private doSearch(value: string = '', suggestPopular = false): TPromise<any> {
|
||||
const progressRunner = this.progressService.show(true);
|
||||
let promise: TPromise<IPager<IExtension> | IExtension[]>;
|
||||
const context = this.getContext(value);
|
||||
const promise = this.progress(context.query());
|
||||
|
||||
if (!value) {
|
||||
promise = this.extensionsWorkbenchService.queryLocal()
|
||||
.then(result => {
|
||||
if (result.length === 0 && suggestPopular) {
|
||||
this.search('@popular', true);
|
||||
}
|
||||
return promise.then(model => {
|
||||
if (context instanceof LocalContext && model.length === 0 && suggestPopular) {
|
||||
return this.search('@popular', true);
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
} else if (/@outdated/i.test(value)) {
|
||||
promise = this.extensionsWorkbenchService.queryLocal()
|
||||
.then(result => result.filter(e => e.outdated));
|
||||
} else if (/@popular/i.test(value)) {
|
||||
promise = this.extensionsWorkbenchService.queryGallery({ sortBy: SortBy.InstallCount });
|
||||
} else if (/@recommended/i.test(value)) {
|
||||
promise = this.extensionsWorkbenchService.getRecommendations();
|
||||
this.list.model = model;
|
||||
this.list.scrollTop = 0;
|
||||
});
|
||||
}
|
||||
|
||||
private getContext(value: string): IContext {
|
||||
if (!value || /@outdated/i.test(value)) {
|
||||
return new LocalContext(value, this.extensionsWorkbenchService);
|
||||
} else {
|
||||
promise = this.extensionsWorkbenchService.queryGallery({ text: value });
|
||||
return new GalleryContext(value, this.extensionsWorkbenchService, this.tipsService);
|
||||
}
|
||||
|
||||
return always(promise, () => progressRunner.done())
|
||||
.then(result => new PagedModel<IExtension>(result))
|
||||
.then(model => {
|
||||
this.list.model = model;
|
||||
this.list.scrollTop = 0;
|
||||
});
|
||||
}
|
||||
|
||||
private openExtension(extension: IExtension): void {
|
||||
@@ -256,6 +295,11 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
|
||||
});
|
||||
}
|
||||
|
||||
private progress<T>(promise: TPromise<T>): TPromise<T> {
|
||||
const progressRunner = this.progressService.show(true);
|
||||
return always(promise, () => progressRunner.done());
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables = dispose(this.disposables);
|
||||
super.dispose();
|
||||
|
||||
@@ -14,7 +14,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IPager, mapPager, singlePagePager } from 'vs/base/common/paging';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, ILocalExtension, IGalleryExtension, IQueryOptions, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionTelemetry';
|
||||
import * as semver from 'semver';
|
||||
import * as path from 'path';
|
||||
@@ -217,8 +217,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
constructor(
|
||||
@IExtensionManagementService private extensionService: IExtensionManagementService,
|
||||
@IExtensionGalleryService private galleryService: IExtensionGalleryService,
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@IExtensionTipsService private tipsService: IExtensionTipsService
|
||||
@ITelemetryService private telemetryService: ITelemetryService
|
||||
) {
|
||||
this.stateProvider = ext => this.getExtensionState(ext);
|
||||
|
||||
@@ -267,14 +266,6 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
});
|
||||
}
|
||||
|
||||
getRecommendations(): TPromise<IExtension[]> {
|
||||
return this.tipsService.getRecommendations()
|
||||
.then(result => result
|
||||
.map(gallery => this.fromGallery(gallery))
|
||||
.filter(extension => extension.state === ExtensionState.Uninstalled)
|
||||
);
|
||||
}
|
||||
|
||||
private fromGallery(gallery: IGalleryExtension): Extension {
|
||||
const installedByGalleryId = index(this.installed, e => e.local.metadata ? e.local.metadata.id : '');
|
||||
const id = gallery.id;
|
||||
|
||||
Reference in New Issue
Block a user