add extension tips widget

This commit is contained in:
Johannes Rieken
2016-02-04 15:29:07 +01:00
parent 58f156a0ea
commit 6b2e4968f3
5 changed files with 89 additions and 15 deletions

View File

@@ -59,5 +59,5 @@ export var IExtensionTipsService = createDecorator<IExtensionTipsService>('exten
export interface IExtensionTipsService { export interface IExtensionTipsService {
serviceId: ServiceIdentifier<any>; serviceId: ServiceIdentifier<any>;
tips: IExtension[]; tips: IExtension[];
onDidChangeTips: Event<void>; onDidChangeTips: Event<IExtension[]>;
} }

View File

@@ -68,7 +68,7 @@ export class ExtensionTipsService implements IExtensionTipsService {
serviceId: any; serviceId: any;
private _onDidChangeTips: Emitter<void> = new Emitter<void>(); private _onDidChangeTips: Emitter<IExtension[]> = new Emitter<IExtension[]>();
private _tips: { [id: string]: ExtensionTip } = Object.create(null); private _tips: { [id: string]: ExtensionTip } = Object.create(null);
private _toDispose: IDisposable[] = []; private _toDispose: IDisposable[] = [];
private _availableExtensions: Promise<ExtensionMap>; private _availableExtensions: Promise<ExtensionMap>;
@@ -81,7 +81,7 @@ export class ExtensionTipsService implements IExtensionTipsService {
) { ) {
configurationService.loadConfiguration('extensions').then(value => { configurationService.loadConfiguration('extensions').then(value => {
if (value && value.enableSuggestions) { if (value && value.experimentalSuggestions === true) {
this._init(); this._init();
} }
}, onUnexpectedError); }, onUnexpectedError);
@@ -91,7 +91,7 @@ export class ExtensionTipsService implements IExtensionTipsService {
this._toDispose = disposeAll(this._toDispose); this._toDispose = disposeAll(this._toDispose);
} }
get onDidChangeTips(): Event<void> { get onDidChangeTips(): Event<IExtension[]> {
return this._onDidChangeTips.event; return this._onDidChangeTips.event;
} }
@@ -112,8 +112,12 @@ export class ExtensionTipsService implements IExtensionTipsService {
// don't suggest what got installed // don't suggest what got installed
this._toDispose.push(this._extensionService.onDidInstallExtension(ext => { this._toDispose.push(this._extensionService.onDidInstallExtension(ext => {
const id = `${ext.publisher}.${ext.name}`; const id = `${ext.publisher}.${ext.name}`;
let change = false;
if (delete this._tips[id]) { if (delete this._tips[id]) {
this._onDidChangeTips.fire(void 0); change = true;
}
if (change) {
this._onDidChangeTips.fire(this.tips);
} }
this._availableExtensions = this._getAvailableExtensions(); this._availableExtensions = this._getAvailableExtensions();
})); }));
@@ -189,19 +193,19 @@ export class ExtensionTipsService implements IExtensionTipsService {
}); });
if (change) { if (change) {
this._onDidChangeTips.fire(undefined); this._onDidChangeTips.fire(this.tips);
} }
}, onUnexpectedError); }, onUnexpectedError);
} }
private static _extensionByPattern: { [pattern: string]: string } = { private static _extensionByPattern: { [pattern: string]: string } = {
'jrieken.vscode-omnisharp': '{**/*.cs,**/project.json,**/global.json,**/*.csproj,**/*.sln}', 'jrieken.vscode-omnisharp': '{**/*.cs,**/project.json,**/global.json,**/*.csproj,**/*.sln}',
'eg2.tslint': '**/*.ts', 'msjsdiag.debugger-for-chrome': '{**/*.ts,**/*.tsx**/*.js,**/*.jsx,**/*.es6}',
'dbaeumer.vscode-eslint': '{**/*.js,**/*.es6}', 'lukehoban.Go': '**/*.go',
'mkaufman.HTMLHint': '{**/*.html,**/*.htm}', 'ms-vscode.PowerShell': '{**/*.ps,**/*.ps1}',
'seanmcbreen.Spell': '**/*.md', 'austin.code-gnu-global': '{**/*.c,**/*.cpp,**/*.h}',
'ms-vscode.jscs': '{**/*.js,**/*.es6}', 'Ionide.Ionide-fsharp': '{**/*.fsx,**/*.fsi,**/*.fs,**/*.ml,**/*.mli}',
'ms-vscode.wordcount': '**/*.md', 'dbaeumer.vscode-eslint': '{**/*.js,**/*.jsx,**/*.es6}',
'Ionide.Ionide-fsharp': '{**/*.fsx,**/*.fsi,**/*.fs,**/*.ml,**/*.mli}' 'eg2.tslint': '{**/*.ts,**/*.tsx}'
} }
} }

View File

@@ -6,7 +6,7 @@
import platform = require('vs/platform/platform'); import platform = require('vs/platform/platform');
import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import statusbar = require('vs/workbench/browser/parts/statusbar/statusbar'); import statusbar = require('vs/workbench/browser/parts/statusbar/statusbar');
import { ExtensionsStatusbarItem } from 'vs/workbench/parts/extensions/electron-browser/extensionsWidgets'; import { ExtensionsStatusbarItem, ExtensionTipsStatusbarItem } from 'vs/workbench/parts/extensions/electron-browser/extensionsWidgets';
import { IGalleryService } from 'vs/workbench/parts/extensions/common/extensions'; import { IGalleryService } from 'vs/workbench/parts/extensions/common/extensions';
import { GalleryService } from 'vs/workbench/parts/extensions/node/vsoGalleryService'; import { GalleryService } from 'vs/workbench/parts/extensions/node/vsoGalleryService';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
@@ -26,3 +26,10 @@ registerSingleton(IGalleryService, GalleryService);
statusbar.StatusbarAlignment.LEFT, statusbar.StatusbarAlignment.LEFT,
10 /* Low Priority */ 10 /* Low Priority */
)); ));
// Register Statusbar item
(<statusbar.IStatusbarRegistry>platform.Registry.as(statusbar.Extensions.Statusbar)).registerStatusbarItem(new statusbar.StatusbarItemDescriptor(
ExtensionTipsStatusbarItem,
statusbar.StatusbarAlignment.LEFT,
9 /* Low Priority */
));

View File

@@ -15,7 +15,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IMessageService, CloseAction } from 'vs/platform/message/common/message'; import { IMessageService, CloseAction } from 'vs/platform/message/common/message';
import { UninstallAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; import { UninstallAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions';
import { IQuickOpenService } from 'vs/workbench/services/quickopen/common/quickOpenService'; import { IQuickOpenService } from 'vs/workbench/services/quickopen/common/quickOpenService';
import { IExtensionsService, IGalleryService, IExtension } from 'vs/workbench/parts/extensions/common/extensions'; import { IExtensionsService, IGalleryService, IExtension, IExtensionTipsService } from 'vs/workbench/parts/extensions/common/extensions';
import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel';
var $ = dom.emmet; var $ = dom.emmet;
@@ -83,3 +84,49 @@ export class ExtensionsStatusbarItem implements statusbar.IStatusbarItem {
}; };
} }
} }
export class ExtensionTipsStatusbarItem implements statusbar.IStatusbarItem {
private _domNode: HTMLElement;
private _label: OcticonLabel;
private _prevTips: IExtension[] = [];
constructor(
@IQuickOpenService private _quickOpenService: IQuickOpenService,
@IExtensionTipsService private _extensionTipsService: IExtensionTipsService
) {
this._extensionTipsService.onDidChangeTips(tips => {
// check for new tips
let hasNewTips = false;
for (let tip of tips) {
if (this._prevTips.indexOf(tip) < 0) {
this._prevTips.push(tip);
hasNewTips = true;
}
}
if (hasNewTips) {
dom.addClass(this._domNode, 'active');
}
// only keep 10 tips
while (this._prevTips.length > 10) {
this._prevTips.shift();
}
});
}
public render(container: HTMLElement): lifecycle.IDisposable {
this._domNode = document.createElement('a');
this._domNode.className = 'extensions-suggestions';
this._label = new OcticonLabel(this._domNode);
this._label.text = '$(light-bulb) extension tips';
container.appendChild(this._domNode);
return dom.addDisposableListener(this._domNode, 'click', event => this._onClick(event));
}
private _onClick(event: MouseEvent): void {
this._quickOpenService.show('ext tips ').then(() => dom.removeClass(this._domNode, 'active'));
}
}

View File

@@ -132,3 +132,19 @@
background-size: 14px; background-size: 14px;
background-position: 4px 50%; background-position: 4px 50%;
} }
.monaco-shell .extensions-suggestions {
visibility: hidden;
padding: 0 5px 0 5px;
-webkit-transition: visibility 250ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
transition: visibility 250ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.monaco-shell .extensions-suggestions.active {
visibility: inherit;
background-color: rgba(76, 119, 76, 0.9);
}
.monaco-shell .extensions-suggestions > .octicon {
font-size: 14px;
}