diff --git a/api-types/index.ts b/api-types/index.ts index 4d471acc..6ac63cef 100644 --- a/api-types/index.ts +++ b/api-types/index.ts @@ -70,6 +70,12 @@ export type DesktopAPI = { focusPopout: () => void; + openThreadForCalls: (threadID: string) => void; + onOpenThreadForCalls: (listener: (threadID: string) => void) => () => void; + + openStopRecordingModal: (channelID: string) => void; + onOpenStopRecordingModal: (listener: (channelID: string) => void) => () => void; + // Utility unregister: (channel: string) => void; } diff --git a/api-types/lib/index.d.ts b/api-types/lib/index.d.ts index 60fef0a0..0eb97c63 100644 --- a/api-types/lib/index.d.ts +++ b/api-types/lib/index.d.ts @@ -59,5 +59,9 @@ export type DesktopAPI = { onJoinCallRequest: (listener: (callID: string) => void) => () => void; openLinkFromCalls: (url: string) => void; focusPopout: () => void; + openThreadForCalls: (threadID: string) => void; + onOpenThreadForCalls: (listener: (threadID: string) => void) => () => void; + openStopRecordingModal: (channelID: string) => void; + onOpenStopRecordingModal: (listener: (channelID: string) => void) => () => void; unregister: (channel: string) => void; }; diff --git a/src/common/communication.ts b/src/common/communication.ts index a0e4d448..2bc7b1fe 100644 --- a/src/common/communication.ts +++ b/src/common/communication.ts @@ -132,6 +132,8 @@ export const CALLS_JOINED_CALL = 'calls-joined-call'; export const CALLS_POPOUT_FOCUS = 'calls-popout-focus'; export const CALLS_ERROR = 'calls-error'; export const CALLS_JOIN_REQUEST = 'calls-join-request'; +export const CALLS_WIDGET_OPEN_THREAD = 'calls-widget-open-thread'; +export const CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL = 'calls-widget-open-stop-recording-modal'; export const REQUEST_CLEAR_DOWNLOADS_DROPDOWN = 'request-clear-downloads-dropdown'; export const CLOSE_DOWNLOADS_DROPDOWN = 'close-downloads-dropdown'; diff --git a/src/main/preload/externalAPI.ts b/src/main/preload/externalAPI.ts index e529c311..eb0b666f 100644 --- a/src/main/preload/externalAPI.ts +++ b/src/main/preload/externalAPI.ts @@ -36,6 +36,8 @@ import { CALLS_WIDGET_CHANNEL_LINK_CLICK, CALLS_LINK_CLICK, CALLS_POPOUT_FOCUS, + CALLS_WIDGET_OPEN_THREAD, + CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, GET_DESKTOP_SOURCES, UNREADS_AND_MENTIONS, LEGACY_OFF, @@ -109,6 +111,12 @@ const desktopAPI: DesktopAPI = { focusPopout: () => ipcRenderer.send(CALLS_POPOUT_FOCUS), + openThreadForCalls: (threadID) => ipcRenderer.send(CALLS_WIDGET_OPEN_THREAD, threadID), + onOpenThreadForCalls: (listener) => createListener(CALLS_WIDGET_OPEN_THREAD, listener), + + openStopRecordingModal: (channelID) => ipcRenderer.send(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, channelID), + onOpenStopRecordingModal: (listener) => createListener(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, listener), + // Utility unregister: (channel) => ipcRenderer.removeAllListeners(channel), }; diff --git a/src/main/windows/callsWidgetWindow.test.js b/src/main/windows/callsWidgetWindow.test.js index 69b60a71..dc6a615b 100644 --- a/src/main/windows/callsWidgetWindow.test.js +++ b/src/main/windows/callsWidgetWindow.test.js @@ -4,7 +4,13 @@ import {BrowserWindow, desktopCapturer, systemPreferences, ipcMain} from 'electron'; import ServerViewState from 'app/serverViewState'; -import {CALLS_WIDGET_SHARE_SCREEN, BROWSER_HISTORY_PUSH, UPDATE_SHORTCUT_MENU} from 'common/communication'; +import { + CALLS_WIDGET_SHARE_SCREEN, + BROWSER_HISTORY_PUSH, + UPDATE_SHORTCUT_MENU, + CALLS_WIDGET_OPEN_THREAD, + CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, +} from 'common/communication'; import { MINIMUM_CALLS_WIDGET_WIDTH, MINIMUM_CALLS_WIDGET_HEIGHT, @@ -848,4 +854,63 @@ describe('main/windows/callsWidgetWindow', () => { expect(callsWidgetWindow.isOpen()).toBe(false); }); }); + + describe('handleCallsOpenThread', () => { + const view = { + view: { + server: { + id: 'server-1', + }, + }, + sendToRenderer: jest.fn(), + }; + const callsWidgetWindow = new CallsWidgetWindow(); + callsWidgetWindow.mainView = view; + callsWidgetWindow.win = {webContents: {id: 1}}; + + const focus = jest.fn(); + + beforeEach(() => { + MainWindow.get.mockReturnValue({focus}); + ViewManager.getView.mockReturnValue(view); + ViewManager.handleDeepLink = jest.fn(); + }); + + it('should switch server, focus and send open thread event', () => { + const threadID = 'call-thread-id'; + callsWidgetWindow.handleCallsOpenThread({sender: {id: 1}}, threadID); + expect(ServerViewState.switchServer).toHaveBeenCalledWith('server-1'); + expect(focus).toHaveBeenCalled(); + expect(view.sendToRenderer).toBeCalledWith(CALLS_WIDGET_OPEN_THREAD, threadID); + }); + }); + + describe('handleCallsOpenStopRecordingModal', () => { + const view = { + view: { + server: { + id: 'server-1', + }, + }, + sendToRenderer: jest.fn(), + }; + const callsWidgetWindow = new CallsWidgetWindow(); + callsWidgetWindow.mainView = view; + callsWidgetWindow.win = {webContents: {id: 1}}; + + const focus = jest.fn(); + + beforeEach(() => { + MainWindow.get.mockReturnValue({focus}); + ViewManager.getView.mockReturnValue(view); + }); + + it('should switch server, focus and send open modal event', () => { + const channelID = 'call-channel-id'; + callsWidgetWindow.handleCallsOpenStopRecordingModal({sender: {id: 1}}, channelID); + expect(ServerViewState.switchServer).toHaveBeenCalledWith('server-1'); + expect(focus).toHaveBeenCalled(); + expect(view.sendToRenderer).toBeCalledWith(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, channelID); + }); + }); }); diff --git a/src/main/windows/callsWidgetWindow.ts b/src/main/windows/callsWidgetWindow.ts index 5d0c7b0f..823ed4f2 100644 --- a/src/main/windows/callsWidgetWindow.ts +++ b/src/main/windows/callsWidgetWindow.ts @@ -17,6 +17,8 @@ import { CALLS_WIDGET_CHANNEL_LINK_CLICK, CALLS_WIDGET_RESIZE, CALLS_WIDGET_SHARE_SCREEN, + CALLS_WIDGET_OPEN_THREAD, + CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, DESKTOP_SOURCES_MODAL_REQUEST, GET_DESKTOP_SOURCES, UPDATE_SHORTCUT_MENU, @@ -70,6 +72,8 @@ export class CallsWidgetWindow { ipcMain.on(CALLS_ERROR, this.forwardToMainApp(CALLS_ERROR)); ipcMain.on(CALLS_LINK_CLICK, this.handleCallsLinkClick); ipcMain.on(CALLS_JOIN_REQUEST, this.forwardToMainApp(CALLS_JOIN_REQUEST)); + ipcMain.on(CALLS_WIDGET_OPEN_THREAD, this.handleCallsOpenThread); + ipcMain.on(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, this.handleCallsOpenStopRecordingModal); // deprecated in favour of CALLS_LINK_CLICK ipcMain.on(CALLS_WIDGET_CHANNEL_LINK_CLICK, this.handleCallsWidgetChannelLinkClick); @@ -504,6 +508,14 @@ export class CallsWidgetWindow { }; }; + private handleCallsOpenThread = (event: IpcMainEvent, threadID: string) => { + this.forwardToMainApp(CALLS_WIDGET_OPEN_THREAD)(event, threadID); + }; + + private handleCallsOpenStopRecordingModal = (event: IpcMainEvent, channelID: string) => { + this.forwardToMainApp(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL)(event, channelID); + }; + private handleCallsLinkClick = (event: IpcMainEvent, url: string) => { log.debug('handleCallsLinkClick', url); diff --git a/src/types/externalAPI.ts b/src/types/externalAPI.ts index 4c33863a..6f141a5e 100644 --- a/src/types/externalAPI.ts +++ b/src/types/externalAPI.ts @@ -22,4 +22,6 @@ export interface ExternalAPI { createListener(event: 'calls-error', listener: (err: string, callID?: string, errMsg?: string) => void): () => void; createListener(event: 'calls-link-click', listener: (url: string) => void): () => void; createListener(event: 'desktop-sources-modal-request', listener: () => void): () => void; + createListener(event: 'calls-widget-open-thread', listener: (threadID: string) => void): () => void; + createListener(event: 'calls-widget-open-stop-recording-modal', listener: (channelID: string) => void): () => void; }