提交 9a3b1b4a 编写于 作者: B Benjamin Pasero

notifications - first cut keybindings support with commands

上级 4eb771bf
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .close-notification-action { .vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .clear-notification-action {
background-image: url('close.svg'); background-image: url('close.svg');
} }
.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .close-notification-action, .vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .clear-notification-action,
.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .close-notification-action { .hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .clear-notification-action {
background-image: url('close-inverse.svg'); background-image: url('close-inverse.svg');
} }
......
...@@ -7,28 +7,167 @@ ...@@ -7,28 +7,167 @@
import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
import { RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { INotificationViewItem, isNotificationViewItem } from 'vs/workbench/common/notifications';
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
import { localize } from 'vs/nls';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
export const SHOW_NOTFICATIONS_CENTER_COMMAND_ID = 'notificationsCenter.show'; export const SHOW_NOTFICATIONS_CENTER_COMMAND_ID = 'notifications.show';
export const HIDE_NOTFICATIONS_CENTER_COMMAND_ID = 'notificationsCenter.hide'; export const HIDE_NOTFICATIONS_CENTER_COMMAND_ID = 'notifications.hide';
export const TOGGLE_NOTFICATIONS_CENTER_COMMAND_ID = 'notificationsCenter.toggle'; export const TOGGLE_NOTFICATIONS_CENTER_COMMAND_ID = 'notifications.toggle';
export const COLLAPSE_NOTIFICATION = 'notification.collapse';
export const EXPAND_NOTIFICATION = 'notification.expand';
export const TOGGLE_NOTIFICATION = 'notification.toggle';
export const CLEAR_NOTFICATION = 'notification.clear';
export const CLEAR_ALL_NOTFICATIONS = 'notifications.clearAll';
const notificationsCenterFocusedId = 'notificationsCenterFocus';
export const NotificationsCenterFocusedContext = new RawContextKey<boolean>(notificationsCenterFocusedId, true);
const notificationsCenterVisibleId = 'notificationsCenterVisible';
export const NotificationsCenterVisibleContext = new RawContextKey<boolean>(notificationsCenterVisibleId, false);
export const InNotificationsCenterContext = ContextKeyExpr.and(ContextKeyExpr.has(notificationsCenterFocusedId), ContextKeyExpr.has(notificationsCenterVisibleId));
export interface INotificationsCenterController { export interface INotificationsCenterController {
isVisible: boolean; readonly isVisible: boolean;
readonly selected: INotificationViewItem;
show(): void; show(): void;
hide(): void; hide(): void;
clearAll(): void;
} }
export function registerNotificationCommands(center: INotificationsCenterController): void { export function registerNotificationCommands(center: INotificationsCenterController): void {
// Show Center function showCenter(): void {
CommandsRegistry.registerCommand(SHOW_NOTFICATIONS_CENTER_COMMAND_ID, () => center.show()); center.show();
}
function hideCenter(accessor: ServicesAccessor): void {
// Hide center
center.hide();
// Restore focus if we got an editor
const editor = accessor.get(IWorkbenchEditorService).getActiveEditor();
if (editor) {
editor.focus();
}
}
// Show Notifications Cneter
CommandsRegistry.registerCommand(SHOW_NOTFICATIONS_CENTER_COMMAND_ID, () => showCenter());
// Hide Notifications Center
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: HIDE_NOTFICATIONS_CENTER_COMMAND_ID,
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: InNotificationsCenterContext,
primary: KeyCode.Escape,
handler: accessor => hideCenter(accessor)
});
// Toggle Notifications Center
CommandsRegistry.registerCommand(TOGGLE_NOTFICATIONS_CENTER_COMMAND_ID, accessor => center.isVisible ? hideCenter(accessor) : showCenter());
// Clear Notification
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: CLEAR_NOTFICATION,
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: InNotificationsCenterContext,
primary: KeyCode.Delete,
mac: {
primary: KeyMod.CtrlCmd | KeyCode.Backspace
},
handler: (accessor, args?: any) => {
let notification: INotificationViewItem;
if (isNotificationViewItem(args)) {
notification = args;
} else {
notification = center.selected;
}
if (notification) {
notification.dispose();
}
}
});
// Expand Notification
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: EXPAND_NOTIFICATION,
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: InNotificationsCenterContext,
primary: KeyCode.RightArrow,
handler: (accessor, args?: any) => {
let notification: INotificationViewItem;
if (isNotificationViewItem(args)) {
notification = args;
} else {
notification = center.selected;
}
if (notification) {
notification.expand();
}
}
});
// Collapse Notification
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: COLLAPSE_NOTIFICATION,
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: InNotificationsCenterContext,
primary: KeyCode.LeftArrow,
handler: (accessor, args?: any) => {
let notification: INotificationViewItem;
if (isNotificationViewItem(args)) {
notification = args;
} else {
notification = center.selected;
}
if (notification) {
notification.collapse();
}
}
});
// Toggle Notification
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: TOGGLE_NOTIFICATION,
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: InNotificationsCenterContext,
primary: KeyCode.Space,
handler: accessor => {
const notification = center.selected;
if (notification) {
if (notification.expanded) {
notification.collapse();
} else {
notification.expand();
}
}
}
});
/// Clear All Notifications
CommandsRegistry.registerCommand(CLEAR_ALL_NOTFICATIONS, () => center.clearAll());
// Commands for Command Palette
const category = localize('notifications', "Notifications");
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: SHOW_NOTFICATIONS_CENTER_COMMAND_ID, title: localize('showNotifications', "Show Notifications"), category }, when: NotificationsCenterVisibleContext.toNegated() });
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: HIDE_NOTFICATIONS_CENTER_COMMAND_ID, title: localize('hideNotifications', "Hide Notifications"), category }, when: NotificationsCenterVisibleContext });
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: CLEAR_ALL_NOTFICATIONS, title: localize('clearAllNotifications', "Clear All Notifications"), category } });
// Hide Center
CommandsRegistry.registerCommand(HIDE_NOTFICATIONS_CENTER_COMMAND_ID, () => center.hide());
// Toggle Center
CommandsRegistry.registerCommand(TOGGLE_NOTFICATIONS_CENTER_COMMAND_ID, () => center.isVisible ? center.hide() : center.show());
// TODO@Notification remove me // TODO@Notification remove me
CommandsRegistry.registerCommand('notifications.showInfo', accessor => { CommandsRegistry.registerCommand('notifications.showInfo', accessor => {
......
...@@ -12,21 +12,24 @@ import { Action, IAction, ActionRunner } from 'vs/base/common/actions'; ...@@ -12,21 +12,24 @@ import { Action, IAction, ActionRunner } from 'vs/base/common/actions';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
import { CLEAR_NOTFICATION, EXPAND_NOTIFICATION, COLLAPSE_NOTIFICATION } from 'vs/workbench/browser/parts/notifications/notificationCommands';
import { ICommandService } from 'vs/platform/commands/common/commands';
export class CloseNotificationAction extends Action { export class ClearNotificationAction extends Action {
public static readonly ID = 'workbench.action.closeNotification'; public static readonly ID = CLEAR_NOTFICATION;
public static readonly LABEL = localize('closeNotification', "Close Notification"); public static readonly LABEL = localize('closeNotification', "Close Notification");
constructor( constructor(
id: string, id: string,
label: string label: string,
@ICommandService private commandService: ICommandService
) { ) {
super(id, label, 'close-notification-action'); super(id, label, 'clear-notification-action');
} }
public run(notification: INotificationViewItem): TPromise<any> { public run(notification: INotificationViewItem): TPromise<any> {
notification.dispose(); this.commandService.executeCommand(CLEAR_NOTFICATION, notification);
return TPromise.as(void 0); return TPromise.as(void 0);
} }
...@@ -34,18 +37,19 @@ export class CloseNotificationAction extends Action { ...@@ -34,18 +37,19 @@ export class CloseNotificationAction extends Action {
export class ExpandNotificationAction extends Action { export class ExpandNotificationAction extends Action {
public static readonly ID = 'workbench.action.expandNotification'; public static readonly ID = EXPAND_NOTIFICATION;
public static readonly LABEL = localize('expandNotification', "Expand Notification"); public static readonly LABEL = localize('expandNotification', "Expand Notification");
constructor( constructor(
id: string, id: string,
label: string label: string,
@ICommandService private commandService: ICommandService
) { ) {
super(id, label, 'expand-notification-action'); super(id, label, 'expand-notification-action');
} }
public run(notification: INotificationViewItem): TPromise<any> { public run(notification: INotificationViewItem): TPromise<any> {
notification.expand(); this.commandService.executeCommand(EXPAND_NOTIFICATION, notification);
return TPromise.as(void 0); return TPromise.as(void 0);
} }
...@@ -53,18 +57,19 @@ export class ExpandNotificationAction extends Action { ...@@ -53,18 +57,19 @@ export class ExpandNotificationAction extends Action {
export class CollapseNotificationAction extends Action { export class CollapseNotificationAction extends Action {
public static readonly ID = 'workbench.action.collapseNotification'; public static readonly ID = COLLAPSE_NOTIFICATION;
public static readonly LABEL = localize('collapseNotification', "Collapse Notification"); public static readonly LABEL = localize('collapseNotification', "Collapse Notification");
constructor( constructor(
id: string, id: string,
label: string label: string,
@ICommandService private commandService: ICommandService
) { ) {
super(id, label, 'collapse-notification-action'); super(id, label, 'collapse-notification-action');
} }
public run(notification: INotificationViewItem): TPromise<any> { public run(notification: INotificationViewItem): TPromise<any> {
notification.collapse(); this.commandService.executeCommand(COLLAPSE_NOTIFICATION, notification);
return TPromise.as(void 0); return TPromise.as(void 0);
} }
......
...@@ -20,6 +20,8 @@ import { NotificationActionRunner } from 'vs/workbench/browser/parts/notificatio ...@@ -20,6 +20,8 @@ import { NotificationActionRunner } from 'vs/workbench/browser/parts/notificatio
import { Dimension } from 'vs/base/browser/builder'; import { Dimension } from 'vs/base/browser/builder';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
import Event, { Emitter } from 'vs/base/common/event'; import Event, { Emitter } from 'vs/base/common/event';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { NotificationsCenterFocusedContext, NotificationsCenterVisibleContext } from 'vs/workbench/browser/parts/notifications/notificationCommands';
export class NotificationsCenter extends Themable { export class NotificationsCenter extends Themable {
...@@ -31,19 +33,23 @@ export class NotificationsCenter extends Themable { ...@@ -31,19 +33,23 @@ export class NotificationsCenter extends Themable {
private _isVisible: boolean; private _isVisible: boolean;
private workbenchDimensions: Dimension; private workbenchDimensions: Dimension;
private _onDidChangeVisibility: Emitter<void>; private _onDidChangeVisibility: Emitter<void>;
private notificationsCenterVisibleContextKey: IContextKey<boolean>;
constructor( constructor(
private container: HTMLElement, private container: HTMLElement,
private model: INotificationsModel, private model: INotificationsModel,
@IInstantiationService private instantiationService: IInstantiationService, @IInstantiationService private instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService, @IThemeService themeService: IThemeService,
@IPartService private partService: IPartService @IPartService private partService: IPartService,
@IContextKeyService contextKeyService: IContextKeyService
) { ) {
super(themeService); super(themeService);
this._onDidChangeVisibility = new Emitter<void>(); this._onDidChangeVisibility = new Emitter<void>();
this.toUnbind.push(this._onDidChangeVisibility); this.toUnbind.push(this._onDidChangeVisibility);
this.notificationsCenterVisibleContextKey = NotificationsCenterVisibleContext.bindTo(contextKeyService);
this.viewModel = []; this.viewModel = [];
this.registerListeners(); this.registerListeners();
} }
...@@ -56,6 +62,16 @@ export class NotificationsCenter extends Themable { ...@@ -56,6 +62,16 @@ export class NotificationsCenter extends Themable {
return this._isVisible; return this._isVisible;
} }
public get selected(): INotificationViewItem {
if (!this._isVisible || !this.list) {
return null;
}
const focusedIndex = this.list.getFocus()[0];
return this.viewModel[focusedIndex];
}
private registerListeners(): void { private registerListeners(): void {
this.toUnbind.push(this.model.onDidNotificationChange(e => this.onDidNotificationChange(e))); this.toUnbind.push(this.model.onDidNotificationChange(e => this.onDidNotificationChange(e)));
} }
...@@ -82,6 +98,9 @@ export class NotificationsCenter extends Themable { ...@@ -82,6 +98,9 @@ export class NotificationsCenter extends Themable {
// Focus // Focus
this.focusNotificationsList(); this.focusNotificationsList();
// Context Key
this.notificationsCenterVisibleContextKey.set(true);
// Event // Event
this._onDidChangeVisibility.fire(); this._onDidChangeVisibility.fire();
} }
...@@ -92,10 +111,6 @@ export class NotificationsCenter extends Themable { ...@@ -92,10 +111,6 @@ export class NotificationsCenter extends Themable {
} }
this.list.domFocus(); this.list.domFocus();
if (this.list.getFocus().length === 0) {
this.list.focusFirst();
}
} }
private createNotificationsList(): void { private createNotificationsList(): void {
...@@ -120,6 +135,9 @@ export class NotificationsCenter extends Themable { ...@@ -120,6 +135,9 @@ export class NotificationsCenter extends Themable {
); );
this.toUnbind.push(this.list); this.toUnbind.push(this.list);
// Context key
NotificationsCenterFocusedContext.bindTo(this.list.contextKeyService);
// Only allow for focus in notifications, as the // Only allow for focus in notifications, as the
// selection is too strong over the contents of // selection is too strong over the contents of
// the notification // the notification
...@@ -165,7 +183,8 @@ export class NotificationsCenter extends Themable { ...@@ -165,7 +183,8 @@ export class NotificationsCenter extends Themable {
private updateNotificationsList(start: number, deleteCount: number, items: INotificationViewItem[] = []) { private updateNotificationsList(start: number, deleteCount: number, items: INotificationViewItem[] = []) {
// Remember focus // Remember focus
const focus = this.indexToItems(this.list.getFocus()); const focusedIndex = this.list.getFocus()[0];
const focusedItem = this.viewModel[focusedIndex];
// Update view model // Update view model
this.viewModel.splice(start, deleteCount, ...items); this.viewModel.splice(start, deleteCount, ...items);
...@@ -181,15 +200,26 @@ export class NotificationsCenter extends Themable { ...@@ -181,15 +200,26 @@ export class NotificationsCenter extends Themable {
// Otherwise restore focus // Otherwise restore focus
else { else {
this.list.setFocus(focus.map(f => this.viewModel.indexOf(f))); let indexToFocus = 0;
} if (focusedItem) {
} let indexToFocusCandidate = this.viewModel.indexOf(focusedItem);
if (indexToFocusCandidate === -1) {
indexToFocusCandidate = focusedIndex - 1; // item could have been removed
}
if (indexToFocusCandidate < this.viewModel.length && indexToFocusCandidate >= 0) {
indexToFocus = indexToFocusCandidate;
}
}
private indexToItems(indeces: number[]): INotificationViewItem[] { this.list.setFocus([indexToFocus]);
return indeces.map(index => this.viewModel[index]).filter(item => !!item); }
} }
public hide(): void { public hide(): void {
if (!this._isVisible || !this.list) {
return; // already hidden
}
// Hide // Hide
this._isVisible = false; this._isVisible = false;
...@@ -201,6 +231,9 @@ export class NotificationsCenter extends Themable { ...@@ -201,6 +231,9 @@ export class NotificationsCenter extends Themable {
// Clear view model // Clear view model
this.viewModel = []; this.viewModel = [];
// Context Key
this.notificationsCenterVisibleContextKey.set(false);
// Event // Event
this._onDidChangeVisibility.fire(); this._onDidChangeVisibility.fire();
} }
...@@ -264,6 +297,17 @@ export class NotificationsCenter extends Themable { ...@@ -264,6 +297,17 @@ export class NotificationsCenter extends Themable {
this.list.getHTMLElement().style.maxHeight = `${maxHeight}px`; this.list.getHTMLElement().style.maxHeight = `${maxHeight}px`;
this.list.layout(); this.list.layout();
} }
public clearAll(): void {
// Hide notifications center first
this.hide();
// Dispose all
while (this.model.notifications.length) {
this.model.notifications[0].dispose();
}
}
} }
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
......
...@@ -24,7 +24,8 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; ...@@ -24,7 +24,8 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { DropdownMenuActionItem } from 'vs/base/browser/ui/dropdown/dropdown'; import { DropdownMenuActionItem } from 'vs/base/browser/ui/dropdown/dropdown';
import { INotificationViewItem, NotificationViewItem } from 'vs/workbench/common/notifications'; import { INotificationViewItem, NotificationViewItem } from 'vs/workbench/common/notifications';
import { CloseNotificationAction, ExpandNotificationAction, CollapseNotificationAction, DoNotShowNotificationAgainAction, ConfigureNotificationAction } from 'vs/workbench/browser/parts/notifications/notificationsActions'; import { ClearNotificationAction, ExpandNotificationAction, CollapseNotificationAction, DoNotShowNotificationAgainAction, ConfigureNotificationAction } from 'vs/workbench/browser/parts/notifications/notificationsActions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
export class NotificationsListDelegate implements IDelegate<INotificationViewItem> { export class NotificationsListDelegate implements IDelegate<INotificationViewItem> {
...@@ -143,7 +144,7 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN ...@@ -143,7 +144,7 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN
private toDispose: IDisposable[]; private toDispose: IDisposable[];
private closeNotificationAction: CloseNotificationAction; private closeNotificationAction: ClearNotificationAction;
private expandNotificationAction: ExpandNotificationAction; private expandNotificationAction: ExpandNotificationAction;
private collapseNotificationAction: CollapseNotificationAction; private collapseNotificationAction: CollapseNotificationAction;
private doNotShowNotificationAgainAction: DoNotShowNotificationAgainAction; private doNotShowNotificationAgainAction: DoNotShowNotificationAgainAction;
...@@ -153,11 +154,12 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN ...@@ -153,11 +154,12 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN
@IOpenerService private openerService: IOpenerService, @IOpenerService private openerService: IOpenerService,
@IThemeService private themeService: IThemeService, @IThemeService private themeService: IThemeService,
@IInstantiationService private instantiationService: IInstantiationService, @IInstantiationService private instantiationService: IInstantiationService,
@IContextMenuService private contextMenuService: IContextMenuService @IContextMenuService private contextMenuService: IContextMenuService,
@IKeybindingService private keybindingService: IKeybindingService
) { ) {
this.toDispose = []; this.toDispose = [];
this.closeNotificationAction = instantiationService.createInstance(CloseNotificationAction, CloseNotificationAction.ID, CloseNotificationAction.LABEL); this.closeNotificationAction = instantiationService.createInstance(ClearNotificationAction, ClearNotificationAction.ID, ClearNotificationAction.LABEL);
this.expandNotificationAction = instantiationService.createInstance(ExpandNotificationAction, ExpandNotificationAction.ID, ExpandNotificationAction.LABEL); this.expandNotificationAction = instantiationService.createInstance(ExpandNotificationAction, ExpandNotificationAction.ID, ExpandNotificationAction.LABEL);
this.collapseNotificationAction = instantiationService.createInstance(CollapseNotificationAction, CollapseNotificationAction.ID, CollapseNotificationAction.LABEL); this.collapseNotificationAction = instantiationService.createInstance(CollapseNotificationAction, CollapseNotificationAction.ID, CollapseNotificationAction.LABEL);
this.doNotShowNotificationAgainAction = this.instantiationService.createInstance(DoNotShowNotificationAgainAction, DoNotShowNotificationAgainAction.ID, DoNotShowNotificationAgainAction.LABEL); this.doNotShowNotificationAgainAction = this.instantiationService.createInstance(DoNotShowNotificationAgainAction, DoNotShowNotificationAgainAction.ID, DoNotShowNotificationAgainAction.LABEL);
...@@ -206,7 +208,7 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN ...@@ -206,7 +208,7 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN
return null; return null;
} }
}, }
); );
// Details Row // Details Row
...@@ -288,7 +290,7 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN ...@@ -288,7 +290,7 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN
// Toolbar // Toolbar
data.toolbar.clear(); data.toolbar.clear();
data.toolbar.context = notification; data.toolbar.context = notification;
data.toolbar.push(actions, { icon: true, label: false }); actions.forEach(action => data.toolbar.push(action, { icon: true, label: false, keybinding: this.getKeybindingLabel(action) }));
// Source // Source
if (notification.expanded && notification.source) { if (notification.expanded && notification.source) {
...@@ -304,6 +306,12 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN ...@@ -304,6 +306,12 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN
} }
} }
private getKeybindingLabel(action: IAction): string {
const keybinding = this.keybindingService.lookupKeybinding(action.id);
return keybinding ? keybinding.getLabel() : void 0;
}
private createButton(notification: INotificationViewItem, action: IAction, data: INotificationTemplateData): Button { private createButton(notification: INotificationViewItem, action: IAction, data: INotificationTemplateData): Button {
const button = new Button(data.actionsContainer); const button = new Button(data.actionsContainer);
data.toDispose.push(attachButtonStyler(button, this.themeService)); data.toDispose.push(attachButtonStyler(button, this.themeService));
......
...@@ -128,6 +128,10 @@ export interface INotificationViewItem { ...@@ -128,6 +128,10 @@ export interface INotificationViewItem {
dispose(): void; dispose(): void;
} }
export function isNotificationViewItem(obj: any): obj is INotificationViewItem {
return obj instanceof NotificationViewItem;
}
export class NotificationViewItem implements INotificationViewItem { export class NotificationViewItem implements INotificationViewItem {
private static MAX_MESSAGE_LENGTH = 1000; private static MAX_MESSAGE_LENGTH = 1000;
...@@ -216,11 +220,19 @@ export class NotificationViewItem implements INotificationViewItem { ...@@ -216,11 +220,19 @@ export class NotificationViewItem implements INotificationViewItem {
} }
public expand(): void { public expand(): void {
if (this._expanded) {
return;
}
this._expanded = true; this._expanded = true;
this._onDidChange.fire(); this._onDidChange.fire();
} }
public collapse(): void { public collapse(): void {
if (!this._expanded || !this.canCollapse) {
return;
}
this._expanded = false; this._expanded = false;
this._onDidChange.fire(); this._onDidChange.fire();
} }
......
...@@ -224,7 +224,7 @@ export class FeedbackDropdown extends Dropdown { ...@@ -224,7 +224,7 @@ export class FeedbackDropdown extends Dropdown {
this.toDispose.push(attachStylerCallback(this.themeService, { widgetShadow, editorWidgetBackground, inputBackground, inputForeground, inputBorder, editorBackground, contrastBorder }, colors => { this.toDispose.push(attachStylerCallback(this.themeService, { widgetShadow, editorWidgetBackground, inputBackground, inputForeground, inputBorder, editorBackground, contrastBorder }, colors => {
$form.style('background-color', colors.editorWidgetBackground); $form.style('background-color', colors.editorWidgetBackground);
$form.style('box-shadow', colors.widgetShadow ? `0 2px 8px ${colors.widgetShadow}` : null); $form.style('box-shadow', colors.widgetShadow ? `0 5px 8px ${colors.widgetShadow}` : null);
if (this.feedbackDescriptionInput) { if (this.feedbackDescriptionInput) {
this.feedbackDescriptionInput.style.backgroundColor = colors.inputBackground; this.feedbackDescriptionInput.style.backgroundColor = colors.inputBackground;
......
...@@ -88,7 +88,6 @@ ...@@ -88,7 +88,6 @@
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
margin: .5em 0 0 0;
padding: .5em; padding: .5em;
width: 22px; width: 22px;
height: 22px; height: 22px;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册