From ae053fd767cae84aa2fcccfd30960f1f5af77c37 Mon Sep 17 00:00:00 2001 From: vince-fugnitto Date: Fri, 3 Apr 2020 11:33:38 -0400 Subject: [PATCH] plugin: fix message-service Fixes #7332 Fixes #7491 The following commit fixes the following issues: - it should now be possible for plugins to call the `showMessage` with newlines when using the `modal` MessageOption`. - the `showMessage` should now support displaying the `isCloseAffordance` MessageType option. - fixes the argument type for `MessageItem`. Signed-off-by: vince-fugnitto --- .../plugin-ext/src/common/plugin-api-rpc.ts | 8 +++++- .../browser/dialogs/modal-notification.ts | 27 ++++++++++--------- .../dialogs/style/modal-notification.css | 5 ++++ .../src/main/browser/message-registry-main.ts | 16 ++++++----- .../plugin-ext/src/plugin/message-registry.ts | 6 ++--- 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts index c090dcf57dfab..589731c70460c 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts @@ -310,8 +310,14 @@ export interface MainMessageOptions { onCloseActionHandle?: number } +export interface MainMessageItem { + title: string, + isCloseAffordance?: boolean; + handle?: number +} + export interface MessageRegistryMain { - $showMessage(type: MainMessageType, message: string, options: MainMessageOptions, actions: string[]): PromiseLike; + $showMessage(type: MainMessageType, message: string, options: MainMessageOptions, actions: MainMessageItem[]): PromiseLike; } export interface StatusBarMessageRegistryMain { diff --git a/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts b/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts index ccd9e1bb0dd49..2b2d3869c13d8 100644 --- a/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts +++ b/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts @@ -13,11 +13,12 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import {injectable} from 'inversify'; -import {Message} from '@phosphor/messaging'; -import {Key} from '@theia/core/lib/browser'; -import {AbstractDialog} from '@theia/core/lib/browser/dialogs'; +import { injectable } from 'inversify'; +import { Message } from '@phosphor/messaging'; +import { Key } from '@theia/core/lib/browser'; +import { AbstractDialog } from '@theia/core/lib/browser/dialogs'; import '../../../../src/main/browser/dialogs/style/modal-notification.css'; +import { MainMessageItem } from '../../../common/plugin-api-rpc'; export enum MessageType { Error = 'error', @@ -35,7 +36,7 @@ export class ModalNotification extends AbstractDialog { protected actionTitle: string | undefined; constructor() { - super({title: 'Theia'}); + super({ title: 'Theia' }); } protected onCloseRequest(msg: Message): void { @@ -47,12 +48,12 @@ export class ModalNotification extends AbstractDialog { return this.actionTitle; } - showDialog(messageType: MessageType, text: string, actions: string[]): Promise { + showDialog(messageType: MessageType, text: string, actions: MainMessageItem[]): Promise { this.contentNode.appendChild(this.createMessageNode(messageType, text, actions)); return this.open(); } - protected createMessageNode(messageType: MessageType, text: string, actions: string[]): HTMLElement { + protected createMessageNode(messageType: MessageType, text: string, actions: MainMessageItem[]): HTMLElement { const messageNode = document.createElement('div'); messageNode.classList.add(NOTIFICATION); @@ -63,22 +64,24 @@ export class ModalNotification extends AbstractDialog { const textContainer = messageNode.appendChild(document.createElement('div')); textContainer.classList.add(TEXT); - const textElement = textContainer.appendChild(document.createElement('span')); + const textElement = textContainer.appendChild(document.createElement('pre')); textElement.textContent = text; - actions.forEach((action: string) => { - const button = this.createButton(action); + actions.forEach((action: MainMessageItem) => { + const button = this.createButton(action.title); button.classList.add('main'); this.controlPanel.appendChild(button); this.addKeyListener(button, Key.ENTER, () => { - this.actionTitle = action; + this.actionTitle = action.title; this.accept(); }, 'click'); }); - this.appendCloseButton('close'); + if (!actions.some(action => action.isCloseAffordance === true)) { + this.appendCloseButton('close'); + } return messageNode; } diff --git a/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css b/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css index 432d7cf0feed6..6004158c9119e 100644 --- a/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css +++ b/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css @@ -106,3 +106,8 @@ .modal-Notification .buttons > button:hover { background-color: var(--theia-button-hoverBackground); } + +.modal-Notification pre { + font-family: var(--theia-ui-font-family); + font-size: var(--theia-ui-font-size1); +} diff --git a/packages/plugin-ext/src/main/browser/message-registry-main.ts b/packages/plugin-ext/src/main/browser/message-registry-main.ts index b57e775cb563b..6d493a9b68385 100644 --- a/packages/plugin-ext/src/main/browser/message-registry-main.ts +++ b/packages/plugin-ext/src/main/browser/message-registry-main.ts @@ -16,7 +16,7 @@ import { interfaces } from 'inversify'; import { MessageService } from '@theia/core/lib/common/message-service'; -import { MessageRegistryMain, MainMessageType, MainMessageOptions } from '../../common/plugin-api-rpc'; +import { MessageRegistryMain, MainMessageType, MainMessageOptions, MainMessageItem } from '../../common/plugin-api-rpc'; import { ModalNotification, MessageType } from './dialogs/modal-notification'; export class MessageRegistryMainImpl implements MessageRegistryMain { @@ -26,13 +26,15 @@ export class MessageRegistryMainImpl implements MessageRegistryMain { this.messageService = container.get(MessageService); } - async $showMessage(type: MainMessageType, message: string, options: MainMessageOptions, actions: string[]): Promise { + async $showMessage(type: MainMessageType, message: string, options: MainMessageOptions, actions: MainMessageItem[]): Promise { const action = await this.doShowMessage(type, message, options, actions); - const handle = action ? actions.indexOf(action) : undefined; + const handle = action + ? actions.map(a => a.title).indexOf(action) + : undefined; return handle === undefined && options.modal ? options.onCloseActionHandle : handle; } - protected async doShowMessage(type: MainMessageType, message: string, options: MainMessageOptions, actions: string[]): Promise { + protected async doShowMessage(type: MainMessageType, message: string, options: MainMessageOptions, actions: MainMessageItem[]): Promise { if (options.modal) { const messageType = type === MainMessageType.Error ? MessageType.Error : type === MainMessageType.Warning ? MessageType.Warning : @@ -42,11 +44,11 @@ export class MessageRegistryMainImpl implements MessageRegistryMain { } switch (type) { case MainMessageType.Info: - return this.messageService.info(message, ...actions); + return this.messageService.info(message, ...actions.map(a => a.title)); case MainMessageType.Warning: - return this.messageService.warn(message, ...actions); + return this.messageService.warn(message, ...actions.map(a => a.title)); case MainMessageType.Error: - return this.messageService.error(message, ...actions); + return this.messageService.error(message, ...actions.map(a => a.title)); } throw new Error(`Message type '${type}' is not supported yet!`); } diff --git a/packages/plugin-ext/src/plugin/message-registry.ts b/packages/plugin-ext/src/plugin/message-registry.ts index 502da2a57cb0f..08a99bc0386e1 100644 --- a/packages/plugin-ext/src/plugin/message-registry.ts +++ b/packages/plugin-ext/src/plugin/message-registry.ts @@ -31,14 +31,14 @@ export class MessageRegistryExt { optionsOrFirstItem?: MessageOptions | string | MessageItem, ...rest: (string | MessageItem)[]): Promise { const options: MainMessageOptions = {}; - const actions: string[] = []; + const actions: MessageItem[] = []; const items: (string | MessageItem)[] = []; const pushItem = (item: string | MessageItem) => { items.push(item); if (typeof item === 'string') { - actions.push(item); + actions.push({ title: item }); } else { - actions.push(item.title); + actions.push({ title: item.title, isCloseAffordance: item.isCloseAffordance }); if (item.isCloseAffordance) { options.onCloseActionHandle = actions.length - 1; }