From d555ff2cba5a35408d102bb312680c6d3f9f5e2a Mon Sep 17 00:00:00 2001 From: richard-loafle <44828666+richard-loafle@users.noreply.github.com> Date: Thu, 20 Feb 2020 15:44:38 +0900 Subject: [PATCH] pooling of notification window is added --- .../models/electron-notification-options.ts | 9 +- .../services/electron-notification.service.ts | 84 +++++++++++++++++-- .../ucap-webmessenger-electron/src/index.ts | 4 + 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/electron-projects/ucap-webmessenger-electron-notification/src/lib/models/electron-notification-options.ts b/electron-projects/ucap-webmessenger-electron-notification/src/lib/models/electron-notification-options.ts index d25ec28d..ba569567 100644 --- a/electron-projects/ucap-webmessenger-electron-notification/src/lib/models/electron-notification-options.ts +++ b/electron-projects/ucap-webmessenger-electron-notification/src/lib/models/electron-notification-options.ts @@ -13,6 +13,10 @@ export interface ElectronNotificationOptions { appIcon?: string; pathToModule?: string; logging?: boolean; + browserWindowPool?: { + min?: number; + max?: number; + }; defaultStyleContainer?: { [attribute: string]: any; }; @@ -44,7 +48,10 @@ export const DefaultElectronNotificationOptions: ElectronNotificationOptions = { appIcon: null, pathToModule: '', logging: true, - + browserWindowPool: { + min: 0, + max: 7 + }, defaultStyleContainer: { backgroundColor: '#f0f0f0', overflow: 'hidden', diff --git a/electron-projects/ucap-webmessenger-electron-notification/src/lib/services/electron-notification.service.ts b/electron-projects/ucap-webmessenger-electron-notification/src/lib/services/electron-notification.service.ts index 79b3b879..fbfcceea 100644 --- a/electron-projects/ucap-webmessenger-electron-notification/src/lib/services/electron-notification.service.ts +++ b/electron-projects/ucap-webmessenger-electron-notification/src/lib/services/electron-notification.service.ts @@ -28,6 +28,69 @@ interface ENDimension { height: number; } +class BrowserWindowPooler { + private readonly inactiveWindows: BrowserWindow[]; + private handle: any; + + constructor(private readonly minSize: number) { + this.minSize = 0 > this.minSize ? 0 : this.minSize; + this.inactiveWindows = []; + } + + get length() { + return this.inactiveWindows.length; + } + + push(...items: BrowserWindow[]): number { + const length = this.inactiveWindows.push(...items); + + if (this.minSize < length) { + this.start(); + } + + return length; + } + + pop(): BrowserWindow { + if (!this.inactiveWindows || 0 === this.inactiveWindows.length) { + return undefined; + } + + const w = this.inactiveWindows.pop(); + if (this.minSize >= this.inactiveWindows.length) { + this.stop(); + } + + return w; + } + + closeAll() { + while (this.inactiveWindows.length > 0) { + const w = this.inactiveWindows.pop(); + w.close(); + } + } + + private start() { + if (!!this.handle) { + this.stop(); + } + this.handle = setTimeout(() => { + while (this.minSize < this.inactiveWindows.length) { + const w = this.inactiveWindows.pop(); + w.close(); + } + }, 3000); + } + + private stop() { + if (!!this.handle) { + clearTimeout(this.handle); + this.handle = undefined; + } + } +} + export class ElectronNotificationService { private animationQueue: AnimationQueue; private customOptions: ElectronNotificationOptions; @@ -37,7 +100,8 @@ export class ElectronNotificationService { private lowerRightCornerPosition: ENPoint; private maxVisibleNotifications: number; private activeNotifications: BrowserWindow[]; - private inactiveWindows: BrowserWindow[]; + private browserWindowPooler: BrowserWindowPooler; + private notificationQueue: ElectronNotification[]; private closedNotifications: Map; private latestId: number; @@ -99,13 +163,13 @@ export class ElectronNotificationService { dispose(): void { this.animationQueue.clear(); this.activeNotifications.forEach(window => window.close()); - this.inactiveWindows.forEach(window => window.close()); + this.browserWindowPooler.closeAll(); } closeAll(): void { this.animationQueue.clear(); this.activeNotifications.forEach(window => window.close()); - this.inactiveWindows.forEach(window => window.close()); + this.browserWindowPooler.closeAll(); this.setup(); } @@ -115,7 +179,9 @@ export class ElectronNotificationService { this.totalDimension = { width: 0, height: 0 }; this.firstPosition = { x: 0, y: 0 }; this.activeNotifications = []; - this.inactiveWindows = []; + this.browserWindowPooler = new BrowserWindowPooler( + this.options.browserWindowPool.min + ); this.notificationQueue = []; this.closedNotifications = new Map(); this.latestId = 0; @@ -136,7 +202,9 @@ export class ElectronNotificationService { ); this.maxVisibleNotifications = - 7 < this.maxVisibleNotifications ? 7 : this.maxVisibleNotifications; + this.options.browserWindowPool.max < this.maxVisibleNotifications + ? this.options.browserWindowPool.max + : this.maxVisibleNotifications; } private setupEvents(): void { @@ -335,7 +403,7 @@ export class ElectronNotificationService { } const i = self.activeNotifications.indexOf(notificationWindow); self.activeNotifications.splice(i, 1); - self.inactiveWindows.push(notificationWindow); + self.browserWindowPooler.push(notificationWindow); notificationWindow.hide(); self.checkForQueuedNotifications(); @@ -376,8 +444,8 @@ export class ElectronNotificationService { private getWindow(): Promise { const slef = this; return new Promise((resolve, reject) => { - if (0 < slef.inactiveWindows.length) { - resolve(slef.inactiveWindows.pop()); + if (0 < slef.browserWindowPooler.length) { + resolve(slef.browserWindowPooler.pop()); } else { const windowProperties = slef.customOptions.defaultWindow; windowProperties.width = slef.customOptions.width; diff --git a/electron-projects/ucap-webmessenger-electron/src/index.ts b/electron-projects/ucap-webmessenger-electron/src/index.ts index 71848a60..458c55e0 100644 --- a/electron-projects/ucap-webmessenger-electron/src/index.ts +++ b/electron-projects/ucap-webmessenger-electron/src/index.ts @@ -291,6 +291,10 @@ app.on(ElectronAppChannel.Ready, () => { padding: 0, borderRadius: 0, // appIcon: iconPath, + browserWindowPool: { + min: 0, + max: 7 + }, displayTime: 5000, defaultStyleContainer: {}, defaultStyleAppIcon: { display: 'none' },