From d0fc0546db23f9858724149ab02cce8ea936371f Mon Sep 17 00:00:00 2001 From: Timofei Domnikov Date: Mon, 3 Jul 2023 17:49:11 +0300 Subject: [PATCH] KEEP-1731: Fix notification popup opening --- src/background.ts | 2 +- src/copied/manifest.json | 3 +- src/lib/windowManager.ts | 103 ++++++++++++++++----------------------- 3 files changed, 46 insertions(+), 62 deletions(-) diff --git a/src/background.ts b/src/background.ts index becba44fe..2893c81d9 100644 --- a/src/background.ts +++ b/src/background.ts @@ -179,7 +179,7 @@ async function setupBackgroundService() { }); // Notification window management - const windowManager = new WindowManager({ extensionStorage }); + const windowManager = new WindowManager(); backgroundService.on( 'Show notification', windowManager.showWindow.bind(windowManager) diff --git a/src/copied/manifest.json b/src/copied/manifest.json index 555d6246e..2b323be74 100644 --- a/src/copied/manifest.json +++ b/src/copied/manifest.json @@ -40,6 +40,7 @@ "clipboardWrite", "idle", "storage", - "unlimitedStorage" + "unlimitedStorage", + "tabs" ] } diff --git a/src/lib/windowManager.ts b/src/lib/windowManager.ts index 7f49ec90e..d3fe120e8 100644 --- a/src/lib/windowManager.ts +++ b/src/lib/windowManager.ts @@ -1,80 +1,63 @@ -import ObservableStore from 'obs-store'; +import invariant from 'tiny-invariant'; import Browser from 'webextension-polyfill'; -import { type ExtensionStorage } from '../storage/storage'; - -const height = 622; -const width = 357; +const NOTIFICATION_WINDOW_URL = Browser.runtime.getURL('/notification.html'); export class WindowManager { - #store; + #lastWindowPromise: Promise = + Promise.resolve(); + + async #getNotificationWindowId() { + const windows = await Browser.windows.getAll({ + populate: true, + windowTypes: ['popup'], + }); - constructor({ extensionStorage }: { extensionStorage: ExtensionStorage }) { - this.#store = new ObservableStore( - extensionStorage.getInitState({ - notificationWindowId: undefined, - inShowMode: undefined, - }) + const win = windows.find(w => + w.tabs?.some(tab => tab.url?.startsWith(NOTIFICATION_WINDOW_URL)) ); - extensionStorage.subscribe(this.#store); + return win?.id; } - async showWindow() { - const { inShowMode } = this.#store.getState(); - - if (inShowMode) { - return null; - } - - this.#store.updateState({ inShowMode: true }); - - const notificationWindow = await this.#getNotificationWindow(); - - if (notificationWindow?.id) { - await Browser.windows.update(notificationWindow.id, { focused: true }); - } else { - const { id: notificationWindowId } = await Browser.windows.create({ - url: 'notification.html', - type: 'popup', - focused: true, - width, - height, + showWindow() { + this.#lastWindowPromise = this.#lastWindowPromise + .catch(() => undefined) + .then(async win => { + const notificationWindowId = + win?.id ?? (await this.#getNotificationWindowId()); + + try { + invariant(notificationWindowId); + return await Browser.windows.update(notificationWindowId, { + focused: true, + }); + } catch (e) { + return Browser.windows.create({ + url: NOTIFICATION_WINDOW_URL, + type: 'popup', + focused: true, + width: 357, + height: 622, + }); + } }); - - this.#store.updateState({ notificationWindowId }); - } - - this.#store.updateState({ inShowMode: false }); - } - - async #getNotificationWindow() { - const windows = - (await Browser.windows.getAll({ windowTypes: ['popup'] })) ?? []; - - const { notificationWindowId } = this.#store.getState(); - - return windows.find(window => window.id === notificationWindowId); } async resizeWindow(newWidth: number, newHeight: number) { - const notificationWindow = await this.#getNotificationWindow(); + const notificationWindowId = await this.#getNotificationWindowId(); + if (notificationWindowId == null) return; - if (notificationWindow?.id) { - await Browser.windows.update(notificationWindow.id, { - width: newWidth, - height: newHeight, - }); - } + await Browser.windows.update(notificationWindowId, { + width: newWidth, + height: newHeight, + }); } async closeWindow() { - const notificationWindow = await this.#getNotificationWindow(); - - if (notificationWindow?.id) { - await Browser.windows.remove(notificationWindow.id); - } + const notificationWindowId = await this.#getNotificationWindowId(); + if (notificationWindowId == null) return; - this.#store.updateState({ notificationWindowId: undefined }); + await Browser.windows.remove(notificationWindowId); } }