feat: Add Notifications API

Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
This commit is contained in:
Yevhen Vydolob 2022-06-16 11:40:30 +03:00
parent 14b1d8e426
commit d2fbc755c8
7 changed files with 66 additions and 3 deletions

View file

@ -182,7 +182,7 @@ class WinInstaller extends BaseInstaller {
if (fs.existsSync(msiPath)) {
await this.executeInstaller('msiexec', ['/i', msiPath, '/qb', '/norestart']);
progress.report({ increment: 80 });
await extensionApi.window.showInformationMessage('Podman is successfully installed.', 'OK');
extensionApi.window.showNotification({ body: 'Podman is successfully installed.' });
return true;
} else {
throw new Error(`Can't find Podman msi package! Path: ${msiPath} doesn't exists.`);

View file

@ -26,5 +26,7 @@ export const isLinux = os.platform() === 'linux';
* @returns true if app running in dev mode
*/
export function isDev(): boolean {
return process.argv[2] === '--dev';
const isEnvSet = 'ELECTRON_IS_DEV' in process.env;
const envSet = Number.parseInt(process.env.ELECTRON_IS_DEV, 10) === 1;
return isEnvSet ? envSet : false;
}

View file

@ -379,6 +379,21 @@ declare module '@tmpwip/extension-api' {
onCancellationRequested: Event<any>;
}
export interface NotificationOptions {
/**
* A title for the notification, which will be shown at the top of the notification window when it is shown.
*/
title?: string;
/**
* The body text of the notification, which will be displayed below the title.
*/
body?: string;
/**
* Whether or not to emit an OS notification noise when showing the notification.
*/
silent?: boolean;
}
export namespace window {
/**
* Show an information message. Optionally provide an array of items which will be presented as
@ -414,5 +429,11 @@ declare module '@tmpwip/extension-api' {
options: ProgressOptions,
task: (progress: Progress<{ message?: string; increment?: number }>, token: CancellationToken) => Promise<R>,
): Promise<R>;
/**
* Show OS desktop notification
* @param options
*/
export function showNotification(options: NotificationOptions): Disposable;
}
}

View file

@ -31,6 +31,7 @@ import type { ImageRegistry } from './image-registry';
import type { Dialogs } from './dialog-impl';
import type { ProgressImpl } from './progress-impl';
import { ProgressLocation } from './progress-impl';
import type { NotificationImpl } from './notification-impl';
/**
* Handle the loading of an extension
@ -71,6 +72,7 @@ export class ExtensionLoader {
private trayMenuRegistry: TrayMenuRegistry,
private dialogs: Dialogs,
private progress: ProgressImpl,
private notifications: NotificationImpl,
) {}
async listExtensions(): Promise<ExtensionInfo[]> {
@ -272,6 +274,7 @@ export class ExtensionLoader {
const dialogs = this.dialogs;
const progress = this.progress;
const notifications = this.notifications;
const windowObj: typeof containerDesktopAPI.window = {
showInformationMessage: (message: string, ...items: string[]) => {
return dialogs.showDialog('info', extManifest.name, message, items);
@ -292,6 +295,10 @@ export class ExtensionLoader {
): Promise<R> => {
return progress.withProgress(options, task);
},
showNotification: (options: containerDesktopAPI.NotificationOptions): containerDesktopAPI.Disposable => {
return notifications.showNotification(options);
},
};
return <typeof containerDesktopAPI>{

View file

@ -49,6 +49,7 @@ import { ContributionManager } from './contribution-manager';
import { DockerDesktopInstallation } from './docker-extension/docker-desktop-installation';
import { DockerPluginAdapter } from './docker-extension/docker-plugin-adapter';
import { Telemetry } from './telemetry/telemetry';
import { NotificationImpl } from './notification-impl';
export class PluginSystem {
constructor(private trayMenu: TrayMenu) {}
@ -107,6 +108,7 @@ export class PluginSystem {
trayMenuRegistry,
new Dialogs(),
new ProgressImpl(),
new NotificationImpl(),
);
const contributionManager = new ContributionManager(apiSender);

View file

@ -0,0 +1,31 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import type * as containerDesktopAPI from '@tmpwip/extension-api';
import { Notification } from 'electron';
import { Disposable } from './types/disposable';
export class NotificationImpl {
showNotification(options: containerDesktopAPI.NotificationOptions): Disposable {
const notification = new Notification(options);
notification.show();
return Disposable.create(() => {
notification.close();
});
}
}

View file

@ -74,7 +74,7 @@ const setupMainPackageWatcher = ({config: {server}}) => {
spawnProcess = null;
}
spawnProcess = spawn(String(electronPath), ['.']);
spawnProcess = spawn(String(electronPath), ['.'], { env: {ELECTRON_IS_DEV: 1} });
spawnProcess.stdout.on('data', d => d.toString().trim() && logger.warn(d.toString(), {timestamp: true}));
spawnProcess.stderr.on('data', d => {