From e18c452e5e196e9ac76c743c228b1ec7dceb1c37 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 16 Feb 2018 16:32:54 +0100 Subject: [PATCH] notifications - introduce notifications center container --- .../media/notificationsActions.css | 24 ++++---- .../media/notificationsCenter.css | 23 ++++++++ .../notifications/media/notificationsList.css | 55 ++++++------------- .../notifications/notificationsCenter.ts | 28 +++++++--- .../parts/notifications/notificationsList.ts | 19 +++---- 5 files changed, 80 insertions(+), 69 deletions(-) create mode 100644 src/vs/workbench/browser/parts/notifications/media/notificationsCenter.css diff --git a/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css b/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css index f2ee54515fc..33415792819 100644 --- a/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css +++ b/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css @@ -3,38 +3,38 @@ * 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 .clear-notification-action { +.vs .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .clear-notification-action { background-image: url('close.svg'); } -.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 .clear-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 .clear-notification-action { background-image: url('close-inverse.svg'); } -.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action { +.vs .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action { background-image: url('down.svg'); } -.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action, -.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action { +.vs-dark .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action, +.hc-black .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action { background-image: url('down-inverse.svg'); } -.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action { +.vs .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action { background-image: url('up.svg'); } -.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action, -.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action { +.vs-dark .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action, +.hc-black .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action { background-image: url('up-inverse.svg'); } -.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action { +.vs .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action { background-image: url('configure.svg'); } -.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action, -.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action { +.vs-dark .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action, +.hc-black .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action { background-image: url('configure-inverse.svg'); } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/notifications/media/notificationsCenter.css b/src/vs/workbench/browser/parts/notifications/media/notificationsCenter.css new file mode 100644 index 00000000000..001f0b18713 --- /dev/null +++ b/src/vs/workbench/browser/parts/notifications/media/notificationsCenter.css @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.monaco-workbench > .notifications-center { + position: absolute; + width: 600px; + z-index: 1000; + right: 8px; + bottom: 30px; /* above status bar */ + display: none; + overflow: hidden; +} + +.monaco-workbench.nostatusbar > .notifications-center { + right: 12px; + bottom: 12px; +} + +.monaco-workbench > .notifications-center.visible { + display: block; +} \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/notifications/media/notificationsList.css b/src/vs/workbench/browser/parts/notifications/media/notificationsList.css index 034ad4693c8..d1036af4143 100644 --- a/src/vs/workbench/browser/parts/notifications/media/notificationsList.css +++ b/src/vs/workbench/browser/parts/notifications/media/notificationsList.css @@ -3,28 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-workbench > .notifications-list-container { - position: absolute; - width: 600px; - z-index: 1000; - right: 8px; - bottom: 30px; /* above status bar */ - display: none; - overflow: hidden; -} - -.monaco-workbench.nostatusbar > .notifications-list-container { - right: 12px; - bottom: 12px; -} - -.monaco-workbench > .notifications-list-container.visible { - display: block; -} - /** Notification: Container */ -.monaco-workbench > .notifications-list-container .notification-list-item { +.monaco-workbench .notifications-list-container .notification-list-item { display: flex; flex-direction: column; flex-direction: column-reverse; /* the details row appears first in order for better keyboard access to notification buttons */ @@ -35,14 +16,14 @@ /** Notification: Main Row */ -.monaco-workbench > .notifications-list-container .notification-list-item > .notification-list-item-main-row { +.monaco-workbench .notifications-list-container .notification-list-item > .notification-list-item-main-row { display: flex; flex-grow: 1; } /** Notification: Icon */ -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-icon { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-icon { flex: 0 0 16px; height: 22px; margin-right: 4px; @@ -51,44 +32,44 @@ background-repeat: no-repeat; } -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-icon.icon-info { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-icon.icon-info { background-image: url('info.svg'); } -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-icon.icon-warning { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-icon.icon-warning { background-image: url('warning.svg'); } -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-icon.icon-error { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-icon.icon-error { background-image: url('error.svg'); } /** Notification: Message */ -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-message { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-message { line-height: 22px; overflow: hidden; text-overflow: ellipsis; flex: 1; /* let the message always grow */ } -.monaco-workbench > .notifications-list-container .notification-list-item.expanded .notification-list-item-message { +.monaco-workbench .notifications-list-container .notification-list-item.expanded .notification-list-item-message { white-space: normal; } /** Notification: Toolbar Container */ -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container { display: none; } -.monaco-workbench > .notifications-list-container .notification-list-item:hover .notification-list-item-toolbar-container, -.monaco-workbench > .notifications-list-container .monaco-list-row.focused .notification-list-item .notification-list-item-toolbar-container, -.monaco-workbench > .notifications-list-container .notification-list-item.expanded .notification-list-item-toolbar-container { +.monaco-workbench .notifications-list-container .notification-list-item:hover .notification-list-item-toolbar-container, +.monaco-workbench .notifications-list-container .monaco-list-row.focused .notification-list-item .notification-list-item-toolbar-container, +.monaco-workbench .notifications-list-container .notification-list-item.expanded .notification-list-item-toolbar-container { display: block; } -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .action-label { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .action-label { flex: 0 0 16px; display: block; width: 16px; @@ -101,20 +82,20 @@ /** Notification: Details Row */ -.monaco-workbench > .notifications-list-container .notification-list-item > .notification-list-item-details-row { +.monaco-workbench .notifications-list-container .notification-list-item > .notification-list-item-details-row { display: none; align-items: center; padding: 0 5px; overflow: hidden; /* details row should never overflow */ } -.monaco-workbench > .notifications-list-container .notification-list-item.expanded > .notification-list-item-details-row { +.monaco-workbench .notifications-list-container .notification-list-item.expanded > .notification-list-item-details-row { display: flex; } /** Notification: Source */ -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-source { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-source { opacity: 0.7; flex: 1; font-size: 12px; @@ -123,12 +104,12 @@ /** Notification: Actions */ -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-actions-container .monaco-button { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-actions-container .monaco-button { max-width: fit-content; padding: 5px 10px; font-size: 12px; } -.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-actions-container .monaco-button:not(:first-of-type) { +.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-actions-container .monaco-button:not(:first-of-type) { margin-left: 10px; } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts b/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts index 727b4c21405..f32f0dab762 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts @@ -5,6 +5,7 @@ 'use strict'; +import 'vs/css!./media/notificationsCenter'; import { Themable } from 'vs/workbench/common/theme'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { INotificationsModel, INotificationChangeEvent, NotificationChangeType } from 'vs/workbench/common/notifications'; @@ -15,11 +16,13 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c import { NotificationsCenterVisibleContext } from 'vs/workbench/browser/parts/notifications/notificationCommands'; import { NotificationsList } from 'vs/workbench/browser/parts/notifications/notificationsList'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { addClass, removeClass } from 'vs/base/browser/dom'; export class NotificationsCenter extends Themable { private static MAX_DIMENSIONS = new Dimension(600, 600); + private notificationsCenterContainer: HTMLElement; private notificationsList: NotificationsList; private _isVisible: boolean; private workbenchDimensions: Dimension; @@ -59,16 +62,22 @@ export class NotificationsCenter extends Themable { public show(): void { // Lazily create if showing for the first time - if (!this.notificationsList) { - this.notificationsList = this.instantiationService.createInstance(NotificationsList, this.container); + if (!this.notificationsCenterContainer) { + this.notificationsCenterContainer = document.createElement('div'); + addClass(this.notificationsCenterContainer, 'notifications-center'); + + this.notificationsList = this.instantiationService.createInstance(NotificationsList, this.notificationsCenterContainer); + + this.container.appendChild(this.notificationsCenterContainer); } // Make visible this._isVisible = true; + addClass(this.notificationsCenterContainer, 'visible'); this.notificationsList.show(); // Layout - this.layoutList(); + this.doLayout(); // Show all notifications that are present now this.notificationsList.updateNotificationsList(0, 0, this.model.notifications); @@ -105,12 +114,13 @@ export class NotificationsCenter extends Themable { } public hide(): void { - if (!this._isVisible || !this.notificationsList) { + if (!this._isVisible || !this.notificationsCenterContainer) { return; // already hidden } // Hide this._isVisible = false; + removeClass(this.notificationsCenterContainer, 'visible'); this.notificationsList.hide(); // Context Key @@ -123,12 +133,12 @@ export class NotificationsCenter extends Themable { public layout(dimension: Dimension): void { this.workbenchDimensions = dimension; - if (this._isVisible && this.notificationsList) { - this.layoutList(); + if (this._isVisible && this.notificationsCenterContainer) { + this.doLayout(); } } - private layoutList(): void { + private doLayout(): void { let width = NotificationsCenter.MAX_DIMENSIONS.width; let maxHeight = NotificationsCenter.MAX_DIMENSIONS.height; @@ -159,7 +169,9 @@ export class NotificationsCenter extends Themable { } } - this.notificationsList.layout(new Dimension(width, maxHeight)); + this.notificationsCenterContainer.style.width = `${width}px`; + + this.notificationsList.layout(maxHeight); } public clearAll(): void { diff --git a/src/vs/workbench/browser/parts/notifications/notificationsList.ts b/src/vs/workbench/browser/parts/notifications/notificationsList.ts index d92d6c96e12..c8703031461 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsList.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsList.ts @@ -6,7 +6,7 @@ 'use strict'; import 'vs/css!./media/notificationsList'; -import { addClass, removeClass, isAncestor } from 'vs/base/browser/dom'; +import { addClass, isAncestor } from 'vs/base/browser/dom'; import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IListOptions } from 'vs/base/browser/ui/list/listWidget'; @@ -17,14 +17,13 @@ import { contrastBorder, widgetShadow } from 'vs/platform/theme/common/colorRegi import { INotificationViewItem } from 'vs/workbench/common/notifications'; import { NotificationsListDelegate, NotificationRenderer } from 'vs/workbench/browser/parts/notifications/notificationsViewer'; import { NotificationActionRunner } from 'vs/workbench/browser/parts/notifications/notificationsActions'; -import { Dimension } from 'vs/base/browser/builder'; import { NotificationFocusedContext } from 'vs/workbench/browser/parts/notifications/notificationCommands'; export class NotificationsList extends Themable { private listContainer: HTMLElement; private list: WorkbenchList; private viewModel: INotificationViewItem[]; - private dimensions: Dimension; + private maxHeight: number; private isVisible: boolean; constructor( @@ -51,7 +50,6 @@ export class NotificationsList extends Themable { // Make visible this.isVisible = true; - addClass(this.listContainer, 'visible'); // Focus this.list.domFocus(); @@ -148,7 +146,6 @@ export class NotificationsList extends Themable { // Hide this.isVisible = false; - removeClass(this.listContainer, 'visible'); // Clear list this.list.splice(0, this.viewModel.length); @@ -173,17 +170,15 @@ export class NotificationsList extends Themable { } } - public layout(dimension: Dimension): void { - this.dimensions = dimension; + public layout(maxHeight: number): void { + this.maxHeight = maxHeight; this.layoutList(); } private layoutList(): void { if (this.list) { - this.listContainer.style.width = `${this.dimensions.width}px`; - - this.list.getHTMLElement().style.maxHeight = `${this.dimensions.height}px`; + this.list.getHTMLElement().style.maxHeight = `${this.maxHeight}px`; this.list.layout(); } } @@ -198,11 +193,11 @@ export class NotificationsList extends Themable { registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const linkColor = theme.getColor(NOTIFICATIONS_LINKS); if (linkColor) { - collector.addRule(`.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-message a { color: ${linkColor}; }`); + collector.addRule(`.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-message a { color: ${linkColor}; }`); } const notificationBorderColor = theme.getColor(NOTIFICATIONS_BORDER); if (notificationBorderColor) { - collector.addRule(`.monaco-workbench > .notifications-list-container .notification-list-item { border-bottom: 1px solid ${notificationBorderColor}; }`); + collector.addRule(`.monaco-workbench .notifications-list-container .notification-list-item { border-bottom: 1px solid ${notificationBorderColor}; }`); } }); -- GitLab