[MM-51871] Migrate mainWindow and settingsWindow to singletons (#2650)
* Migrate mainWindow to singleton * Migrate settingsWindow to singleton * PR feedback * Missed a couple unwrapping cases
This commit is contained in:
@@ -7,6 +7,7 @@ import {LOAD_FAILED, TOGGLE_BACK_BUTTON, UPDATE_TARGET_URL} from 'common/communi
|
||||
import {MattermostServer} from 'common/servers/MattermostServer';
|
||||
import MessagingTabView from 'common/tabs/MessagingTabView';
|
||||
|
||||
import MainWindow from '../windows/mainWindow';
|
||||
import * as WindowManager from '../windows/windowManager';
|
||||
import * as appState from '../appState';
|
||||
import Utils from '../utils';
|
||||
@@ -30,9 +31,12 @@ jest.mock('electron', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('../windows/mainWindow', () => ({
|
||||
focusThreeDotMenu: jest.fn(),
|
||||
get: jest.fn(),
|
||||
}));
|
||||
jest.mock('../windows/windowManager', () => ({
|
||||
sendToRenderer: jest.fn(),
|
||||
focusThreeDotMenu: jest.fn(),
|
||||
}));
|
||||
jest.mock('../appState', () => ({
|
||||
updateMentions: jest.fn(),
|
||||
@@ -54,9 +58,10 @@ const tabView = new MessagingTabView(server);
|
||||
describe('main/views/MattermostView', () => {
|
||||
describe('load', () => {
|
||||
const window = {on: jest.fn()};
|
||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||
const mattermostView = new MattermostView(tabView, {}, {});
|
||||
|
||||
beforeEach(() => {
|
||||
MainWindow.get.mockReturnValue(window);
|
||||
mattermostView.loadSuccess = jest.fn();
|
||||
mattermostView.loadRetry = jest.fn();
|
||||
});
|
||||
@@ -112,11 +117,12 @@ describe('main/views/MattermostView', () => {
|
||||
|
||||
describe('retry', () => {
|
||||
const window = {on: jest.fn()};
|
||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||
const mattermostView = new MattermostView(tabView, {}, {});
|
||||
const retryInBackgroundFn = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
MainWindow.get.mockReturnValue(window);
|
||||
mattermostView.view.webContents.loadURL.mockImplementation(() => Promise.resolve());
|
||||
mattermostView.loadSuccess = jest.fn();
|
||||
mattermostView.loadRetry = jest.fn();
|
||||
@@ -175,10 +181,11 @@ describe('main/views/MattermostView', () => {
|
||||
|
||||
describe('loadSuccess', () => {
|
||||
const window = {on: jest.fn()};
|
||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||
const mattermostView = new MattermostView(tabView, {}, {});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
MainWindow.get.mockReturnValue(window);
|
||||
mattermostView.emit = jest.fn();
|
||||
mattermostView.setBounds = jest.fn();
|
||||
mattermostView.setInitialized = jest.fn();
|
||||
@@ -202,10 +209,11 @@ describe('main/views/MattermostView', () => {
|
||||
|
||||
describe('show', () => {
|
||||
const window = {addBrowserView: jest.fn(), removeBrowserView: jest.fn(), on: jest.fn()};
|
||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||
const mattermostView = new MattermostView(tabView, {}, {});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
MainWindow.get.mockReturnValue(window);
|
||||
mattermostView.setBounds = jest.fn();
|
||||
mattermostView.focus = jest.fn();
|
||||
});
|
||||
@@ -253,9 +261,10 @@ describe('main/views/MattermostView', () => {
|
||||
|
||||
describe('destroy', () => {
|
||||
const window = {removeBrowserView: jest.fn(), on: jest.fn()};
|
||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||
const mattermostView = new MattermostView(tabView, {}, {});
|
||||
|
||||
beforeEach(() => {
|
||||
MainWindow.get.mockReturnValue(window);
|
||||
mattermostView.view.webContents.destroy = jest.fn();
|
||||
});
|
||||
|
||||
@@ -280,17 +289,18 @@ describe('main/views/MattermostView', () => {
|
||||
|
||||
describe('handleInputEvents', () => {
|
||||
const window = {on: jest.fn()};
|
||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||
const mattermostView = new MattermostView(tabView, {}, {});
|
||||
|
||||
it('should open three dot menu on pressing Alt', () => {
|
||||
MainWindow.get.mockReturnValue(window);
|
||||
mattermostView.handleInputEvents(null, {key: 'Alt', type: 'keyDown', alt: true, shift: false, control: false, meta: false});
|
||||
mattermostView.handleInputEvents(null, {key: 'Alt', type: 'keyUp'});
|
||||
expect(WindowManager.focusThreeDotMenu).toHaveBeenCalled();
|
||||
expect(MainWindow.focusThreeDotMenu).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not open three dot menu on holding Alt', () => {
|
||||
mattermostView.handleInputEvents(null, {key: 'Alt', type: 'keyDown'});
|
||||
expect(WindowManager.focusThreeDotMenu).not.toHaveBeenCalled();
|
||||
expect(MainWindow.focusThreeDotMenu).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not open three dot menu on Alt as key combp', () => {
|
||||
@@ -298,15 +308,16 @@ describe('main/views/MattermostView', () => {
|
||||
mattermostView.handleInputEvents(null, {key: 'F', type: 'keyDown'});
|
||||
mattermostView.handleInputEvents(null, {key: 'F', type: 'keyUp'});
|
||||
mattermostView.handleInputEvents(null, {key: 'Alt', type: 'keyUp'});
|
||||
expect(WindowManager.focusThreeDotMenu).not.toHaveBeenCalled();
|
||||
expect(MainWindow.focusThreeDotMenu).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleDidNavigate', () => {
|
||||
const window = {on: jest.fn()};
|
||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||
const mattermostView = new MattermostView(tabView, {}, {});
|
||||
|
||||
beforeEach(() => {
|
||||
MainWindow.get.mockReturnValue(window);
|
||||
mattermostView.setBounds = jest.fn();
|
||||
});
|
||||
|
||||
@@ -325,9 +336,10 @@ describe('main/views/MattermostView', () => {
|
||||
|
||||
describe('handleUpdateTarget', () => {
|
||||
const window = {on: jest.fn()};
|
||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||
const mattermostView = new MattermostView(tabView, {}, {});
|
||||
|
||||
beforeEach(() => {
|
||||
MainWindow.get.mockReturnValue(window);
|
||||
mattermostView.emit = jest.fn();
|
||||
});
|
||||
|
||||
@@ -355,8 +367,7 @@ describe('main/views/MattermostView', () => {
|
||||
});
|
||||
|
||||
describe('updateMentionsFromTitle', () => {
|
||||
const window = {on: jest.fn()};
|
||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||
const mattermostView = new MattermostView(tabView, {}, {});
|
||||
|
||||
it('should parse mentions from title', () => {
|
||||
mattermostView.updateMentionsFromTitle('(7) Mattermost');
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {BrowserView, app, ipcMain, BrowserWindow} from 'electron';
|
||||
import {BrowserView, app, ipcMain} from 'electron';
|
||||
import {BrowserViewConstructorOptions, Event, Input} from 'electron/main';
|
||||
import log from 'electron-log';
|
||||
|
||||
@@ -25,6 +25,8 @@ import {MattermostServer} from 'common/servers/MattermostServer';
|
||||
import {TabView, TabTuple} from 'common/tabs/TabView';
|
||||
|
||||
import {ServerInfo} from 'main/server/serverInfo';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
import ContextMenu from '../contextMenu';
|
||||
import {getWindowBoundaries, getLocalPreload, composeUserAgent, shouldHaveBackBar} from '../utils';
|
||||
import WindowManager from '../windows/windowManager';
|
||||
@@ -43,7 +45,6 @@ const MENTIONS_GROUP = 2;
|
||||
|
||||
export class MattermostView extends EventEmitter {
|
||||
tab: TabView;
|
||||
window: BrowserWindow;
|
||||
view: BrowserView;
|
||||
isVisible: boolean;
|
||||
isLoggedIn: boolean;
|
||||
@@ -63,10 +64,9 @@ export class MattermostView extends EventEmitter {
|
||||
|
||||
private altPressStatus: boolean;
|
||||
|
||||
constructor(tab: TabView, serverInfo: ServerInfo, win: BrowserWindow, options: BrowserViewConstructorOptions) {
|
||||
constructor(tab: TabView, serverInfo: ServerInfo, options: BrowserViewConstructorOptions) {
|
||||
super();
|
||||
this.tab = tab;
|
||||
this.window = win;
|
||||
this.serverInfo = serverInfo;
|
||||
|
||||
const preload = getLocalPreload('preload.js');
|
||||
@@ -118,7 +118,7 @@ export class MattermostView extends EventEmitter {
|
||||
|
||||
this.altPressStatus = false;
|
||||
|
||||
this.window.on('blur', () => {
|
||||
MainWindow.get()?.on('blur', () => {
|
||||
this.altPressStatus = false;
|
||||
});
|
||||
}
|
||||
@@ -224,6 +224,11 @@ export class MattermostView extends EventEmitter {
|
||||
|
||||
loadSuccess = (loadURL: string) => {
|
||||
return () => {
|
||||
const mainWindow = MainWindow.get();
|
||||
if (!mainWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.verbose(`[${Util.shorten(this.tab.name)}] finished loading ${loadURL}`);
|
||||
WindowManager.sendToRenderer(LOAD_SUCCESS, this.tab.name);
|
||||
this.maxRetries = MAX_SERVER_RETRIES;
|
||||
@@ -235,21 +240,26 @@ export class MattermostView extends EventEmitter {
|
||||
this.status = Status.WAITING_MM;
|
||||
this.removeLoading = setTimeout(this.setInitialized, MAX_LOADING_SCREEN_SECONDS, true);
|
||||
this.emit(LOAD_SUCCESS, this.tab.name, loadURL);
|
||||
this.setBounds(getWindowBoundaries(this.window, shouldHaveBackBar(this.tab.url || '', this.view.webContents.getURL())));
|
||||
this.setBounds(getWindowBoundaries(mainWindow, shouldHaveBackBar(this.tab.url || '', this.view.webContents.getURL())));
|
||||
};
|
||||
}
|
||||
|
||||
show = (requestedVisibility?: boolean) => {
|
||||
const mainWindow = MainWindow.get();
|
||||
if (!mainWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hasBeenShown = true;
|
||||
const request = typeof requestedVisibility === 'undefined' ? true : requestedVisibility;
|
||||
if (request && !this.isVisible) {
|
||||
this.window.addBrowserView(this.view);
|
||||
this.setBounds(getWindowBoundaries(this.window, shouldHaveBackBar(this.tab.url || '', this.view.webContents.getURL())));
|
||||
mainWindow.addBrowserView(this.view);
|
||||
this.setBounds(getWindowBoundaries(mainWindow, shouldHaveBackBar(this.tab.url || '', this.view.webContents.getURL())));
|
||||
if (this.status === Status.READY) {
|
||||
this.focus();
|
||||
}
|
||||
} else if (!request && this.isVisible) {
|
||||
this.window.removeBrowserView(this.view);
|
||||
mainWindow.removeBrowserView(this.view);
|
||||
}
|
||||
this.isVisible = request;
|
||||
}
|
||||
@@ -268,9 +278,7 @@ export class MattermostView extends EventEmitter {
|
||||
destroy = () => {
|
||||
WebContentsEventManager.removeWebContentsListeners(this.view.webContents.id);
|
||||
appState.updateMentions(this.tab.name, 0, false);
|
||||
if (this.window) {
|
||||
this.window.removeBrowserView(this.view);
|
||||
}
|
||||
MainWindow.get()?.removeBrowserView(this.view);
|
||||
|
||||
// workaround to eliminate zombie processes
|
||||
// https://github.com/mattermost/desktop/pull/1519
|
||||
@@ -352,7 +360,7 @@ export class MattermostView extends EventEmitter {
|
||||
this.registerAltKeyPressed(input);
|
||||
|
||||
if (this.isAltKeyReleased(input)) {
|
||||
WindowManager.focusThreeDotMenu();
|
||||
MainWindow.focusThreeDotMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,11 +368,11 @@ export class MattermostView extends EventEmitter {
|
||||
log.debug('MattermostView.handleDidNavigate', {tabName: this.tab.name, url});
|
||||
|
||||
if (shouldHaveBackBar(this.tab.url || '', url)) {
|
||||
this.setBounds(getWindowBoundaries(this.window, true));
|
||||
this.setBounds(getWindowBoundaries(MainWindow.get()!, true));
|
||||
WindowManager.sendToRenderer(TOGGLE_BACK_BUTTON, true);
|
||||
log.info('show back button');
|
||||
} else {
|
||||
this.setBounds(getWindowBoundaries(this.window));
|
||||
this.setBounds(getWindowBoundaries(MainWindow.get()!));
|
||||
WindowManager.sendToRenderer(TOGGLE_BACK_BUTTON, false);
|
||||
log.info('hide back button');
|
||||
}
|
||||
|
@@ -7,6 +7,8 @@ import {getDoNotDisturb as getDarwinDoNotDisturb} from 'macos-notification-state
|
||||
|
||||
import {DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT, DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, TAB_BAR_HEIGHT} from 'common/utils/constants';
|
||||
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
import DownloadsDropdownMenuView from './downloadsDropdownMenuView';
|
||||
|
||||
jest.mock('main/utils', () => ({
|
||||
@@ -50,6 +52,11 @@ jest.mock('electron', () => {
|
||||
jest.mock('macos-notification-state', () => ({
|
||||
getDoNotDisturb: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/downloadsManager', () => ({}));
|
||||
jest.mock('main/windows/mainWindow', () => ({
|
||||
get: jest.fn(),
|
||||
getBounds: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/windows/windowManager', () => ({
|
||||
sendToRenderer: jest.fn(),
|
||||
}));
|
||||
@@ -60,24 +67,21 @@ jest.mock('fs', () => ({
|
||||
}));
|
||||
|
||||
describe('main/views/DownloadsDropdownMenuView', () => {
|
||||
const window = {
|
||||
getContentBounds: () => ({width: 800, height: 600, x: 0, y: 0}),
|
||||
addBrowserView: jest.fn(),
|
||||
setTopBrowserView: jest.fn(),
|
||||
};
|
||||
const downloadsDropdownMenuView = new DownloadsDropdownMenuView(window, {}, false);
|
||||
|
||||
beforeEach(() => {
|
||||
MainWindow.get.mockReturnValue({addBrowserView: jest.fn(), setTopBrowserView: jest.fn()});
|
||||
MainWindow.getBounds.mockReturnValue({width: 800, height: 600, x: 0, y: 0});
|
||||
getDarwinDoNotDisturb.mockReturnValue(false);
|
||||
});
|
||||
|
||||
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});
|
||||
});
|
||||
});
|
||||
|
||||
it('should change the view bounds based on open/closed state', () => {
|
||||
const downloadsDropdownMenuView = new DownloadsDropdownMenuView();
|
||||
downloadsDropdownMenuView.bounds = {width: 400, height: 300};
|
||||
downloadsDropdownMenuView.handleOpen();
|
||||
expect(downloadsDropdownMenuView.view.setBounds).toBeCalledWith(downloadsDropdownMenuView.bounds);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {BrowserView, BrowserWindow, ipcMain, IpcMainEvent} from 'electron';
|
||||
import {BrowserView, ipcMain, IpcMainEvent} from 'electron';
|
||||
|
||||
import log from 'electron-log';
|
||||
|
||||
@@ -30,40 +30,23 @@ import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||
|
||||
import WindowManager from '../windows/windowManager';
|
||||
import downloadsManager from 'main/downloadsManager';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
export default class DownloadsDropdownMenuView {
|
||||
open: boolean;
|
||||
view: BrowserView;
|
||||
bounds?: Electron.Rectangle;
|
||||
bounds: Electron.Rectangle;
|
||||
item?: DownloadedItem;
|
||||
coordinates?: CoordinatesToJsonType;
|
||||
darkMode: boolean;
|
||||
window: BrowserWindow;
|
||||
windowBounds: Electron.Rectangle;
|
||||
|
||||
constructor(window: BrowserWindow, darkMode: boolean) {
|
||||
constructor(darkMode: boolean) {
|
||||
this.open = false;
|
||||
this.item = undefined;
|
||||
this.coordinates = undefined;
|
||||
this.window = window;
|
||||
this.darkMode = darkMode;
|
||||
|
||||
this.windowBounds = this.window.getContentBounds();
|
||||
this.bounds = this.getBounds(DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT);
|
||||
|
||||
const preload = getLocalPreload('desktopAPI.js');
|
||||
this.view = new BrowserView({webPreferences: {
|
||||
preload,
|
||||
|
||||
// Workaround for this issue: https://github.com/electron/electron/issues/30993
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
transparent: true,
|
||||
}});
|
||||
|
||||
this.view.webContents.loadURL(getLocalURLString('downloadsDropdownMenu.html'));
|
||||
this.window.addBrowserView(this.view);
|
||||
|
||||
ipcMain.on(OPEN_DOWNLOADS_DROPDOWN_MENU, this.handleOpen);
|
||||
ipcMain.on(CLOSE_DOWNLOADS_DROPDOWN_MENU, this.handleClose);
|
||||
ipcMain.on(TOGGLE_DOWNLOADS_DROPDOWN_MENU, this.handleToggle);
|
||||
@@ -74,6 +57,27 @@ export default class DownloadsDropdownMenuView {
|
||||
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)) {
|
||||
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);
|
||||
|
||||
const preload = getLocalPreload('desktopAPI.js');
|
||||
this.view = new BrowserView({webPreferences: {
|
||||
preload,
|
||||
|
||||
// Workaround for this issue: https://github.com/electron/electron/issues/30993
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
transparent: true,
|
||||
}});
|
||||
this.view.webContents.loadURL(getLocalURLString('downloadsDropdownMenu.html'));
|
||||
mainWindow.addBrowserView(this.view);
|
||||
}
|
||||
|
||||
updateItem = (event: IpcMainEvent, item: DownloadedItem) => {
|
||||
@@ -98,9 +102,12 @@ export default class DownloadsDropdownMenuView {
|
||||
updateWindowBounds = () => {
|
||||
log.debug('DownloadsDropdownMenuView.updateWindowBounds');
|
||||
|
||||
this.windowBounds = this.window.getContentBounds();
|
||||
this.updateDownloadsDropdownMenu();
|
||||
this.repositionDownloadsDropdownMenu();
|
||||
const mainWindow = MainWindow.get();
|
||||
if (mainWindow) {
|
||||
this.windowBounds = mainWindow.getContentBounds();
|
||||
this.updateDownloadsDropdownMenu();
|
||||
this.repositionDownloadsDropdownMenu();
|
||||
}
|
||||
}
|
||||
|
||||
updateDownloadsDropdownMenu = () => {
|
||||
@@ -131,7 +138,7 @@ export default class DownloadsDropdownMenuView {
|
||||
this.item = item;
|
||||
this.bounds = this.getBounds(DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT);
|
||||
this.view.setBounds(this.bounds);
|
||||
this.window.setTopBrowserView(this.view);
|
||||
MainWindow.get()?.setTopBrowserView(this.view);
|
||||
this.view.webContents.focus();
|
||||
this.updateDownloadsDropdownMenu();
|
||||
}
|
||||
|
@@ -7,6 +7,8 @@ import {getDoNotDisturb as getDarwinDoNotDisturb} from 'macos-notification-state
|
||||
|
||||
import {DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT, TAB_BAR_HEIGHT} from 'common/utils/constants';
|
||||
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
import DownloadsDropdownView from './downloadsDropdownView';
|
||||
|
||||
jest.mock('main/utils', () => ({
|
||||
@@ -59,42 +61,35 @@ jest.mock('electron', () => {
|
||||
Notification: NotificationMock,
|
||||
};
|
||||
});
|
||||
jest.mock('main/windows/mainWindow', () => ({
|
||||
get: jest.fn(),
|
||||
getBounds: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/windows/windowManager', () => ({
|
||||
sendToRenderer: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('main/views/DownloadsDropdownView', () => {
|
||||
beforeEach(() => {
|
||||
MainWindow.get.mockReturnValue({addBrowserView: jest.fn(), setTopBrowserView: jest.fn()});
|
||||
getDarwinDoNotDisturb.mockReturnValue(false);
|
||||
});
|
||||
describe('getBounds', () => {
|
||||
it('should be placed far right when window is large enough', () => {
|
||||
const window = {
|
||||
getContentBounds: () => ({width: 800, height: 600, x: 0, y: 0}),
|
||||
addBrowserView: jest.fn(),
|
||||
setTopBrowserView: jest.fn(),
|
||||
};
|
||||
const downloadsDropdownView = new DownloadsDropdownView(window, {}, false);
|
||||
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});
|
||||
});
|
||||
it('should be placed left if window is very small', () => {
|
||||
const window = {
|
||||
getContentBounds: () => ({width: 500, height: 400, x: 0, y: 0}),
|
||||
addBrowserView: jest.fn(),
|
||||
setTopBrowserView: jest.fn(),
|
||||
};
|
||||
const downloadsDropdownView = new DownloadsDropdownView(window, {}, false);
|
||||
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});
|
||||
});
|
||||
});
|
||||
|
||||
it('should change the view bounds based on open/closed state', () => {
|
||||
const window = {
|
||||
getContentBounds: () => ({width: 800, height: 600, x: 0, y: 0}),
|
||||
addBrowserView: jest.fn(),
|
||||
setTopBrowserView: jest.fn(),
|
||||
};
|
||||
const downloadsDropdownView = new DownloadsDropdownView(window, {}, false);
|
||||
MainWindow.getBounds.mockReturnValue({width: 800, height: 600, x: 0, y: 0});
|
||||
const downloadsDropdownView = new DownloadsDropdownView();
|
||||
downloadsDropdownView.bounds = {width: 400, height: 300};
|
||||
downloadsDropdownView.handleOpen();
|
||||
expect(downloadsDropdownView.view.setBounds).toBeCalledWith(downloadsDropdownView.bounds);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {BrowserView, BrowserWindow, ipcMain, IpcMainEvent, IpcMainInvokeEvent} from 'electron';
|
||||
import {BrowserView, ipcMain, IpcMainEvent, IpcMainInvokeEvent} from 'electron';
|
||||
|
||||
import log from 'electron-log';
|
||||
|
||||
@@ -25,23 +25,38 @@ import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||
|
||||
import WindowManager from '../windows/windowManager';
|
||||
import downloadsManager from 'main/downloadsManager';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
export default class DownloadsDropdownView {
|
||||
bounds?: Electron.Rectangle;
|
||||
darkMode: boolean;
|
||||
downloads: DownloadedItems;
|
||||
item: DownloadedItem | undefined;
|
||||
item?: DownloadedItem;
|
||||
view: BrowserView;
|
||||
window: BrowserWindow;
|
||||
windowBounds: Electron.Rectangle;
|
||||
|
||||
constructor(window: BrowserWindow, downloads: DownloadedItems, darkMode: boolean) {
|
||||
constructor(downloads: DownloadedItems, darkMode: boolean) {
|
||||
this.downloads = downloads;
|
||||
this.window = window;
|
||||
this.darkMode = darkMode;
|
||||
this.item = undefined;
|
||||
|
||||
this.windowBounds = this.window.getContentBounds();
|
||||
ipcMain.on(OPEN_DOWNLOADS_DROPDOWN, this.handleOpen);
|
||||
ipcMain.on(CLOSE_DOWNLOADS_DROPDOWN, this.handleClose);
|
||||
ipcMain.on(EMIT_CONFIGURATION, this.updateConfig);
|
||||
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_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');
|
||||
}
|
||||
|
||||
this.windowBounds = windowBounds;
|
||||
this.bounds = this.getBounds(DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT);
|
||||
|
||||
const preload = getLocalPreload('desktopAPI.js');
|
||||
@@ -55,20 +70,8 @@ export default class DownloadsDropdownView {
|
||||
}});
|
||||
|
||||
this.view.webContents.loadURL(getLocalURLString('downloadsDropdown.html'));
|
||||
this.window.addBrowserView(this.view);
|
||||
|
||||
this.view.webContents.session.webRequest.onHeadersReceived(downloadsManager.webRequestOnHeadersReceivedHandler);
|
||||
|
||||
ipcMain.on(OPEN_DOWNLOADS_DROPDOWN, this.handleOpen);
|
||||
ipcMain.on(CLOSE_DOWNLOADS_DROPDOWN, this.handleClose);
|
||||
ipcMain.on(EMIT_CONFIGURATION, this.updateConfig);
|
||||
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_MENU_ITEM, this.updateDownloadsDropdownMenuItem);
|
||||
ipcMain.handle(GET_DOWNLOADED_IMAGE_THUMBNAIL_LOCATION, this.getDownloadImageThumbnailLocation);
|
||||
mainWindow.addBrowserView(this.view);
|
||||
}
|
||||
|
||||
updateDownloads = (event: IpcMainEvent, downloads: DownloadedItems) => {
|
||||
@@ -99,9 +102,12 @@ export default class DownloadsDropdownView {
|
||||
updateWindowBounds = () => {
|
||||
log.debug('DownloadsDropdownView.updateWindowBounds');
|
||||
|
||||
this.windowBounds = this.window.getContentBounds();
|
||||
this.updateDownloadsDropdown();
|
||||
this.repositionDownloadsDropdown();
|
||||
const mainWindow = MainWindow.get();
|
||||
if (mainWindow) {
|
||||
this.windowBounds = mainWindow.getContentBounds();
|
||||
this.updateDownloadsDropdown();
|
||||
this.repositionDownloadsDropdown();
|
||||
}
|
||||
}
|
||||
|
||||
updateDownloadsDropdown = () => {
|
||||
@@ -124,7 +130,7 @@ export default class DownloadsDropdownView {
|
||||
}
|
||||
|
||||
this.view.setBounds(this.bounds);
|
||||
this.window.setTopBrowserView(this.view);
|
||||
MainWindow.get()?.setTopBrowserView(this.view);
|
||||
this.view.webContents.focus();
|
||||
downloadsManager.onOpen();
|
||||
WindowManager.sendToRenderer(OPEN_DOWNLOADS_DROPDOWN);
|
||||
@@ -172,7 +178,7 @@ export default class DownloadsDropdownView {
|
||||
}
|
||||
|
||||
repositionDownloadsDropdown = () => {
|
||||
if (!this.bounds) {
|
||||
if (!(this.bounds && this.windowBounds)) {
|
||||
return;
|
||||
}
|
||||
this.bounds = {
|
||||
|
@@ -5,6 +5,8 @@
|
||||
|
||||
import {TAB_BAR_HEIGHT, THREE_DOT_MENU_WIDTH, THREE_DOT_MENU_WIDTH_MAC, MENU_SHADOW_WIDTH} from 'common/utils/constants';
|
||||
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
import TeamDropdownView from './teamDropdownView';
|
||||
|
||||
jest.mock('main/utils', () => ({
|
||||
@@ -24,20 +26,23 @@ jest.mock('electron', () => ({
|
||||
on: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('main/windows/mainWindow', () => ({
|
||||
get: jest.fn(),
|
||||
getBounds: jest.fn(),
|
||||
addBrowserView: jest.fn(),
|
||||
setTopBrowserView: jest.fn(),
|
||||
}));
|
||||
jest.mock('../windows/windowManager', () => ({
|
||||
sendToRenderer: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('main/views/teamDropdownView', () => {
|
||||
const window = {
|
||||
getContentBounds: () => ({width: 500, height: 400, x: 0, y: 0}),
|
||||
addBrowserView: jest.fn(),
|
||||
setTopBrowserView: jest.fn(),
|
||||
};
|
||||
|
||||
describe('getBounds', () => {
|
||||
const teamDropdownView = new TeamDropdownView(window, [], false, true);
|
||||
beforeEach(() => {
|
||||
MainWindow.getBounds.mockReturnValue({width: 500, height: 400, x: 0, y: 0});
|
||||
});
|
||||
|
||||
const teamDropdownView = new TeamDropdownView([], false, true);
|
||||
if (process.platform === 'darwin') {
|
||||
it('should account for three dot menu, tab bar and shadow', () => {
|
||||
expect(teamDropdownView.getBounds(400, 300)).toStrictEqual({x: THREE_DOT_MENU_WIDTH_MAC - MENU_SHADOW_WIDTH, y: TAB_BAR_HEIGHT - MENU_SHADOW_WIDTH, width: 400, height: 300});
|
||||
@@ -50,7 +55,7 @@ describe('main/views/teamDropdownView', () => {
|
||||
});
|
||||
|
||||
it('should change the view bounds based on open/closed state', () => {
|
||||
const teamDropdownView = new TeamDropdownView(window, [], false, true);
|
||||
const teamDropdownView = new TeamDropdownView([], false, true);
|
||||
teamDropdownView.bounds = {width: 400, height: 300};
|
||||
teamDropdownView.handleOpen();
|
||||
expect(teamDropdownView.view.setBounds).toBeCalledWith(teamDropdownView.bounds);
|
||||
@@ -60,7 +65,7 @@ describe('main/views/teamDropdownView', () => {
|
||||
|
||||
describe('addGpoToTeams', () => {
|
||||
it('should return teams with "isGPO": false when no config.registryTeams exist', () => {
|
||||
const teamDropdownView = new TeamDropdownView(window, [], false, true);
|
||||
const teamDropdownView = new TeamDropdownView([], false, true);
|
||||
const teams = [{
|
||||
name: 'team-1',
|
||||
url: 'https://mattermost.team-1.com',
|
||||
@@ -81,7 +86,7 @@ describe('main/views/teamDropdownView', () => {
|
||||
}]);
|
||||
});
|
||||
it('should return teams with "isGPO": true if they exist in config.registryTeams', () => {
|
||||
const teamDropdownView = new TeamDropdownView(window, [], false, true);
|
||||
const teamDropdownView = new TeamDropdownView([], false, true);
|
||||
const teams = [{
|
||||
name: 'team-1',
|
||||
url: 'https://mattermost.team-1.com',
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {BrowserView, BrowserWindow, ipcMain, IpcMainEvent} from 'electron';
|
||||
import {BrowserView, ipcMain, IpcMainEvent} from 'electron';
|
||||
|
||||
import log from 'electron-log';
|
||||
|
||||
@@ -21,6 +21,7 @@ import * as AppState from '../appState';
|
||||
import {TAB_BAR_HEIGHT, THREE_DOT_MENU_WIDTH, THREE_DOT_MENU_WIDTH_MAC, MENU_SHADOW_WIDTH} from 'common/utils/constants';
|
||||
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||
import WindowManager from '../windows/windowManager';
|
||||
import MainWindow from '../windows/mainWindow';
|
||||
|
||||
export default class TeamDropdownView {
|
||||
view: BrowserView;
|
||||
@@ -33,18 +34,16 @@ export default class TeamDropdownView {
|
||||
unreads?: Map<string, boolean>;
|
||||
mentions?: Map<string, number>;
|
||||
expired?: Map<string, boolean>;
|
||||
window: BrowserWindow;
|
||||
windowBounds: Electron.Rectangle;
|
||||
windowBounds?: Electron.Rectangle;
|
||||
isOpen: boolean;
|
||||
|
||||
constructor(window: BrowserWindow, teams: TeamWithTabs[], darkMode: boolean, enableServerManagement: boolean) {
|
||||
constructor(teams: TeamWithTabs[], darkMode: boolean, enableServerManagement: boolean) {
|
||||
this.teams = this.addGpoToTeams(teams, []);
|
||||
this.window = window;
|
||||
this.darkMode = darkMode;
|
||||
this.enableServerManagement = enableServerManagement;
|
||||
this.isOpen = false;
|
||||
|
||||
this.windowBounds = this.window.getContentBounds();
|
||||
this.windowBounds = MainWindow.getBounds();
|
||||
|
||||
const preload = getLocalPreload('desktopAPI.js');
|
||||
this.view = new BrowserView({webPreferences: {
|
||||
@@ -57,7 +56,7 @@ export default class TeamDropdownView {
|
||||
}});
|
||||
|
||||
this.view.webContents.loadURL(getLocalURLString('dropdown.html'));
|
||||
this.window.addBrowserView(this.view);
|
||||
MainWindow.get()?.addBrowserView(this.view);
|
||||
|
||||
ipcMain.on(OPEN_TEAMS_DROPDOWN, this.handleOpen);
|
||||
ipcMain.on(CLOSE_TEAMS_DROPDOWN, this.handleClose);
|
||||
@@ -95,7 +94,7 @@ export default class TeamDropdownView {
|
||||
}
|
||||
|
||||
updateWindowBounds = () => {
|
||||
this.windowBounds = this.window.getContentBounds();
|
||||
this.windowBounds = MainWindow.getBounds();
|
||||
this.updateDropdown();
|
||||
}
|
||||
|
||||
@@ -123,7 +122,7 @@ export default class TeamDropdownView {
|
||||
return;
|
||||
}
|
||||
this.view.setBounds(this.bounds);
|
||||
this.window.setTopBrowserView(this.view);
|
||||
MainWindow.get()?.setTopBrowserView(this.view);
|
||||
this.view.webContents.focus();
|
||||
WindowManager.sendToRenderer(OPEN_TEAMS_DROPDOWN);
|
||||
this.isOpen = true;
|
||||
|
@@ -7,11 +7,13 @@
|
||||
import {dialog, ipcMain} from 'electron';
|
||||
import {Tuple as tuple} from '@bloomberg/record-tuple-polyfill';
|
||||
|
||||
import {BROWSER_HISTORY_PUSH, LOAD_SUCCESS, MAIN_WINDOW_SHOWN} from 'common/communication';
|
||||
import {LOAD_SUCCESS, MAIN_WINDOW_SHOWN, BROWSER_HISTORY_PUSH} from 'common/communication';
|
||||
import {MattermostServer} from 'common/servers/MattermostServer';
|
||||
import {getTabViewName} from 'common/tabs/TabView';
|
||||
import {equalUrlsIgnoringSubpath} from 'common/utils/url';
|
||||
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
import {MattermostView} from './MattermostView';
|
||||
import {ViewManager} from './viewManager';
|
||||
|
||||
@@ -56,6 +58,9 @@ jest.mock('main/server/serverInfo', () => ({
|
||||
ServerInfo: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('main/windows/mainWindow', () => ({
|
||||
get: jest.fn(),
|
||||
}));
|
||||
jest.mock('./MattermostView', () => ({
|
||||
MattermostView: jest.fn(),
|
||||
}));
|
||||
@@ -174,15 +179,18 @@ describe('main/views/viewManager', () => {
|
||||
});
|
||||
|
||||
describe('reloadConfiguration', () => {
|
||||
const viewManager = new ViewManager({});
|
||||
const viewManager = new ViewManager();
|
||||
|
||||
beforeEach(() => {
|
||||
viewManager.loadView = jest.fn();
|
||||
viewManager.showByName = jest.fn();
|
||||
viewManager.showInitial = jest.fn();
|
||||
viewManager.mainWindow.webContents = {
|
||||
send: jest.fn(),
|
||||
const mainWindow = {
|
||||
webContents: {
|
||||
send: jest.fn(),
|
||||
},
|
||||
};
|
||||
MainWindow.get.mockReturnValue(mainWindow);
|
||||
|
||||
viewManager.getServerView = jest.fn().mockImplementation((srv, tabName) => ({
|
||||
name: `${srv.name}-${tabName}`,
|
||||
@@ -653,10 +661,11 @@ describe('main/views/viewManager', () => {
|
||||
setTopBrowserView: jest.fn(),
|
||||
addBrowserView: jest.fn(),
|
||||
};
|
||||
const viewManager = new ViewManager(window);
|
||||
const viewManager = new ViewManager();
|
||||
const loadingScreen = {webContents: {send: jest.fn(), isLoading: () => false}};
|
||||
|
||||
beforeEach(() => {
|
||||
MainWindow.get.mockReturnValue(window);
|
||||
viewManager.createLoadingScreen = jest.fn();
|
||||
viewManager.setLoadingScreenBounds = jest.fn();
|
||||
window.getBrowserViews.mockImplementation(() => []);
|
||||
|
@@ -1,8 +1,10 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {BrowserView, dialog, ipcMain, IpcMainEvent} from 'electron';
|
||||
import log from 'electron-log';
|
||||
import {BrowserView, BrowserWindow, dialog, ipcMain, IpcMainEvent} from 'electron';
|
||||
import {BrowserViewConstructorOptions} from 'electron/main';
|
||||
|
||||
import {Tuple as tuple} from '@bloomberg/record-tuple-polyfill';
|
||||
|
||||
import {Tab, TeamWithTabs} from 'types/config';
|
||||
@@ -33,6 +35,7 @@ import PlaybooksTabView from 'common/tabs/PlaybooksTabView';
|
||||
|
||||
import {localizeMessage} from 'main/i18nManager';
|
||||
import {ServerInfo} from 'main/server/serverInfo';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
import {getLocalURLString, getLocalPreload, getWindowBoundaries} from '../utils';
|
||||
|
||||
@@ -57,23 +60,17 @@ export class ViewManager {
|
||||
currentView?: string;
|
||||
urlView?: BrowserView;
|
||||
urlViewCancel?: () => void;
|
||||
mainWindow: BrowserWindow;
|
||||
loadingScreen?: BrowserView;
|
||||
loadingScreenState: LoadingScreenState;
|
||||
|
||||
constructor(mainWindow: BrowserWindow) {
|
||||
constructor() {
|
||||
this.lastActiveServer = Config.lastActiveTeam;
|
||||
this.viewOptions = {webPreferences: {spellcheck: Config.useSpellChecker}};
|
||||
this.views = new Map(); // keep in mind that this doesn't need to hold server order, only tabs on the renderer need that.
|
||||
this.mainWindow = mainWindow;
|
||||
this.closedViews = new Map();
|
||||
this.loadingScreenState = LoadingScreenState.HIDDEN;
|
||||
}
|
||||
|
||||
updateMainWindow = (mainWindow: BrowserWindow) => {
|
||||
this.mainWindow = mainWindow;
|
||||
}
|
||||
|
||||
getServers = () => {
|
||||
return Config.teams.concat();
|
||||
}
|
||||
@@ -86,7 +83,7 @@ export class ViewManager {
|
||||
|
||||
makeView = (srv: MattermostServer, serverInfo: ServerInfo, tab: Tab, url?: string): MattermostView => {
|
||||
const tabView = this.getServerView(srv, tab.name);
|
||||
const view = new MattermostView(tabView, serverInfo, this.mainWindow, this.viewOptions);
|
||||
const view = new MattermostView(tabView, serverInfo, this.viewOptions);
|
||||
view.once(LOAD_SUCCESS, this.activateView);
|
||||
view.load(url);
|
||||
view.on(UPDATE_TARGET_URL, this.showURLView);
|
||||
@@ -186,7 +183,7 @@ export class ViewManager {
|
||||
this.currentView = undefined;
|
||||
this.showInitial();
|
||||
} else {
|
||||
this.mainWindow.webContents.send(SET_ACTIVE_VIEW);
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +193,7 @@ export class ViewManager {
|
||||
if (view) {
|
||||
this.currentView = view.name;
|
||||
this.showByName(view.name);
|
||||
this.mainWindow.webContents.send(SET_ACTIVE_VIEW, view.tab.server.name, view.tab.type);
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW, view.tab.server.name, view.tab.type);
|
||||
}
|
||||
} else {
|
||||
this.showInitial();
|
||||
@@ -221,7 +218,7 @@ export class ViewManager {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.mainWindow.webContents.send(SET_ACTIVE_VIEW, null, null);
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW, null, null);
|
||||
ipcMain.emit(MAIN_WINDOW_SHOWN);
|
||||
}
|
||||
}
|
||||
@@ -248,7 +245,7 @@ export class ViewManager {
|
||||
this.showLoadingScreen();
|
||||
}
|
||||
}
|
||||
newView.window.webContents.send(SET_ACTIVE_VIEW, newView.tab.server.name, newView.tab.type);
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW, newView.tab.server.name, newView.tab.type);
|
||||
ipcMain.emit(SET_ACTIVE_VIEW, true, newView.tab.server.name, newView.tab.type);
|
||||
if (newView.isReady()) {
|
||||
ipcMain.emit(UPDATE_LAST_ACTIVE, true, newView.tab.server.name, newView.tab.type);
|
||||
@@ -375,13 +372,13 @@ export class ViewManager {
|
||||
const query = new Map([['url', urlString]]);
|
||||
const localURL = getLocalURLString('urlView.html', query);
|
||||
urlView.webContents.loadURL(localURL);
|
||||
this.mainWindow.addBrowserView(urlView);
|
||||
const boundaries = this.views.get(this.currentView || '')?.view.getBounds() ?? this.mainWindow.getBounds();
|
||||
MainWindow.get()?.addBrowserView(urlView);
|
||||
const boundaries = this.views.get(this.currentView || '')?.view.getBounds() ?? MainWindow.get()!.getBounds();
|
||||
|
||||
const hideView = () => {
|
||||
delete this.urlViewCancel;
|
||||
try {
|
||||
this.mainWindow.removeBrowserView(urlView);
|
||||
MainWindow.get()?.removeBrowserView(urlView);
|
||||
} catch (e) {
|
||||
log.error('Failed to remove URL view', e);
|
||||
}
|
||||
@@ -421,9 +418,11 @@ export class ViewManager {
|
||||
}
|
||||
|
||||
setLoadingScreenBounds = () => {
|
||||
if (this.loadingScreen) {
|
||||
this.loadingScreen.setBounds(getWindowBoundaries(this.mainWindow));
|
||||
const mainWindow = MainWindow.get();
|
||||
if (!mainWindow) {
|
||||
return;
|
||||
}
|
||||
this.loadingScreen?.setBounds(getWindowBoundaries(mainWindow));
|
||||
}
|
||||
|
||||
createLoadingScreen = () => {
|
||||
@@ -441,6 +440,11 @@ export class ViewManager {
|
||||
}
|
||||
|
||||
showLoadingScreen = () => {
|
||||
const mainWindow = MainWindow.get();
|
||||
if (!mainWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.loadingScreen) {
|
||||
this.createLoadingScreen();
|
||||
}
|
||||
@@ -455,10 +459,10 @@ export class ViewManager {
|
||||
this.loadingScreen!.webContents.send(TOGGLE_LOADING_SCREEN_VISIBILITY, true);
|
||||
}
|
||||
|
||||
if (this.mainWindow.getBrowserViews().includes(this.loadingScreen!)) {
|
||||
this.mainWindow.setTopBrowserView(this.loadingScreen!);
|
||||
if (mainWindow.getBrowserViews().includes(this.loadingScreen!)) {
|
||||
mainWindow.setTopBrowserView(this.loadingScreen!);
|
||||
} else {
|
||||
this.mainWindow.addBrowserView(this.loadingScreen!);
|
||||
mainWindow.addBrowserView(this.loadingScreen!);
|
||||
}
|
||||
|
||||
this.setLoadingScreenBounds();
|
||||
@@ -474,7 +478,7 @@ export class ViewManager {
|
||||
hideLoadingScreen = () => {
|
||||
if (this.loadingScreen && this.loadingScreenState !== LoadingScreenState.HIDDEN) {
|
||||
this.loadingScreenState = LoadingScreenState.HIDDEN;
|
||||
this.mainWindow.removeBrowserView(this.loadingScreen);
|
||||
MainWindow.get()?.removeBrowserView(this.loadingScreen);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user