mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-25 11:08:51 +01:00
add extension tips widget
This commit is contained in:
@@ -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[]>;
|
||||||
}
|
}
|
||||||
@@ -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}'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
));
|
||||||
@@ -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'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user