SDA-3033 Add ability to close all windows from SFE-Lite

This commit is contained in:
psjostrom 2021-04-01 15:34:02 +02:00
parent c621018c22
commit 614b3beef9
9 changed files with 46 additions and 57 deletions

View File

@ -38,6 +38,7 @@ jest.mock('../src/app/window-actions', () => {
jest.mock('../src/app/window-handler', () => { jest.mock('../src/app/window-handler', () => {
return { return {
windowHandler: { windowHandler: {
closeAllWindows: jest.fn(),
closeWindow: jest.fn(), closeWindow: jest.fn(),
createNotificationSettingsWindow: jest.fn(), createNotificationSettingsWindow: jest.fn(),
createScreenPickerWindow: jest.fn(), createScreenPickerWindow: jest.fn(),
@ -458,5 +459,14 @@ describe('main api handler', () => {
expect(windowHandler.appMenu.buildMenu).not.toBeCalled(); expect(windowHandler.appMenu.buildMenu).not.toBeCalled();
} }
}); });
it('should call closeAllWindows on windowHandler correctly', () => {
const spy = jest.spyOn(windowHandler, 'closeAllWindows');
const value = {
cmd: apiCmds.closeAllWrapperWindows,
};
ipcMain.send(apiName.symphonyApi, value);
expect(spy).toBeCalled();
});
}); });
}); });

View File

@ -35,6 +35,7 @@ import {
/** /**
* Handle API related ipc messages from renderers. Only messages from windows * Handle API related ipc messages from renderers. Only messages from windows
* we have created are allowed. * we have created are allowed.
* Used mainly for Mana to communicate with SDA
*/ */
ipcMain.on( ipcMain.on(
apiName.symphonyApi, apiName.symphonyApi,
@ -270,6 +271,9 @@ ipcMain.on(
await notificationHelper.closeNotification(arg.notificationId); await notificationHelper.closeNotification(arg.notificationId);
} }
break; break;
case apiCmds.closeAllWrapperWindows:
windowHandler.closeAllWindows();
break;
default: default:
break; break;
} }

View File

@ -607,7 +607,7 @@ export class WindowHandler {
if (isWindowsOS || isMac) { if (isWindowsOS || isMac) {
this.execCmd(this.screenShareIndicatorFrameUtil, []); this.execCmd(this.screenShareIndicatorFrameUtil, []);
} }
this.closeAllWindow(); this.closeAllWindows();
this.destroyAllWindows(); this.destroyAllWindows();
}); });
@ -796,18 +796,14 @@ export class WindowHandler {
/** /**
* Finds all the child window and closes it * Finds all the child window and closes it
*/ */
public async closeAllWindow(): Promise<void> { public closeAllWindows(): void {
const browserWindows = BrowserWindow.getAllWindows(); const browserWindows = BrowserWindow.getAllWindows();
await notification.cleanUp();
if (browserWindows && browserWindows.length) { if (browserWindows && browserWindows.length) {
browserWindows.forEach((win) => { browserWindows.forEach((win) => {
const browserWindow = win as ICustomBrowserWindow; const browserWindow = win as ICustomBrowserWindow;
if (browserWindow && windowExists(browserWindow)) { if (browserWindow && windowExists(browserWindow)) {
// Closes only child windows // Closes only child windows
if ( if (browserWindow.winName !== apiName.mainWindowName) {
browserWindow.winName !== apiName.mainWindowName &&
browserWindow.winName !== apiName.notificationWindowName
) {
if (browserWindow.closable) { if (browserWindow.closable) {
browserWindow.close(); browserWindow.close();
} else { } else {
@ -817,6 +813,7 @@ export class WindowHandler {
} }
}); });
} }
notification.cleanUp();
} }
/** /**

View File

@ -323,7 +323,7 @@ export const showPopupMenu = (opts: Electron.PopupOptions): void => {
* *
* @param windowName {string} * @param windowName {string}
*/ */
export const sanitize = async (windowName: string): Promise<void> => { export const sanitize = (windowName: string): void => {
// To make sure the reload event is from the main window // To make sure the reload event is from the main window
const mainWindow = windowHandler.getMainWindow(); const mainWindow = windowHandler.getMainWindow();
if (mainWindow && windowName === mainWindow.winName) { if (mainWindow && windowName === mainWindow.winName) {
@ -335,7 +335,7 @@ export const sanitize = async (windowName: string): Promise<void> => {
screenSnippet.killChildProcess(); screenSnippet.killChildProcess();
} }
// Closes all the child windows // Closes all the child windows
await windowHandler.closeAllWindow(); windowHandler.closeAllWindows();
} }
}; };
@ -675,7 +675,7 @@ export const reloadWindow = (browserWindow: ICustomBrowserWindow) => {
logger.info(`window-utils: reloading the main window`); logger.info(`window-utils: reloading the main window`);
browserWindow.reload(); browserWindow.reload();
windowHandler.closeAllWindow(); windowHandler.closeAllWindows();
windowHandler.execCmd(windowHandler.screenShareIndicatorFrameUtil, []); windowHandler.execCmd(windowHandler.screenShareIndicatorFrameUtil, []);

View File

@ -45,6 +45,7 @@ export enum apiCmds {
restartApp = 'restart-app', restartApp = 'restart-app',
setIsMana = 'set-is-mana', setIsMana = 'set-is-mana',
showNotification = 'show-notification', showNotification = 'show-notification',
closeAllWrapperWindows = 'close-all-windows',
} }
export enum apiName { export enum apiName {

View File

@ -94,6 +94,8 @@ export class AppBridge {
* Switch case that validates and handle * Switch case that validates and handle
* incoming messages from postMessage * incoming messages from postMessage
* *
* Is only used for 1.5.
*
* @param event * @param event
*/ */
private async handleMessage(event): Promise<void> { private async handleMessage(event): Promise<void> {

View File

@ -18,7 +18,6 @@ import { isNodeEnv, isWindowsOS } from '../common/env';
import { logger } from '../common/logger'; import { logger } from '../common/logger';
import NotificationHandler from './notification-handler'; import NotificationHandler from './notification-handler';
// const MAX_QUEUE_SIZE = 30;
const CLEAN_UP_INTERVAL = 60 * 1000; // Closes inactive notification const CLEAN_UP_INTERVAL = 60 * 1000; // Closes inactive notification
const animationQueue = new AnimationQueue(); const animationQueue = new AnimationQueue();
const CONTAINER_HEIGHT_WITH_INPUT = 120; // Notification container height const CONTAINER_HEIGHT_WITH_INPUT = 120; // Notification container height
@ -68,8 +67,8 @@ class Notification extends NotificationHandler {
this.onMouseLeave(windowId, isInputHidden), this.onMouseLeave(windowId, isInputHidden),
onShowReply: (_event, windowId) => this.onShowReply(windowId), onShowReply: (_event, windowId) => this.onShowReply(windowId),
}; };
private activeNotifications: Electron.BrowserWindow[] = []; private activeNotifications: ICustomBrowserWindow[] = [];
private inactiveWindows: Electron.BrowserWindow[] = []; private inactiveWindows: ICustomBrowserWindow[] = [];
private cleanUpTimer: NodeJS.Timer; private cleanUpTimer: NodeJS.Timer;
private notificationQueue: INotificationData[] = []; private notificationQueue: INotificationData[] = [];
@ -150,15 +149,13 @@ class Notification extends NotificationHandler {
} }
for (const window of this.activeNotifications) { for (const window of this.activeNotifications) {
const notificationWin = window as ICustomBrowserWindow; const winHeight = windowExists(window) && window.getBounds().height;
const winHeight =
windowExists(notificationWin) && notificationWin.getBounds().height;
if ( if (
window && window &&
notificationWin.notificationData.tag === data.tag && window.notificationData.tag === data.tag &&
winHeight < CONTAINER_HEIGHT_WITH_INPUT winHeight < CONTAINER_HEIGHT_WITH_INPUT
) { ) {
this.setNotificationContent(notificationWin, data); this.setNotificationContent(window, data);
return; return;
} }
} }
@ -175,7 +172,7 @@ class Notification extends NotificationHandler {
// Checks for the cashed window and use them // Checks for the cashed window and use them
if (this.inactiveWindows.length > 0) { if (this.inactiveWindows.length > 0) {
const inactiveWin = this.inactiveWindows[0] as ICustomBrowserWindow; const inactiveWin = this.inactiveWindows[0];
if (windowExists(inactiveWin)) { if (windowExists(inactiveWin)) {
this.inactiveWindows.splice(0, 1); this.inactiveWindows.splice(0, 1);
this.renderNotification(inactiveWin, data); this.renderNotification(inactiveWin, data);
@ -398,14 +395,9 @@ class Notification extends NotificationHandler {
public getNotificationWindow( public getNotificationWindow(
clientId: number, clientId: number,
): ICustomBrowserWindow | undefined { ): ICustomBrowserWindow | undefined {
const index: number = this.activeNotifications.findIndex((win) => { return this.activeNotifications.find(
const notificationWindow = win as ICustomBrowserWindow; (notification) => notification.clientId === clientId,
return notificationWindow.clientId === clientId; );
});
if (index === -1) {
return;
}
return this.activeNotifications[index] as ICustomBrowserWindow;
} }
/** /**
@ -426,35 +418,9 @@ class Notification extends NotificationHandler {
/** /**
* Closes all the notification windows and resets some configurations * Closes all the notification windows and resets some configurations
*/ */
public async cleanUp(): Promise<void> { public cleanUp(): void {
animationQueue.clear(); animationQueue.clear();
this.notificationQueue = []; this.notificationQueue = [];
const activeNotificationWindows = {
...[],
...this.activeNotifications,
};
const inactiveNotificationWindows = { ...[], ...this.inactiveWindows };
if (activeNotificationWindows && Array.isArray(activeNotificationWindows)) {
for (const activeWindow of activeNotificationWindows) {
if (activeWindow && windowExists(activeWindow)) {
await this.hideNotification(
(activeWindow as ICustomBrowserWindow).clientId,
);
}
}
}
if (
inactiveNotificationWindows &&
Array.isArray(inactiveNotificationWindows)
) {
for (const inactiveWindow of inactiveNotificationWindows) {
if (inactiveWindow && windowExists(inactiveWindow)) {
inactiveWindow.close();
}
}
}
this.activeNotifications = []; this.activeNotifications = [];
this.inactiveWindows = []; this.inactiveWindows = [];
} }
@ -464,9 +430,7 @@ class Notification extends NotificationHandler {
* issue: ELECTRON-1382 * issue: ELECTRON-1382
*/ */
public moveNotificationToTop(): void { public moveNotificationToTop(): void {
const notificationWindows = this this.activeNotifications
.activeNotifications as ICustomBrowserWindow[];
notificationWindows
.filter( .filter(
(browserWindow) => (browserWindow) =>
typeof browserWindow.notificationData === 'object' && typeof browserWindow.notificationData === 'object' &&

View File

@ -49,6 +49,7 @@ createAPI();
if (ssfWindow.ssf) { if (ssfWindow.ssf) {
// New context bridge api that exposes all the methods on to window object // New context bridge api that exposes all the methods on to window object
// For Mana to communicate with SDA
contextBridge.exposeInMainWorld('manaSSF', { contextBridge.exposeInMainWorld('manaSSF', {
setIsMana: ssfWindow.ssf.setIsMana, setIsMana: ssfWindow.ssf.setIsMana,
CryptoLib: ssfWindow.ssf.CryptoLib, CryptoLib: ssfWindow.ssf.CryptoLib,
@ -85,6 +86,7 @@ if (ssfWindow.ssf) {
showNotification: ssfWindow.ssf.showNotification, showNotification: ssfWindow.ssf.showNotification,
closeNotification: ssfWindow.ssf.closeNotification, closeNotification: ssfWindow.ssf.closeNotification,
restartApp: ssfWindow.ssf.restartApp, restartApp: ssfWindow.ssf.restartApp,
closeAllWrapperWindows: ssfWindow.ssf.closeAllWrapperWindows,
}); });
} }

View File

@ -627,6 +627,15 @@ export class SSFApi {
}); });
} }
/**
* Closes all browser windows on SDA side, such as notifications, Screen snippet window, popped out chats etc
*/
public closeAllWrapperWindows(): void {
ipcRenderer.send(apiName.symphonyApi, {
cmd: apiCmds.closeAllWrapperWindows,
});
}
/** /**
* Displays a notification from the main process * Displays a notification from the main process
* @param notificationOpts {INotificationData} * @param notificationOpts {INotificationData}