From 34932dfa0663212f55a851bbd21557d4a1d571ca Mon Sep 17 00:00:00 2001 From: Claudio Costa Date: Mon, 20 Jan 2025 11:26:02 -0600 Subject: [PATCH] Expose Desktop API in Calls popout window (#3258) --- i18n/en.json | 1 + src/main/menus/app.test.js | 16 ++++++++++++++++ src/main/menus/app.ts | 9 +++++++++ src/main/windows/callsWidgetWindow.test.js | 8 +++++++- src/main/windows/callsWidgetWindow.ts | 15 +++++++++++++++ 5 files changed, 48 insertions(+), 1 deletion(-) diff --git a/i18n/en.json b/i18n/en.json index 8f3b6174..36d21b8a 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -97,6 +97,7 @@ "main.menus.app.view.developerModeDisableUserActivityMonitor": "Disable User Activity Monitor", "main.menus.app.view.devToolsAppWrapper": "Developer Tools for Application Wrapper", "main.menus.app.view.devToolsCurrentCallWidget": "Developer Tools for Call Widget", + "main.menus.app.view.devToolsCurrentCallWidgetPopout": "Developer Tools for Call Widget Popout", "main.menus.app.view.devToolsCurrentServer": "Developer Tools for Current Server", "main.menus.app.view.devToolsSubMenu": "Developer Tools", "main.menus.app.view.downloads": "Downloads", diff --git a/src/main/menus/app.test.js b/src/main/menus/app.test.js index de187ac6..9b8cc92c 100644 --- a/src/main/menus/app.test.js +++ b/src/main/menus/app.test.js @@ -360,6 +360,7 @@ describe('main/menus/app', () => { it('should show menu item if widget window is open', () => { CallsWidgetWindow.isOpen = jest.fn(() => true); + CallsWidgetWindow.isPopoutOpen = jest.fn(() => false); const menu = createTemplate(config); const appMenu = menu.find((item) => item.label === 'main.menus.app.view'); @@ -371,4 +372,19 @@ describe('main/menus/app', () => { const menuItem = devToolsSubMenu.submenu.find((item) => item.label === 'main.menus.app.view.devToolsCurrentCallWidget'); expect(menuItem).not.toBe(undefined); }); + + it('should show additional menu item if widget popout is open', () => { + CallsWidgetWindow.isOpen = jest.fn(() => true); + CallsWidgetWindow.isPopoutOpen = jest.fn(() => true); + const menu = createTemplate(config); + + const appMenu = menu.find((item) => item.label === 'main.menus.app.view'); + expect(appMenu).not.toBe(undefined); + + const devToolsSubMenu = appMenu.submenu.find((item) => item.label === 'main.menus.app.view.devToolsSubMenu'); + expect(devToolsSubMenu).not.toBe(undefined); + + const menuItem = devToolsSubMenu.submenu.find((item) => item.label === 'main.menus.app.view.devToolsCurrentCallWidgetPopout'); + expect(menuItem).not.toBe(undefined); + }); }); diff --git a/src/main/menus/app.ts b/src/main/menus/app.ts index 8215ae85..a766966d 100644 --- a/src/main/menus/app.ts +++ b/src/main/menus/app.ts @@ -179,6 +179,15 @@ export function createTemplate(config: Config, updateManager: UpdateManager) { CallsWidgetWindow.openDevTools(); }, }); + + if (CallsWidgetWindow.isPopoutOpen()) { + devToolsSubMenu.push({ + label: localizeMessage('main.menus.app.view.devToolsCurrentCallWidgetPopout', 'Developer Tools for Call Widget Popout'), + click() { + CallsWidgetWindow.openPopoutDevTools(); + }, + }); + } } if (DeveloperMode.enabled()) { diff --git a/src/main/windows/callsWidgetWindow.test.js b/src/main/windows/callsWidgetWindow.test.js index 40286746..c8e8cfef 100644 --- a/src/main/windows/callsWidgetWindow.test.js +++ b/src/main/windows/callsWidgetWindow.test.js @@ -79,7 +79,7 @@ jest.mock('main/views/viewManager', () => ({ jest.mock('../utils', () => ({ openScreensharePermissionsSettingsMacOS: jest.fn(), resetScreensharePermissionsMacOS: jest.fn(), - getLocalPreload: jest.fn(), + getLocalPreload: jest.fn((file) => file), composeUserAgent: jest.fn(), })); @@ -369,6 +369,12 @@ describe('main/windows/callsWidgetWindow', () => { urlUtils.isCallsPopOutURL.mockReturnValue(false); expect(callsWidgetWindow.onPopOutOpen({url: 'http://localhost:8065/notpopouturl'})).toHaveProperty('action', 'deny'); }); + + it('should pop out and make sure preload is set', () => { + urlUtils.isCallsPopOutURL.mockReturnValue(true); + expect(callsWidgetWindow.onPopOutOpen({url: 'http://localhost:8065/popouturl'})).toHaveProperty('action', 'allow'); + expect(callsWidgetWindow.onPopOutOpen({url: 'http://localhost:8065/popouturl'})).toHaveProperty('overrideBrowserWindowOptions.webPreferences.preload', 'externalAPI.js'); + }); }); describe('handlePopOutFocus', () => { diff --git a/src/main/windows/callsWidgetWindow.ts b/src/main/windows/callsWidgetWindow.ts index fcb1952a..b1365b40 100644 --- a/src/main/windows/callsWidgetWindow.ts +++ b/src/main/windows/callsWidgetWindow.ts @@ -97,6 +97,10 @@ export class CallsWidgetWindow { return Boolean(this.win && !this.win.isDestroyed()); } + public isPopoutOpen() { + return Boolean(this.popOut && !this.popOut.isDestroyed()); + } + /** * Helper functions */ @@ -105,6 +109,10 @@ export class CallsWidgetWindow { this.win?.webContents.openDevTools({mode: 'detach'}); }; + public openPopoutDevTools = () => { + this.popOut?.webContents.openDevTools({mode: 'detach'}); + }; + getViewURL = () => { return this.mainView?.view.server.url; }; @@ -292,6 +300,9 @@ export class CallsWidgetWindow { action: 'allow' as const, overrideBrowserWindowOptions: { autoHideMenuBar: true, + webPreferences: { + preload: getLocalPreload('externalAPI.js'), + }, }, }; } @@ -318,7 +329,11 @@ export class CallsWidgetWindow { const contextMenu = new ContextMenu({}, this.popOut); contextMenu.reload(); + // Update menu to show the developer tools option for this window. + ipcMain.emit(UPDATE_SHORTCUT_MENU); + this.popOut.on('closed', () => { + ipcMain.emit(UPDATE_SHORTCUT_MENU); delete this.popOut; contextMenu.dispose(); this.setWidgetWindowStacking({onTop: true});