From a141d3cde48c395f104a8d4a0000748457380a00 Mon Sep 17 00:00:00 2001 From: Devin Binnie <52460000+devinbinnie@users.noreply.github.com> Date: Tue, 18 Apr 2023 09:14:18 -0400 Subject: [PATCH] Migrate downloads dropdown menus to singletons (#2680) --- .../views/downloadsDropdownMenuView.test.js | 5 +- src/main/views/downloadsDropdownMenuView.ts | 122 +++++++--------- src/main/views/downloadsDropdownView.test.js | 9 +- src/main/views/downloadsDropdownView.ts | 130 +++++++----------- src/main/windows/windowManager.test.js | 8 +- src/main/windows/windowManager.ts | 28 ++-- 6 files changed, 129 insertions(+), 173 deletions(-) diff --git a/src/main/views/downloadsDropdownMenuView.test.js b/src/main/views/downloadsDropdownMenuView.test.js index bff652de..37a13b5c 100644 --- a/src/main/views/downloadsDropdownMenuView.test.js +++ b/src/main/views/downloadsDropdownMenuView.test.js @@ -9,7 +9,7 @@ import {DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT, DOWN import MainWindow from 'main/windows/mainWindow'; -import DownloadsDropdownMenuView from './downloadsDropdownMenuView'; +import {DownloadsDropdownMenuView} from './downloadsDropdownMenuView'; jest.mock('main/utils', () => ({ getLocalPreload: (file) => file, @@ -76,12 +76,13 @@ describe('main/views/DownloadsDropdownMenuView', () => { describe('getBounds', () => { it('should be placed top-left inside the downloads dropdown if coordinates not used', () => { const downloadsDropdownMenuView = new DownloadsDropdownMenuView(); - expect(downloadsDropdownMenuView.getBounds(DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT)).toStrictEqual({x: 800 - DOWNLOADS_DROPDOWN_FULL_WIDTH - DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, y: TAB_BAR_HEIGHT, width: DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, height: DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT}); + expect(downloadsDropdownMenuView.getBounds(800, DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT)).toStrictEqual({x: 800 - DOWNLOADS_DROPDOWN_FULL_WIDTH - DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, y: TAB_BAR_HEIGHT, width: DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, height: DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT}); }); }); it('should change the view bounds based on open/closed state', () => { const downloadsDropdownMenuView = new DownloadsDropdownMenuView(); + downloadsDropdownMenuView.init(); downloadsDropdownMenuView.bounds = {width: 400, height: 300}; downloadsDropdownMenuView.handleOpen(); expect(downloadsDropdownMenuView.view.setBounds).toBeCalledWith(downloadsDropdownMenuView.bounds); diff --git a/src/main/views/downloadsDropdownMenuView.ts b/src/main/views/downloadsDropdownMenuView.ts index 15d74a6c..513437ac 100644 --- a/src/main/views/downloadsDropdownMenuView.ts +++ b/src/main/views/downloadsDropdownMenuView.ts @@ -2,7 +2,6 @@ // See LICENSE.txt for license information. import {BrowserView, ipcMain, IpcMainEvent} from 'electron'; -import {CombinedConfig} from 'types/config'; import {CoordinatesToJsonType, DownloadedItem, DownloadsMenuOpenEventPayload} from 'types/downloads'; import { @@ -33,40 +32,35 @@ import WindowManager from 'main/windows/windowManager'; const log = new Logger('DownloadsDropdownMenuView'); -export default class DownloadsDropdownMenuView { - open: boolean; - view: BrowserView; - bounds: Electron.Rectangle; - item?: DownloadedItem; - coordinates?: CoordinatesToJsonType; - darkMode: boolean; - windowBounds: Electron.Rectangle; +export class DownloadsDropdownMenuView { + private open: boolean; + private view?: BrowserView; + private bounds?: Electron.Rectangle; + private item?: DownloadedItem; + private coordinates?: CoordinatesToJsonType; + private windowBounds?: Electron.Rectangle; constructor() { this.open = false; - this.item = undefined; - this.coordinates = undefined; - this.darkMode = Config.darkMode; ipcMain.on(OPEN_DOWNLOADS_DROPDOWN_MENU, this.handleOpen); ipcMain.on(CLOSE_DOWNLOADS_DROPDOWN_MENU, this.handleClose); ipcMain.on(TOGGLE_DOWNLOADS_DROPDOWN_MENU, this.handleToggle); - ipcMain.on(EMIT_CONFIGURATION, this.updateConfig); + ipcMain.on(EMIT_CONFIGURATION, this.updateDownloadsDropdownMenu); ipcMain.on(REQUEST_DOWNLOADS_DROPDOWN_MENU_INFO, this.updateDownloadsDropdownMenu); ipcMain.on(DOWNLOADS_DROPDOWN_MENU_OPEN_FILE, this.openFile); ipcMain.on(DOWNLOADS_DROPDOWN_MENU_SHOW_FILE_IN_FOLDER, this.showFileInFolder); ipcMain.on(DOWNLOADS_DROPDOWN_MENU_CANCEL_DOWNLOAD, this.cancelDownload); ipcMain.on(DOWNLOADS_DROPDOWN_MENU_CLEAR_FILE, this.clearFile); ipcMain.on(UPDATE_DOWNLOADS_DROPDOWN_MENU, this.updateItem); + } - const mainWindow = MainWindow.get(); - const windowBounds = MainWindow.getBounds(); - if (!(mainWindow && windowBounds)) { + init = () => { + this.windowBounds = MainWindow.getBounds(); + if (!this.windowBounds) { throw new Error('Cannot initialize downloadsDropdownMenuView, missing MainWindow'); } - - this.windowBounds = windowBounds; - this.bounds = this.getBounds(DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT); + this.bounds = this.getBounds(this.windowBounds.width, DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT); const preload = getLocalPreload('desktopAPI.js'); this.view = new BrowserView({webPreferences: { @@ -78,22 +72,7 @@ export default class DownloadsDropdownMenuView { transparent: true, }}); this.view.webContents.loadURL(getLocalURLString('downloadsDropdownMenu.html')); - mainWindow.addBrowserView(this.view); - } - - updateItem = (event: IpcMainEvent, item: DownloadedItem) => { - log.debug('updateItem', {item}); - - this.item = item; - - this.updateDownloadsDropdownMenu(); - } - - updateConfig = (event: IpcMainEvent, config: CombinedConfig) => { - log.debug('updateConfig'); - - this.darkMode = config.darkMode; - this.updateDownloadsDropdownMenu(); + MainWindow.get()?.addBrowserView(this.view); } /** @@ -103,30 +82,34 @@ export default class DownloadsDropdownMenuView { updateWindowBounds = () => { log.debug('updateWindowBounds'); - const mainWindow = MainWindow.get(); - if (mainWindow) { - this.windowBounds = mainWindow.getContentBounds(); - this.updateDownloadsDropdownMenu(); - this.repositionDownloadsDropdownMenu(); - } + this.windowBounds = MainWindow.getBounds(); + this.updateDownloadsDropdownMenu(); + this.repositionDownloadsDropdownMenu(); } - updateDownloadsDropdownMenu = () => { + private updateItem = (event: IpcMainEvent, item: DownloadedItem) => { + log.debug('updateItem', {item}); + + this.item = item; + this.updateDownloadsDropdownMenu(); + } + + private updateDownloadsDropdownMenu = () => { log.debug('updateDownloadsDropdownMenu'); - this.view.webContents.send( + this.view?.webContents.send( UPDATE_DOWNLOADS_DROPDOWN_MENU, this.item, - this.darkMode, + Config.darkMode, ); ipcMain.emit(UPDATE_DOWNLOADS_DROPDOWN_MENU_ITEM, true, this.item); this.repositionDownloadsDropdownMenu(); } - handleOpen = (event: IpcMainEvent, payload: DownloadsMenuOpenEventPayload = {} as DownloadsMenuOpenEventPayload) => { + private handleOpen = (event: IpcMainEvent, payload: DownloadsMenuOpenEventPayload = {} as DownloadsMenuOpenEventPayload) => { log.debug('handleOpen', {bounds: this.bounds, payload}); - if (!this.bounds) { + if (!(this.bounds && this.view && this.windowBounds)) { return; } @@ -137,24 +120,24 @@ export default class DownloadsDropdownMenuView { this.open = true; this.coordinates = coordinates; this.item = item; - this.bounds = this.getBounds(DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT); + this.bounds = this.getBounds(this.windowBounds.width, DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT); this.view.setBounds(this.bounds); MainWindow.get()?.setTopBrowserView(this.view); this.view.webContents.focus(); this.updateDownloadsDropdownMenu(); } - handleClose = () => { + private handleClose = () => { log.debug('handleClose'); this.open = false; this.item = undefined; ipcMain.emit(UPDATE_DOWNLOADS_DROPDOWN_MENU_ITEM); - this.view.setBounds(this.getBounds(0, 0)); + this.view?.setBounds(this.getBounds(this.windowBounds?.width ?? 0, 0, 0)); WindowManager.sendToRenderer(CLOSE_DOWNLOADS_DROPDOWN_MENU); } - handleToggle = (event: IpcMainEvent, payload: DownloadsMenuOpenEventPayload) => { + private handleToggle = (event: IpcMainEvent, payload: DownloadsMenuOpenEventPayload) => { if (this.open) { if (this.item?.location === payload.item.location) { // clicking 3-dot in the same item @@ -169,61 +152,60 @@ export default class DownloadsDropdownMenuView { } } - openFile = () => { + private openFile = () => { downloadsManager.openFile(this.item); this.handleClose(); } - showFileInFolder = (e: IpcMainEvent, item: DownloadedItem) => { + private showFileInFolder = (e: IpcMainEvent, item: DownloadedItem) => { downloadsManager.showFileInFolder(item); this.handleClose(); } - clearFile = () => { + private clearFile = () => { downloadsManager.clearFile(this.item); this.handleClose(); } - cancelDownload = () => { + private cancelDownload = () => { downloadsManager.cancelDownload(this.item); this.handleClose(); } - getBounds = (width: number, height: number) => { + private getBounds = (windowWidth: number, width: number, height: number) => { // MUST return integers return { - x: this.getX(), + x: this.getX(windowWidth), y: this.getY(), width: Math.round(width), height: Math.round(height), }; } - getX = () => { - const result = (this.windowBounds.width - DOWNLOADS_DROPDOWN_FULL_WIDTH - DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH) + (this.coordinates?.x || 0) + (this.coordinates?.width || 0); + private getX = (windowWidth: number) => { + const result = (windowWidth - DOWNLOADS_DROPDOWN_FULL_WIDTH - DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH) + (this.coordinates?.x || 0) + (this.coordinates?.width || 0); if (result <= DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH) { return 0; } return Math.round(result); } - getY = () => { + private getY = () => { const result = TAB_BAR_HEIGHT + (this.coordinates?.y || 0) + (this.coordinates?.height || 0); return Math.round(result); } - repositionDownloadsDropdownMenu = () => { - this.bounds = this.getBounds(DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT); + private repositionDownloadsDropdownMenu = () => { + if (!this.windowBounds) { + return; + } + + this.bounds = this.getBounds(this.windowBounds.width, DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT); if (this.open) { - this.view.setBounds(this.bounds); + this.view?.setBounds(this.bounds); } } - - destroy = () => { - // workaround to eliminate zombie processes - // https://github.com/mattermost/desktop/pull/1519 - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - this.view.webContents.destroy(); - } } + +const downloadsDropdownMenuView = new DownloadsDropdownMenuView(); +export default downloadsDropdownMenuView; diff --git a/src/main/views/downloadsDropdownView.test.js b/src/main/views/downloadsDropdownView.test.js index 15c00a5b..a7a24154 100644 --- a/src/main/views/downloadsDropdownView.test.js +++ b/src/main/views/downloadsDropdownView.test.js @@ -9,7 +9,7 @@ import {DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT, TAB_BAR_HEIGHT import MainWindow from 'main/windows/mainWindow'; -import DownloadsDropdownView from './downloadsDropdownView'; +import {DownloadsDropdownView} from './downloadsDropdownView'; jest.mock('main/utils', () => ({ getLocalPreload: (file) => file, @@ -81,20 +81,19 @@ describe('main/views/DownloadsDropdownView', () => { }); describe('getBounds', () => { it('should be placed far right when window is large enough', () => { - MainWindow.getBounds.mockReturnValue({width: 800, height: 600, x: 0, y: 0}); const downloadsDropdownView = new DownloadsDropdownView(); - expect(downloadsDropdownView.getBounds(DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT)).toStrictEqual({x: 800 - DOWNLOADS_DROPDOWN_FULL_WIDTH, y: TAB_BAR_HEIGHT, width: DOWNLOADS_DROPDOWN_FULL_WIDTH, height: DOWNLOADS_DROPDOWN_HEIGHT}); + expect(downloadsDropdownView.getBounds(800, DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT)).toStrictEqual({x: 800 - DOWNLOADS_DROPDOWN_FULL_WIDTH, y: TAB_BAR_HEIGHT, width: DOWNLOADS_DROPDOWN_FULL_WIDTH, height: DOWNLOADS_DROPDOWN_HEIGHT}); }); it('should be placed left if window is very small', () => { - MainWindow.getBounds.mockReturnValue({width: 500, height: 400, x: 0, y: 0}); const downloadsDropdownView = new DownloadsDropdownView(); - expect(downloadsDropdownView.getBounds(DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT)).toStrictEqual({x: 0, y: TAB_BAR_HEIGHT, width: DOWNLOADS_DROPDOWN_FULL_WIDTH, height: DOWNLOADS_DROPDOWN_HEIGHT}); + expect(downloadsDropdownView.getBounds(500, DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT)).toStrictEqual({x: 0, y: TAB_BAR_HEIGHT, width: DOWNLOADS_DROPDOWN_FULL_WIDTH, height: DOWNLOADS_DROPDOWN_HEIGHT}); }); }); it('should change the view bounds based on open/closed state', () => { MainWindow.getBounds.mockReturnValue({width: 800, height: 600, x: 0, y: 0}); const downloadsDropdownView = new DownloadsDropdownView(); + downloadsDropdownView.init(); downloadsDropdownView.bounds = {width: 400, height: 300}; downloadsDropdownView.handleOpen(); expect(downloadsDropdownView.view.setBounds).toBeCalledWith(downloadsDropdownView.bounds); diff --git a/src/main/views/downloadsDropdownView.ts b/src/main/views/downloadsDropdownView.ts index e57c1b0b..bf1fb3a1 100644 --- a/src/main/views/downloadsDropdownView.ts +++ b/src/main/views/downloadsDropdownView.ts @@ -3,8 +3,7 @@ import {BrowserView, ipcMain, IpcMainEvent, IpcMainInvokeEvent} from 'electron'; -import {CombinedConfig} from 'types/config'; -import {DownloadedItem, DownloadedItems} from 'types/downloads'; +import {DownloadedItem} from 'types/downloads'; import { CLOSE_DOWNLOADS_DROPDOWN, @@ -29,37 +28,31 @@ import MainWindow from 'main/windows/mainWindow'; const log = new Logger('DownloadsDropdownView'); -export default class DownloadsDropdownView { - bounds?: Electron.Rectangle; - darkMode: boolean; - downloads: DownloadedItems; - item?: DownloadedItem; - view: BrowserView; - windowBounds: Electron.Rectangle; +export class DownloadsDropdownView { + private bounds?: Electron.Rectangle; + private windowBounds?: Electron.Rectangle; + private item?: DownloadedItem; + private view?: BrowserView; constructor() { - this.downloads = downloadsManager.getDownloads(); - this.darkMode = Config.darkMode; - ipcMain.on(OPEN_DOWNLOADS_DROPDOWN, this.handleOpen); ipcMain.on(CLOSE_DOWNLOADS_DROPDOWN, this.handleClose); - ipcMain.on(EMIT_CONFIGURATION, this.updateConfig); + ipcMain.on(EMIT_CONFIGURATION, this.updateDownloadsDropdown); ipcMain.on(REQUEST_DOWNLOADS_DROPDOWN_INFO, this.updateDownloadsDropdown); ipcMain.on(REQUEST_CLEAR_DOWNLOADS_DROPDOWN, this.clearDownloads); ipcMain.on(RECEIVE_DOWNLOADS_DROPDOWN_SIZE, this.handleReceivedDownloadsDropdownSize); ipcMain.on(DOWNLOADS_DROPDOWN_OPEN_FILE, this.openFile); - ipcMain.on(UPDATE_DOWNLOADS_DROPDOWN, this.updateDownloads); + ipcMain.on(UPDATE_DOWNLOADS_DROPDOWN, this.updateDownloadsDropdown); ipcMain.on(UPDATE_DOWNLOADS_DROPDOWN_MENU_ITEM, this.updateDownloadsDropdownMenuItem); ipcMain.handle(GET_DOWNLOADED_IMAGE_THUMBNAIL_LOCATION, this.getDownloadImageThumbnailLocation); + } - const mainWindow = MainWindow.get(); - const windowBounds = MainWindow.getBounds(); - if (!(mainWindow && windowBounds)) { - throw new Error('Cannot initialize downloadsDropdownView, missing MainWindow'); + init = () => { + this.windowBounds = MainWindow.getBounds(); + if (!this.windowBounds) { + throw new Error('Cannot initialize, no main window'); } - - this.windowBounds = windowBounds; - this.bounds = this.getBounds(DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT); + this.bounds = this.getBounds(this.windowBounds.width, DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT); const preload = getLocalPreload('desktopAPI.js'); this.view = new BrowserView({webPreferences: { @@ -73,28 +66,7 @@ export default class DownloadsDropdownView { this.view.webContents.loadURL(getLocalURLString('downloadsDropdown.html')); this.view.webContents.session.webRequest.onHeadersReceived(downloadsManager.webRequestOnHeadersReceivedHandler); - mainWindow.addBrowserView(this.view); - } - - updateDownloads = (event: IpcMainEvent, downloads: DownloadedItems) => { - log.debug('updateDownloads', {downloads}); - - this.downloads = downloads; - - this.updateDownloadsDropdown(); - } - - updateDownloadsDropdownMenuItem = (event: IpcMainEvent, item?: DownloadedItem) => { - log.debug('updateDownloadsDropdownMenuItem', {item}); - this.item = item; - this.updateDownloadsDropdown(); - } - - updateConfig = (event: IpcMainEvent, config: CombinedConfig) => { - log.debug('updateConfig'); - - this.darkMode = config.darkMode; - this.updateDownloadsDropdown(); + MainWindow.get()?.addBrowserView(this.view); } /** @@ -104,30 +76,33 @@ export default class DownloadsDropdownView { updateWindowBounds = () => { log.debug('updateWindowBounds'); - const mainWindow = MainWindow.get(); - if (mainWindow) { - this.windowBounds = mainWindow.getContentBounds(); - this.updateDownloadsDropdown(); - this.repositionDownloadsDropdown(); - } + this.windowBounds = MainWindow.getBounds(); + this.updateDownloadsDropdown(); + this.repositionDownloadsDropdown(); } - updateDownloadsDropdown = () => { + private updateDownloadsDropdownMenuItem = (event: IpcMainEvent, item?: DownloadedItem) => { + log.debug('updateDownloadsDropdownMenuItem', {item}); + this.item = item; + this.updateDownloadsDropdown(); + } + + private updateDownloadsDropdown = () => { log.debug('updateDownloadsDropdown'); - this.view.webContents.send( + this.view?.webContents.send( UPDATE_DOWNLOADS_DROPDOWN, - this.downloads, - this.darkMode, - this.windowBounds, + downloadsManager.getDownloads(), + Config.darkMode, + MainWindow.getBounds(), this.item, ); } - handleOpen = () => { + private handleOpen = () => { log.debug('handleOpen', {bounds: this.bounds}); - if (!this.bounds) { + if (!(this.bounds && this.view)) { return; } @@ -138,36 +113,36 @@ export default class DownloadsDropdownView { WindowManager.sendToRenderer(OPEN_DOWNLOADS_DROPDOWN); } - handleClose = () => { + private handleClose = () => { log.debug('handleClose'); - this.view.setBounds(this.getBounds(0, 0)); + this.view?.setBounds(this.getBounds(this.windowBounds?.width ?? 0, 0, 0)); downloadsManager.onClose(); WindowManager.sendToRenderer(CLOSE_DOWNLOADS_DROPDOWN); } - clearDownloads = () => { + private clearDownloads = () => { downloadsManager.clearDownloadsDropDown(); this.handleClose(); } - openFile = (e: IpcMainEvent, item: DownloadedItem) => { + private openFile = (e: IpcMainEvent, item: DownloadedItem) => { log.debug('openFile', {item}); downloadsManager.openFile(item); } - getBounds = (width: number, height: number) => { + private getBounds = (windowWidth: number, width: number, height: number) => { // Must always use integers return { - x: this.getX(this.windowBounds.width), + x: this.getX(windowWidth), y: this.getY(), width: Math.round(width), height: Math.round(height), }; } - getX = (windowWidth: number) => { + private getX = (windowWidth: number) => { const result = windowWidth - DOWNLOADS_DROPDOWN_FULL_WIDTH; if (result <= DOWNLOADS_DROPDOWN_WIDTH) { return 0; @@ -175,11 +150,11 @@ export default class DownloadsDropdownView { return Math.round(result); } - getY = () => { + private getY = () => { return Math.round(TAB_BAR_HEIGHT); } - repositionDownloadsDropdown = () => { + private repositionDownloadsDropdown = () => { if (!(this.bounds && this.windowBounds)) { return; } @@ -189,28 +164,27 @@ export default class DownloadsDropdownView { y: this.getY(), }; if (downloadsManager.getIsOpen()) { - this.view.setBounds(this.bounds); + this.view?.setBounds(this.bounds); } } - handleReceivedDownloadsDropdownSize = (event: IpcMainEvent, width: number, height: number) => { + private handleReceivedDownloadsDropdownSize = (event: IpcMainEvent, width: number, height: number) => { log.silly('handleReceivedDownloadsDropdownSize', {width, height}); - this.bounds = this.getBounds(width, height); + if (!this.windowBounds) { + return; + } + + this.bounds = this.getBounds(this.windowBounds.width, width, height); if (downloadsManager.getIsOpen()) { - this.view.setBounds(this.bounds); + this.view?.setBounds(this.bounds); } } - destroy = () => { - // workaround to eliminate zombie processes - // https://github.com/mattermost/desktop/pull/1519 - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - this.view.webContents.destroy(); - } - - getDownloadImageThumbnailLocation = (event: IpcMainInvokeEvent, location: string) => { + private getDownloadImageThumbnailLocation = (event: IpcMainInvokeEvent, location: string) => { return location; } } + +const downloadsDropdownView = new DownloadsDropdownView(); +export default downloadsDropdownView; diff --git a/src/main/windows/windowManager.test.js b/src/main/windows/windowManager.test.js index 9b5310d3..fcb7920b 100644 --- a/src/main/windows/windowManager.test.js +++ b/src/main/windows/windowManager.test.js @@ -76,8 +76,12 @@ jest.mock('../views/loadingScreen', () => ({ jest.mock('../views/teamDropdownView', () => ({ updateWindowBounds: jest.fn(), })); -jest.mock('../views/downloadsDropdownView', () => jest.fn()); -jest.mock('../views/downloadsDropdownMenuView', () => jest.fn()); +jest.mock('../views/downloadsDropdownView', () => ({ + updateWindowBounds: jest.fn(), +})); +jest.mock('../views/downloadsDropdownMenuView', () => ({ + updateWindowBounds: jest.fn(), +})); jest.mock('./settingsWindow', () => ({ show: jest.fn(), get: jest.fn(), diff --git a/src/main/windows/windowManager.ts b/src/main/windows/windowManager.ts index 70cde426..f751f33e 100644 --- a/src/main/windows/windowManager.ts +++ b/src/main/windows/windowManager.ts @@ -44,9 +44,6 @@ import SettingsWindow from './settingsWindow'; const log = new Logger('WindowManager'); export class WindowManager { - private downloadsDropdown?: DownloadsDropdownView; - private downloadsDropdownMenu?: DownloadsDropdownMenuView; - private isResizing: boolean; constructor() { @@ -98,11 +95,10 @@ export class WindowManager { mainWindow.on('enter-full-screen', () => this.sendToRenderer('enter-full-screen')); mainWindow.on('leave-full-screen', () => this.sendToRenderer('leave-full-screen')); - this.downloadsDropdown = new DownloadsDropdownView(); - this.downloadsDropdownMenu = new DownloadsDropdownMenuView(); - this.initializeViewManager(); TeamDropdownView.init(); + DownloadsDropdownView.init(); + DownloadsDropdownMenuView.init(); } // max retries allows the message to get to the renderer even if it is sent while the app is starting up. @@ -240,14 +236,14 @@ export class WindowManager { *****************/ private handleMaximizeMainWindow = () => { - this.downloadsDropdown?.updateWindowBounds(); - this.downloadsDropdownMenu?.updateWindowBounds(); + DownloadsDropdownView.updateWindowBounds(); + DownloadsDropdownMenuView.updateWindowBounds(); this.sendToRenderer(MAXIMIZE_CHANGE, true); } private handleUnmaximizeMainWindow = () => { - this.downloadsDropdown?.updateWindowBounds(); - this.downloadsDropdownMenu?.updateWindowBounds(); + DownloadsDropdownView.updateWindowBounds(); + DownloadsDropdownMenuView.updateWindowBounds(); this.sendToRenderer(MAXIMIZE_CHANGE, false); } @@ -276,8 +272,8 @@ export class WindowManager { this.throttledWillResize(newBounds); LoadingScreen.setBounds(); TeamDropdownView.updateWindowBounds(); - this.downloadsDropdown?.updateWindowBounds(); - this.downloadsDropdownMenu?.updateWindowBounds(); + DownloadsDropdownView.updateWindowBounds(); + DownloadsDropdownMenuView.updateWindowBounds(); ipcMain.emit(RESIZE_MODAL, null, newBounds); } @@ -288,8 +284,8 @@ export class WindowManager { this.throttledWillResize(bounds); ipcMain.emit(RESIZE_MODAL, null, bounds); TeamDropdownView.updateWindowBounds(); - this.downloadsDropdown?.updateWindowBounds(); - this.downloadsDropdownMenu?.updateWindowBounds(); + DownloadsDropdownView.updateWindowBounds(); + DownloadsDropdownMenuView.updateWindowBounds(); this.isResizing = false; } @@ -318,8 +314,8 @@ export class WindowManager { LoadingScreen.setBounds(); TeamDropdownView.updateWindowBounds(); - this.downloadsDropdown?.updateWindowBounds(); - this.downloadsDropdownMenu?.updateWindowBounds(); + DownloadsDropdownView.updateWindowBounds(); + DownloadsDropdownMenuView.updateWindowBounds(); ipcMain.emit(RESIZE_MODAL, null, bounds); };