From 5cc2e98a1da1779f68686c0b122553f780404a81 Mon Sep 17 00:00:00 2001 From: Devin Binnie <52460000+devinbinnie@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:42:53 -0500 Subject: [PATCH] Merge and migrate locally-trusted preload scripts to `contextBridge` API (#2553) * Migrate intl_provider to contextBridge * Migrate modalPreload to contextBridge * Migrate loadingScreenPreload to contextBridge * Migrate downloadDropdown preloads to contextBridge * Migrate server dropdown preload to contextBridge * Migrate urlView preload to contextBridge * Merge all desktop API scripts into one * Remove unused communication channel constants --- src/common/communication.ts | 9 -- src/main/app/intercom.ts | 16 +-- src/main/authManager.ts | 6 +- src/main/certificateManager.ts | 4 +- .../preload/{mainWindow.js => desktopAPI.js} | 123 ++++++++++++++++-- src/main/preload/downloadsDropdown.js | 90 ------------- src/main/preload/downloadsDropdownMenu.js | 58 --------- src/main/preload/dropdown.js | 66 ---------- src/main/preload/loadingScreenPreload.js | 45 ------- src/main/preload/modalPreload.js | 88 ------------- src/main/preload/urlView.js | 22 ---- src/main/views/downloadsDropdownMenuView.ts | 2 +- src/main/views/downloadsDropdownView.ts | 10 +- src/main/views/teamDropdownView.ts | 6 +- src/main/views/viewManager.ts | 8 +- src/main/windows/mainWindow.ts | 2 +- src/main/windows/settingsWindow.ts | 2 +- src/main/windows/windowManager.ts | 2 - src/renderer/components/ConfigureServer.tsx | 37 ++---- .../DownloadsDropdownItemFile.tsx | 4 +- .../DownloadsDropdown/ThreeDotButton.tsx | 13 +- .../Update/UpdateAvailable.tsx | 4 +- .../Update/UpdateDownloaded.tsx | 4 +- src/renderer/components/NewTeamModal.tsx | 21 +-- src/renderer/components/urlDescription.tsx | 4 +- src/renderer/downloadsDropdown.tsx | 65 +++++---- src/renderer/downloadsDropdownMenu.tsx | 49 ++++--- src/renderer/dropdown.tsx | 68 +++++----- src/renderer/intl_provider.tsx | 20 +-- .../modals/certificate/certificate.tsx | 10 +- .../modals/certificate/certificateModal.tsx | 32 +---- src/renderer/modals/darkMode.ts | 19 ++- src/renderer/modals/editServer/editServer.tsx | 30 ++--- src/renderer/modals/loadingScreen/index.tsx | 37 +++--- src/renderer/modals/login/login.tsx | 8 +- src/renderer/modals/login/loginModal.tsx | 30 ++--- src/renderer/modals/newServer/newServer.tsx | 34 ++--- src/renderer/modals/permission/permission.tsx | 10 +- .../modals/permission/permissionModal.tsx | 35 ++--- .../modals/removeServer/removeServer.tsx | 24 +--- .../modals/welcomeScreen/welcomeScreen.tsx | 41 ++---- src/types/modals.ts | 24 +++- src/types/window.ts | 69 +++++++++- webpack.config.main.js | 8 +- 44 files changed, 438 insertions(+), 821 deletions(-) rename src/main/preload/{mainWindow.js => desktopAPI.js} (57%) delete mode 100644 src/main/preload/downloadsDropdown.js delete mode 100644 src/main/preload/downloadsDropdownMenu.js delete mode 100644 src/main/preload/dropdown.js delete mode 100644 src/main/preload/loadingScreenPreload.js delete mode 100644 src/main/preload/modalPreload.js delete mode 100644 src/main/preload/urlView.js diff --git a/src/common/communication.ts b/src/common/communication.ts index 770c314a..d918d62f 100644 --- a/src/common/communication.ts +++ b/src/common/communication.ts @@ -41,10 +41,8 @@ export const SHOW_REMOVE_SERVER_MODAL = 'show-remove-server-modal'; export const MAIN_WINDOW_SHOWN = 'main-window-shown'; export const RETRIEVE_MODAL_INFO = 'retrieve-modal-info'; -export const MODAL_INFO = 'modal-info'; export const MODAL_CANCEL = 'modal-cancel'; export const MODAL_RESULT = 'modal-result'; -export const MODAL_SEND_IPC_MESSAGE = 'modal-send-ipc-message'; export const MODAL_OPEN = 'modal-open'; export const MODAL_CLOSE = 'modal-close'; export const NOTIFY_MENTION = 'notify_mention'; @@ -74,8 +72,6 @@ export const TOGGLE_BACK_BUTTON = 'toggle-back-button'; export const SHOW_SETTINGS_WINDOW = 'show-settings-window'; -export const RECEIVED_LOADING_SCREEN_DATA = 'received-loading-screen-data'; -export const GET_LOADING_SCREEN_DATA = 'get-loading-screen-data'; export const LOADING_SCREEN_ANIMATION_FINISHED = 'loading-screen-animation-finished'; export const TOGGLE_LOADING_SCREEN_VISIBILITY = 'toggle-loading-screen-visibility'; @@ -91,7 +87,6 @@ export const UPDATE_TEAMS_DROPDOWN = 'update-teams-dropdown'; export const UPDATE_DROPDOWN_MENTIONS = 'update-dropdown-mentions'; export const REQUEST_TEAMS_DROPDOWN_INFO = 'request-teams-dropdown-info'; export const RECEIVE_DROPDOWN_MENU_SIZE = 'receive-dropdown-menu-size'; -export const SEND_DROPDOWN_MENU_SIZE = 'send-dropdown-menu-size'; export const UPDATE_AVAILABLE = 'update-available'; export const UPDATE_DOWNLOADED = 'update-downloaded'; @@ -116,7 +111,6 @@ export const GET_VIEW_WEBCONTENTS_ID = 'get-view-webcontents-id'; export const RESIZE_MODAL = 'resize-modal'; export const GET_MODAL_UNCLOSEABLE = 'get-modal-uncloseable'; -export const MODAL_UNCLOSEABLE = 'modal-uncloseable'; export const UPDATE_PATHS = 'update-paths'; @@ -128,7 +122,6 @@ export const PING_DOMAIN = 'ping-domain'; export const PING_DOMAIN_RESPONSE = 'ping-domain-response'; export const GET_LANGUAGE_INFORMATION = 'get-language-information'; -export const RETRIEVED_LANGUAGE_INFORMATION = 'retrieved-language-information'; export const GET_AVAILABLE_LANGUAGES = 'get-available-languages'; export const VIEW_FINISHED_RESIZING = 'view-finished-resizing'; @@ -152,12 +145,10 @@ export const SHOW_DOWNLOADS_DROPDOWN_BUTTON_BADGE = 'show-downloads-dropdown-but export const HIDE_DOWNLOADS_DROPDOWN_BUTTON_BADGE = 'hide-downloads-dropdown-button-badge'; export const REQUEST_DOWNLOADS_DROPDOWN_INFO = 'request-downloads-dropdown-info'; export const UPDATE_DOWNLOADS_DROPDOWN = 'update-downloads-dropdown'; -export const DOWNLOADS_DROPDOWN_SHOW_FILE_IN_FOLDER = 'downloads-dropdown-show-file-in-folder'; export const DOWNLOADS_DROPDOWN_OPEN_FILE = 'downloads-dropdown-open-file'; export const REQUEST_HAS_DOWNLOADS = 'request-has-downloads'; export const DOWNLOADS_DROPDOWN_FOCUSED = 'downloads-dropdown-focused'; export const RECEIVE_DOWNLOADS_DROPDOWN_SIZE = 'receive-downloads-dropdown-size'; -export const SEND_DOWNLOADS_DROPDOWN_SIZE = 'send-downloads-dropdown-size'; export const GET_DOWNLOADED_IMAGE_THUMBNAIL_LOCATION = 'get-downloaded-image-thumbnail-location'; export const OPEN_DOWNLOADS_DROPDOWN_MENU = 'open-downloads-dropdown-menu'; diff --git a/src/main/app/intercom.ts b/src/main/app/intercom.ts index 9040fcf6..c91a6be9 100644 --- a/src/main/app/intercom.ts +++ b/src/main/app/intercom.ts @@ -151,13 +151,13 @@ export function handleNewServerModal() { const html = getLocalURLString('newServer.html'); - const modalPreload = getLocalPreload('modalPreload.js'); + const preload = getLocalPreload('desktopAPI.js'); const mainWindow = WindowManager.getMainWindow(); if (!mainWindow) { return; } - const modalPromise = ModalManager.addModal('newServer', html, modalPreload, Config.teams.map((team, index) => ({...team, index})), mainWindow, Config.teams.length === 0); + const modalPromise = ModalManager.addModal('newServer', html, preload, Config.teams.map((team, index) => ({...team, index})), mainWindow, Config.teams.length === 0); if (modalPromise) { modalPromise.then((data) => { const teams = Config.teams; @@ -183,7 +183,7 @@ export function handleEditServerModal(e: IpcMainEvent, name: string) { const html = getLocalURLString('editServer.html'); - const modalPreload = getLocalPreload('modalPreload.js'); + const preload = getLocalPreload('desktopAPI.js'); const mainWindow = WindowManager.getMainWindow(); if (!mainWindow) { @@ -196,7 +196,7 @@ export function handleEditServerModal(e: IpcMainEvent, name: string) { const modalPromise = ModalManager.addModal<{currentTeams: TeamWithIndex[]; team: TeamWithIndex}, Team>( 'editServer', html, - modalPreload, + preload, { currentTeams: Config.teams.map((team, index) => ({...team, index})), team: {...Config.teams[serverIndex], index: serverIndex}, @@ -225,13 +225,13 @@ export function handleRemoveServerModal(e: IpcMainEvent, name: string) { const html = getLocalURLString('removeServer.html'); - const modalPreload = getLocalPreload('modalPreload.js'); + const preload = getLocalPreload('desktopAPI.js'); const mainWindow = WindowManager.getMainWindow(); if (!mainWindow) { return; } - const modalPromise = ModalManager.addModal('removeServer', html, modalPreload, name, mainWindow); + const modalPromise = ModalManager.addModal('removeServer', html, preload, name, mainWindow); if (modalPromise) { modalPromise.then((remove) => { if (remove) { @@ -265,13 +265,13 @@ export function handleWelcomeScreenModal() { const html = getLocalURLString('welcomeScreen.html'); - const modalPreload = getLocalPreload('modalPreload.js'); + const preload = getLocalPreload('desktopAPI.js'); const mainWindow = WindowManager.getMainWindow(); if (!mainWindow) { return; } - const modalPromise = ModalManager.addModal('welcomeScreen', html, modalPreload, Config.teams.map((team, index) => ({...team, index})), mainWindow, Config.teams.length === 0); + const modalPromise = ModalManager.addModal('welcomeScreen', html, preload, Config.teams.map((team, index) => ({...team, index})), mainWindow, Config.teams.length === 0); if (modalPromise) { modalPromise.then((data) => { const teams = Config.teams; diff --git a/src/main/authManager.ts b/src/main/authManager.ts index 3c71e4af..3f261225 100644 --- a/src/main/authManager.ts +++ b/src/main/authManager.ts @@ -14,7 +14,7 @@ import TrustedOriginsStore from 'main/trustedOrigins'; import {getLocalURLString, getLocalPreload} from 'main/utils'; import WindowManager from 'main/windows/windowManager'; -const modalPreload = getLocalPreload('modalPreload.js'); +const preload = getLocalPreload('desktopAPI.js'); const loginModalHtml = getLocalURLString('loginModal.html'); const permissionModalHtml = getLocalURLString('permissionModal.html'); @@ -56,7 +56,7 @@ export class AuthManager { if (!mainWindow) { return; } - const modalPromise = modalManager.addModal(authInfo.isProxy ? `proxy-${authInfo.host}` : `login-${request.url}`, loginModalHtml, modalPreload, {request, authInfo}, mainWindow); + const modalPromise = modalManager.addModal(authInfo.isProxy ? `proxy-${authInfo.host}` : `login-${request.url}`, loginModalHtml, preload, {request, authInfo}, mainWindow); if (modalPromise) { modalPromise.then((data) => { const {username, password} = data; @@ -75,7 +75,7 @@ export class AuthManager { if (!mainWindow) { return; } - const modalPromise = modalManager.addModal(`permission-${request.url}`, permissionModalHtml, modalPreload, {url: request.url, permission}, mainWindow); + const modalPromise = modalManager.addModal(`permission-${request.url}`, permissionModalHtml, preload, {url: request.url, permission}, mainWindow); if (modalPromise) { modalPromise.then(() => { this.handlePermissionGranted(request.url, permission); diff --git a/src/main/certificateManager.ts b/src/main/certificateManager.ts index efb36c2d..00869b2f 100644 --- a/src/main/certificateManager.ts +++ b/src/main/certificateManager.ts @@ -10,7 +10,7 @@ import WindowManager from './windows/windowManager'; import modalManager from './views/modalManager'; import {getLocalURLString, getLocalPreload} from './utils'; -const modalPreload = getLocalPreload('modalPreload.js'); +const preload = getLocalPreload('desktopAPI.js'); const html = getLocalURLString('certificateModal.html'); type CertificateModalResult = { @@ -43,7 +43,7 @@ export class CertificateManager { if (!mainWindow) { return; } - const modalPromise = modalManager.addModal(`certificate-${url}`, html, modalPreload, {url, list}, mainWindow); + const modalPromise = modalManager.addModal(`certificate-${url}`, html, preload, {url, list}, mainWindow); if (modalPromise) { modalPromise.then((data) => { const {cert} = data; diff --git a/src/main/preload/mainWindow.js b/src/main/preload/desktopAPI.js similarity index 57% rename from src/main/preload/mainWindow.js rename to src/main/preload/desktopAPI.js index 6e09dd41..85f74b51 100644 --- a/src/main/preload/mainWindow.js +++ b/src/main/preload/desktopAPI.js @@ -8,7 +8,6 @@ import {ipcRenderer, contextBridge} from 'electron'; import { GET_LANGUAGE_INFORMATION, - RETRIEVED_LANGUAGE_INFORMATION, QUIT, GET_VIEW_NAME, GET_VIEW_WEBCONTENTS_ID, @@ -56,6 +55,36 @@ import { UPDATE_DOWNLOADS_DROPDOWN, APP_MENU_WILL_CLOSE, FOCUS_THREE_DOT_MENU, + UPDATE_URL_VIEW_WIDTH, + DOWNLOADS_DROPDOWN_MENU_CLEAR_FILE, + DOWNLOADS_DROPDOWN_MENU_SHOW_FILE_IN_FOLDER, + DOWNLOADS_DROPDOWN_MENU_CANCEL_DOWNLOAD, + DOWNLOADS_DROPDOWN_MENU_OPEN_FILE, + UPDATE_DOWNLOADS_DROPDOWN_MENU, + REQUEST_DOWNLOADS_DROPDOWN_MENU_INFO, + UPDATE_TEAMS_DROPDOWN, + REQUEST_TEAMS_DROPDOWN_INFO, + RECEIVE_DROPDOWN_MENU_SIZE, + SWITCH_SERVER, + SHOW_NEW_SERVER_MODAL, + SHOW_EDIT_SERVER_MODAL, + SHOW_REMOVE_SERVER_MODAL, + RECEIVE_DOWNLOADS_DROPDOWN_SIZE, + REQUEST_CLEAR_DOWNLOADS_DROPDOWN, + REQUEST_DOWNLOADS_DROPDOWN_INFO, + START_UPDATE_DOWNLOAD, + START_UPGRADE, + TOGGLE_DOWNLOADS_DROPDOWN_MENU, + GET_DOWNLOADED_IMAGE_THUMBNAIL_LOCATION, + DOWNLOADS_DROPDOWN_OPEN_FILE, + MODAL_CANCEL, + MODAL_RESULT, + RETRIEVE_MODAL_INFO, + GET_MODAL_UNCLOSEABLE, + PING_DOMAIN, + LOADING_SCREEN_ANIMATION_FINISHED, + TOGGLE_LOADING_SCREEN_VISIBILITY, + DOWNLOADS_DROPDOWN_FOCUSED, } from 'common/communication'; console.log('Preload initialized'); @@ -79,6 +108,10 @@ contextBridge.exposeInMainWorld('timers', { setImmediate, }); +contextBridge.exposeInMainWorld('mas', { + getThumbnailLocation: (location) => ipcRenderer.invoke(GET_DOWNLOADED_IMAGE_THUMBNAIL_LOCATION, location), +}); + contextBridge.exposeInMainWorld('desktop', { quit: (reason, stack) => ipcRenderer.send(QUIT, reason, stack), openAppMenu: () => ipcRenderer.send(OPEN_APP_MENU), @@ -110,6 +143,7 @@ contextBridge.exposeInMainWorld('desktop', { getAvailableLanguages: () => ipcRenderer.invoke(GET_AVAILABLE_LANGUAGES), getLocalConfiguration: (option) => ipcRenderer.invoke(GET_LOCAL_CONFIGURATION, option), getDownloadLocation: (downloadLocation) => ipcRenderer.invoke(GET_DOWNLOAD_LOCATION, downloadLocation), + getLanguageInformation: () => ipcRenderer.invoke(GET_LANGUAGE_INFORMATION), onSynchronizeConfig: (listener) => ipcRenderer.on('synchronize-config', () => listener()), onReloadConfiguration: (listener) => ipcRenderer.on(RELOAD_CONFIGURATION, () => listener()), @@ -132,15 +166,86 @@ contextBridge.exposeInMainWorld('desktop', { onOpenDownloadsDropdown: (listener) => ipcRenderer.on(OPEN_DOWNLOADS_DROPDOWN, () => listener()), onShowDownloadsDropdownButtonBadge: (listener) => ipcRenderer.on(SHOW_DOWNLOADS_DROPDOWN_BUTTON_BADGE, () => listener()), onHideDownloadsDropdownButtonBadge: (listener) => ipcRenderer.on(HIDE_DOWNLOADS_DROPDOWN_BUTTON_BADGE, () => listener()), - onUpdateDownloadsDropdown: (listener) => ipcRenderer.on(UPDATE_DOWNLOADS_DROPDOWN, (_, downloads) => listener(downloads)), + onUpdateDownloadsDropdown: (listener) => ipcRenderer.on(UPDATE_DOWNLOADS_DROPDOWN, (_, downloads, darkMode, windowBounds, item) => listener(downloads, darkMode, windowBounds, item)), onAppMenuWillClose: (listener) => ipcRenderer.on(APP_MENU_WILL_CLOSE, () => listener()), onFocusThreeDotMenu: (listener) => ipcRenderer.on(FOCUS_THREE_DOT_MENU, () => listener()), + updateURLViewWidth: (width) => ipcRenderer.send(UPDATE_URL_VIEW_WIDTH, width), + + downloadsDropdown: { + toggleDownloadsDropdownMenu: (payload) => ipcRenderer.send(TOGGLE_DOWNLOADS_DROPDOWN_MENU, payload), + requestInfo: () => ipcRenderer.send(REQUEST_DOWNLOADS_DROPDOWN_INFO), + sendSize: (width, height) => ipcRenderer.send(RECEIVE_DOWNLOADS_DROPDOWN_SIZE, width, height), + requestClearDownloadsDropdown: () => ipcRenderer.send(REQUEST_CLEAR_DOWNLOADS_DROPDOWN), + openFile: (item) => ipcRenderer.send(DOWNLOADS_DROPDOWN_OPEN_FILE, item), + startUpdateDownload: () => ipcRenderer.send(START_UPDATE_DOWNLOAD), + startUpgrade: () => ipcRenderer.send(START_UPGRADE), + focus: () => ipcRenderer.send(DOWNLOADS_DROPDOWN_FOCUSED), + }, + + downloadsDropdownMenu: { + requestInfo: () => ipcRenderer.send(REQUEST_DOWNLOADS_DROPDOWN_MENU_INFO), + showInFolder: (item) => ipcRenderer.send(DOWNLOADS_DROPDOWN_MENU_SHOW_FILE_IN_FOLDER, item), + cancelDownload: (item) => ipcRenderer.send(DOWNLOADS_DROPDOWN_MENU_CANCEL_DOWNLOAD, item), + clearFile: (item) => ipcRenderer.send(DOWNLOADS_DROPDOWN_MENU_CLEAR_FILE, item), + openFile: (item) => ipcRenderer.send(DOWNLOADS_DROPDOWN_MENU_OPEN_FILE, item), + + onUpdateDownloadsDropdownMenu: (listener) => ipcRenderer.on(UPDATE_DOWNLOADS_DROPDOWN_MENU, (_, item, darkMode) => listener(item, darkMode)), + }, + + serverDropdown: { + requestInfo: () => ipcRenderer.send(REQUEST_TEAMS_DROPDOWN_INFO), + sendSize: (width, height) => ipcRenderer.send(RECEIVE_DROPDOWN_MENU_SIZE, width, height), + switchServer: (server) => ipcRenderer.send(SWITCH_SERVER, server), + showNewServerModal: () => ipcRenderer.send(SHOW_NEW_SERVER_MODAL), + showEditServerModal: (serverName) => ipcRenderer.send(SHOW_EDIT_SERVER_MODAL, serverName), + showRemoveServerModal: (serverName) => ipcRenderer.send(SHOW_REMOVE_SERVER_MODAL, serverName), + + onUpdateServerDropdown: (listener) => ipcRenderer.on(UPDATE_TEAMS_DROPDOWN, (_, + teams, + activeTeam, + darkMode, + enableServerManagement, + hasGPOTeams, + expired, + mentions, + unreads, + windowBounds, + ) => listener( + teams, + activeTeam, + darkMode, + enableServerManagement, + hasGPOTeams, + expired, + mentions, + unreads, + windowBounds, + )), + }, + + loadingScreen: { + loadingScreenAnimationFinished: () => ipcRenderer.send(LOADING_SCREEN_ANIMATION_FINISHED), + onToggleLoadingScreenVisibility: (listener) => ipcRenderer.on(TOGGLE_LOADING_SCREEN_VISIBILITY, (_, toggle) => listener(toggle)), + }, + + modals: { + cancelModal: (data) => ipcRenderer.send(MODAL_CANCEL, data), + finishModal: (data) => ipcRenderer.send(MODAL_RESULT, data), + getModalInfo: () => ipcRenderer.invoke(RETRIEVE_MODAL_INFO), + isModalUncloseable: () => ipcRenderer.invoke(GET_MODAL_UNCLOSEABLE), + confirmProtocol: (protocol, url) => ipcRenderer.send('confirm-protocol', protocol, url), + pingDomain: (url) => ipcRenderer.invoke(PING_DOMAIN, url), + }, }); -window.addEventListener('message', async (event) => { - switch (event.data.type) { - case GET_LANGUAGE_INFORMATION: - window.postMessage({type: RETRIEVED_LANGUAGE_INFORMATION, data: await ipcRenderer.invoke(GET_LANGUAGE_INFORMATION)}); - break; - } -}); +// TODO: This is for modals only, should probably move this out for them +const createKeyDownListener = () => { + ipcRenderer.invoke(GET_MODAL_UNCLOSEABLE).then((uncloseable) => { + window.addEventListener('keydown', (e) => { + if (e.key === 'Escape' && !uncloseable) { + ipcRenderer.send(MODAL_CANCEL); + } + }); + }); +}; +createKeyDownListener(); diff --git a/src/main/preload/downloadsDropdown.js b/src/main/preload/downloadsDropdown.js deleted file mode 100644 index e0e29708..00000000 --- a/src/main/preload/downloadsDropdown.js +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -'use strict'; - -import {ipcRenderer, contextBridge} from 'electron'; - -import { - CLOSE_DOWNLOADS_DROPDOWN, - CLOSE_DOWNLOADS_DROPDOWN_MENU, - DOWNLOADS_DROPDOWN_FOCUSED, - DOWNLOADS_DROPDOWN_SHOW_FILE_IN_FOLDER, - GET_LANGUAGE_INFORMATION, - RECEIVE_DOWNLOADS_DROPDOWN_SIZE, - REQUEST_CLEAR_DOWNLOADS_DROPDOWN, - REQUEST_DOWNLOADS_DROPDOWN_INFO, - RETRIEVED_LANGUAGE_INFORMATION, - SEND_DOWNLOADS_DROPDOWN_SIZE, - START_UPDATE_DOWNLOAD, - START_UPGRADE, - TOGGLE_DOWNLOADS_DROPDOWN_MENU, - UPDATE_DOWNLOADS_DROPDOWN, - GET_DOWNLOADED_IMAGE_THUMBNAIL_LOCATION, - DOWNLOADS_DROPDOWN_OPEN_FILE, -} from 'common/communication'; - -console.log('preloaded for the downloadsDropdown!'); - -contextBridge.exposeInMainWorld('process', { - platform: process.platform, -}); - -contextBridge.exposeInMainWorld('mas', { - getThumbnailLocation: (location) => ipcRenderer.invoke(GET_DOWNLOADED_IMAGE_THUMBNAIL_LOCATION, location), -}); - -window.addEventListener('click', () => { - ipcRenderer.send(CLOSE_DOWNLOADS_DROPDOWN_MENU); -}); - -window.addEventListener('mousemove', () => { - ipcRenderer.send(DOWNLOADS_DROPDOWN_FOCUSED); -}); - -/** - * renderer => main - */ -window.addEventListener('message', async (event) => { - switch (event.data.type) { - case CLOSE_DOWNLOADS_DROPDOWN: - ipcRenderer.send(CLOSE_DOWNLOADS_DROPDOWN); - break; - case TOGGLE_DOWNLOADS_DROPDOWN_MENU: - ipcRenderer.send(TOGGLE_DOWNLOADS_DROPDOWN_MENU, event.data.payload); - break; - case REQUEST_DOWNLOADS_DROPDOWN_INFO: - ipcRenderer.send(REQUEST_DOWNLOADS_DROPDOWN_INFO); - break; - case SEND_DOWNLOADS_DROPDOWN_SIZE: - ipcRenderer.send(RECEIVE_DOWNLOADS_DROPDOWN_SIZE, event.data.data.width, event.data.data.height); - break; - case REQUEST_CLEAR_DOWNLOADS_DROPDOWN: - ipcRenderer.send(REQUEST_CLEAR_DOWNLOADS_DROPDOWN); - break; - case DOWNLOADS_DROPDOWN_OPEN_FILE: - ipcRenderer.send(DOWNLOADS_DROPDOWN_OPEN_FILE, event.data.payload.item); - break; - case DOWNLOADS_DROPDOWN_SHOW_FILE_IN_FOLDER: - ipcRenderer.send(DOWNLOADS_DROPDOWN_SHOW_FILE_IN_FOLDER, event.data.payload.item); - break; - case START_UPDATE_DOWNLOAD: - ipcRenderer.send(START_UPDATE_DOWNLOAD); - break; - case START_UPGRADE: - ipcRenderer.send(START_UPGRADE); - break; - case GET_LANGUAGE_INFORMATION: - window.postMessage({type: RETRIEVED_LANGUAGE_INFORMATION, data: await ipcRenderer.invoke(GET_LANGUAGE_INFORMATION)}); - break; - default: - console.log('Got an unknown message. Unknown messages are ignored'); - } -}); - -/** - * main => renderer - */ -ipcRenderer.on(UPDATE_DOWNLOADS_DROPDOWN, (event, downloads, darkMode, windowBounds, item) => { - window.postMessage({type: UPDATE_DOWNLOADS_DROPDOWN, data: {downloads, darkMode, windowBounds, item}}, window.location.href); -}); diff --git a/src/main/preload/downloadsDropdownMenu.js b/src/main/preload/downloadsDropdownMenu.js deleted file mode 100644 index 004e3b1d..00000000 --- a/src/main/preload/downloadsDropdownMenu.js +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -'use strict'; - -import {ipcRenderer, contextBridge} from 'electron'; - -import { - GET_LANGUAGE_INFORMATION, - DOWNLOADS_DROPDOWN_MENU_CLEAR_FILE, - RETRIEVED_LANGUAGE_INFORMATION, - DOWNLOADS_DROPDOWN_MENU_SHOW_FILE_IN_FOLDER, - DOWNLOADS_DROPDOWN_MENU_CANCEL_DOWNLOAD, - DOWNLOADS_DROPDOWN_MENU_OPEN_FILE, - UPDATE_DOWNLOADS_DROPDOWN_MENU, - REQUEST_DOWNLOADS_DROPDOWN_MENU_INFO, -} from 'common/communication'; - -console.log('preloaded for the downloadsDropdownMenu!'); - -contextBridge.exposeInMainWorld('process', { - platform: process.platform, -}); - -/** - * renderer => main - */ -window.addEventListener('message', async (event) => { - switch (event.data.type) { - case REQUEST_DOWNLOADS_DROPDOWN_MENU_INFO: - ipcRenderer.send(REQUEST_DOWNLOADS_DROPDOWN_MENU_INFO); - break; - case DOWNLOADS_DROPDOWN_MENU_SHOW_FILE_IN_FOLDER: - ipcRenderer.send(DOWNLOADS_DROPDOWN_MENU_SHOW_FILE_IN_FOLDER, event.data.payload.item); - break; - case DOWNLOADS_DROPDOWN_MENU_CANCEL_DOWNLOAD: - ipcRenderer.send(DOWNLOADS_DROPDOWN_MENU_CANCEL_DOWNLOAD, event.data.payload.item); - break; - case DOWNLOADS_DROPDOWN_MENU_CLEAR_FILE: - ipcRenderer.send(DOWNLOADS_DROPDOWN_MENU_CLEAR_FILE, event.data.payload.item); - break; - case DOWNLOADS_DROPDOWN_MENU_OPEN_FILE: - ipcRenderer.send(DOWNLOADS_DROPDOWN_MENU_OPEN_FILE, event.data.payload.item); - break; - case GET_LANGUAGE_INFORMATION: - window.postMessage({type: RETRIEVED_LANGUAGE_INFORMATION, data: await ipcRenderer.invoke(GET_LANGUAGE_INFORMATION)}); - break; - default: - console.log('Got an unknown message. Unknown messages are ignored'); - } -}); - -/** - * main => renderer - */ -ipcRenderer.on(UPDATE_DOWNLOADS_DROPDOWN_MENU, (event, item, darkMode) => { - window.postMessage({type: UPDATE_DOWNLOADS_DROPDOWN_MENU, data: {item, darkMode}}, window.location.href); -}); diff --git a/src/main/preload/dropdown.js b/src/main/preload/dropdown.js deleted file mode 100644 index e7aaffff..00000000 --- a/src/main/preload/dropdown.js +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -'use strict'; - -import {ipcRenderer, contextBridge} from 'electron'; - -import { - UPDATE_TEAMS_DROPDOWN, - REQUEST_TEAMS_DROPDOWN_INFO, - RECEIVE_DROPDOWN_MENU_SIZE, - SEND_DROPDOWN_MENU_SIZE, - SWITCH_SERVER, - CLOSE_TEAMS_DROPDOWN, - SHOW_NEW_SERVER_MODAL, - SHOW_EDIT_SERVER_MODAL, - SHOW_REMOVE_SERVER_MODAL, - UPDATE_TEAMS, - GET_LANGUAGE_INFORMATION, - RETRIEVED_LANGUAGE_INFORMATION, -} from 'common/communication'; - -console.log('preloaded for the dropdown!'); - -contextBridge.exposeInMainWorld('process', { - platform: process.platform, -}); - -window.addEventListener('message', async (event) => { - switch (event.data.type) { - case REQUEST_TEAMS_DROPDOWN_INFO: - ipcRenderer.send(REQUEST_TEAMS_DROPDOWN_INFO); - break; - case SEND_DROPDOWN_MENU_SIZE: - ipcRenderer.send(RECEIVE_DROPDOWN_MENU_SIZE, event.data.data.width, event.data.data.height); - break; - case SWITCH_SERVER: - ipcRenderer.send(SWITCH_SERVER, event.data.data); - break; - case SHOW_NEW_SERVER_MODAL: - ipcRenderer.send(SHOW_NEW_SERVER_MODAL); - break; - case SHOW_EDIT_SERVER_MODAL: - ipcRenderer.send(SHOW_EDIT_SERVER_MODAL, event.data.data.name); - break; - case SHOW_REMOVE_SERVER_MODAL: - ipcRenderer.send(SHOW_REMOVE_SERVER_MODAL, event.data.data.name); - break; - case CLOSE_TEAMS_DROPDOWN: - ipcRenderer.send(CLOSE_TEAMS_DROPDOWN); - break; - case UPDATE_TEAMS: - ipcRenderer.invoke(UPDATE_TEAMS, event.data.data); - break; - case GET_LANGUAGE_INFORMATION: - window.postMessage({type: RETRIEVED_LANGUAGE_INFORMATION, data: await ipcRenderer.invoke(GET_LANGUAGE_INFORMATION)}); - break; - default: - console.log(`got a message: ${event}`); - console.log(event); - } -}); - -ipcRenderer.on(UPDATE_TEAMS_DROPDOWN, (event, teams, activeTeam, darkMode, enableServerManagement, hasGPOTeams, expired, mentions, unreads, windowBounds) => { - window.postMessage({type: UPDATE_TEAMS_DROPDOWN, data: {teams, activeTeam, darkMode, enableServerManagement, hasGPOTeams, expired, mentions, unreads, windowBounds}}, window.location.href); -}); diff --git a/src/main/preload/loadingScreenPreload.js b/src/main/preload/loadingScreenPreload.js deleted file mode 100644 index b368cf05..00000000 --- a/src/main/preload/loadingScreenPreload.js +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. -// Copyright (c) 2015-2016 Yuya Ochiai - -'use strict'; - -import {ipcRenderer} from 'electron'; - -import { - RECEIVED_LOADING_SCREEN_DATA, - GET_LOADING_SCREEN_DATA, - LOADING_SCREEN_ANIMATION_FINISHED, - TOGGLE_LOADING_SCREEN_VISIBILITY, - CLOSE_TEAMS_DROPDOWN, - CLOSE_DOWNLOADS_DROPDOWN, -} from 'common/communication'; - -console.log('preloaded for the loading screen!'); - -window.addEventListener('message', async (event) => { - switch (event.data.type) { - case GET_LOADING_SCREEN_DATA: - window.postMessage({type: RECEIVED_LOADING_SCREEN_DATA, data: await ipcRenderer.invoke(GET_LOADING_SCREEN_DATA)}, window.location.href); - break; - case LOADING_SCREEN_ANIMATION_FINISHED: - ipcRenderer.send(LOADING_SCREEN_ANIMATION_FINISHED); - break; - default: - console.log(`got a message: ${event}`); - console.log(event); - } -}); - -ipcRenderer.on(GET_LOADING_SCREEN_DATA, (_, result) => { - window.postMessage({type: RECEIVED_LOADING_SCREEN_DATA, data: result}, window.location.href); -}); - -ipcRenderer.on(TOGGLE_LOADING_SCREEN_VISIBILITY, (_, toggle) => { - window.postMessage({type: TOGGLE_LOADING_SCREEN_VISIBILITY, data: toggle}, window.location.href); -}); - -window.addEventListener('click', () => { - ipcRenderer.send(CLOSE_TEAMS_DROPDOWN); - ipcRenderer.send(CLOSE_DOWNLOADS_DROPDOWN); -}); diff --git a/src/main/preload/modalPreload.js b/src/main/preload/modalPreload.js deleted file mode 100644 index 5315442e..00000000 --- a/src/main/preload/modalPreload.js +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. -// Copyright (c) 2015-2016 Yuya Ochiai - -'use strict'; - -import {ipcRenderer} from 'electron'; - -import { - MODAL_CANCEL, - MODAL_RESULT, - MODAL_INFO, - RETRIEVE_MODAL_INFO, - MODAL_SEND_IPC_MESSAGE, - GET_DARK_MODE, - DARK_MODE_CHANGE, - GET_MODAL_UNCLOSEABLE, - MODAL_UNCLOSEABLE, - PING_DOMAIN, - PING_DOMAIN_RESPONSE, - GET_LANGUAGE_INFORMATION, - RETRIEVED_LANGUAGE_INFORMATION, -} from 'common/communication'; - -console.log('preloaded for the modal!'); - -let uncloseable = false; -const createKeyDownListener = () => { - window.addEventListener('keydown', (e) => { - if (e.key === 'Escape' && !uncloseable) { - ipcRenderer.send(MODAL_CANCEL); - } - }); -}; - -window.addEventListener('message', async (event) => { - switch (event.data.type) { - case MODAL_CANCEL: { - console.log('canceling modal'); - ipcRenderer.send(MODAL_CANCEL, event.data.data); - break; - } - case MODAL_RESULT: { - console.log(`accepting modal with ${event.data.data}`); - ipcRenderer.send(MODAL_RESULT, event.data.data); - break; - } - case RETRIEVE_MODAL_INFO: - console.log('getting modal data'); - window.postMessage({type: MODAL_INFO, data: await ipcRenderer.invoke(RETRIEVE_MODAL_INFO)}, window.location.href); - break; - case GET_MODAL_UNCLOSEABLE: - console.log('get modal uncloseable'); - uncloseable = await ipcRenderer.invoke(GET_MODAL_UNCLOSEABLE); - createKeyDownListener(); - window.postMessage({type: MODAL_UNCLOSEABLE, data: uncloseable}, window.location.href); - break; - case MODAL_SEND_IPC_MESSAGE: - console.log('sending custom ipc message'); - ipcRenderer.send(event.data.data.type, ...event.data.data.args); - break; - case GET_DARK_MODE: - console.log('getting dark mode value'); - window.postMessage({type: DARK_MODE_CHANGE, data: await ipcRenderer.invoke(GET_DARK_MODE)}, window.location.href); - break; - case PING_DOMAIN: - console.log('pinging domain: ' + event.data.data); - try { - const protocol = await ipcRenderer.invoke(PING_DOMAIN, event.data.data); - window.postMessage({type: PING_DOMAIN_RESPONSE, data: protocol}, window.location.href); - } catch (error) { - window.postMessage({type: PING_DOMAIN_RESPONSE, data: error}, window.location.href); - } - break; - case GET_LANGUAGE_INFORMATION: - window.postMessage({type: RETRIEVED_LANGUAGE_INFORMATION, data: await ipcRenderer.invoke(GET_LANGUAGE_INFORMATION)}); - break; - default: - console.log(`got a message: ${event}`); - console.log(event); - } -}); - -createKeyDownListener(); - -ipcRenderer.on(DARK_MODE_CHANGE, (event, darkMode) => { - window.postMessage({type: DARK_MODE_CHANGE, data: darkMode}, window.location.href); -}); diff --git a/src/main/preload/urlView.js b/src/main/preload/urlView.js deleted file mode 100644 index d66de1cc..00000000 --- a/src/main/preload/urlView.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. -// Copyright (c) 2015-2016 Yuya Ochiai - -'use strict'; - -import {ipcRenderer} from 'electron'; - -import {UPDATE_URL_VIEW_WIDTH} from 'common/communication'; - -console.log('preloaded for the url view'); - -window.addEventListener('message', async (event) => { - switch (event.data.type) { - case UPDATE_URL_VIEW_WIDTH: - ipcRenderer.send(UPDATE_URL_VIEW_WIDTH, event.data.data); - break; - default: - console.log(`got a message: ${event}`); - console.log(event); - } -}); diff --git a/src/main/views/downloadsDropdownMenuView.ts b/src/main/views/downloadsDropdownMenuView.ts index 899bd71a..6a01fd84 100644 --- a/src/main/views/downloadsDropdownMenuView.ts +++ b/src/main/views/downloadsDropdownMenuView.ts @@ -51,7 +51,7 @@ export default class DownloadsDropdownMenuView { this.windowBounds = this.window.getContentBounds(); this.bounds = this.getBounds(DOWNLOADS_DROPDOWN_MENU_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT); - const preload = getLocalPreload('downloadsDropdownMenu.js'); + const preload = getLocalPreload('desktopAPI.js'); this.view = new BrowserView({webPreferences: { preload, diff --git a/src/main/views/downloadsDropdownView.ts b/src/main/views/downloadsDropdownView.ts index 7c7f3a21..8d2e5614 100644 --- a/src/main/views/downloadsDropdownView.ts +++ b/src/main/views/downloadsDropdownView.ts @@ -10,7 +10,6 @@ import {DownloadedItem, DownloadedItems} from 'types/downloads'; import { CLOSE_DOWNLOADS_DROPDOWN, - DOWNLOADS_DROPDOWN_SHOW_FILE_IN_FOLDER, EMIT_CONFIGURATION, OPEN_DOWNLOADS_DROPDOWN, RECEIVE_DOWNLOADS_DROPDOWN_SIZE, @@ -45,7 +44,7 @@ export default class DownloadsDropdownView { this.windowBounds = this.window.getContentBounds(); this.bounds = this.getBounds(DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT); - const preload = getLocalPreload('downloadsDropdown.js'); + const preload = getLocalPreload('desktopAPI.js'); this.view = new BrowserView({webPreferences: { preload, @@ -67,7 +66,6 @@ export default class DownloadsDropdownView { 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(DOWNLOADS_DROPDOWN_SHOW_FILE_IN_FOLDER, this.showFileInFolder); 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); @@ -151,12 +149,6 @@ export default class DownloadsDropdownView { downloadsManager.openFile(item); } - showFileInFolder = (e: IpcMainEvent, item: DownloadedItem) => { - log.debug('DownloadsDropdownView.showFileInFolder', {item}); - - downloadsManager.showFileInFolder(item); - } - getBounds = (width: number, height: number) => { // Must always use integers return { diff --git a/src/main/views/teamDropdownView.ts b/src/main/views/teamDropdownView.ts index ce267f57..52c1c2d9 100644 --- a/src/main/views/teamDropdownView.ts +++ b/src/main/views/teamDropdownView.ts @@ -46,7 +46,7 @@ export default class TeamDropdownView { this.windowBounds = this.window.getContentBounds(); - const preload = getLocalPreload('dropdown.js'); + const preload = getLocalPreload('desktopAPI.js'); this.view = new BrowserView({webPreferences: { preload, @@ -105,14 +105,14 @@ export default class TeamDropdownView { this.view.webContents.send( UPDATE_TEAMS_DROPDOWN, this.teams, - this.activeTeam, this.darkMode, + this.windowBounds, + this.activeTeam, this.enableServerManagement, this.hasGPOTeams, this.expired, this.mentions, this.unreads, - this.windowBounds, ); } diff --git a/src/main/views/viewManager.ts b/src/main/views/viewManager.ts index 5ad1b360..99614394 100644 --- a/src/main/views/viewManager.ts +++ b/src/main/views/viewManager.ts @@ -13,7 +13,6 @@ import { LOAD_SUCCESS, LOAD_FAILED, TOGGLE_LOADING_SCREEN_VISIBILITY, - GET_LOADING_SCREEN_DATA, LOADSCREEN_END, SET_ACTIVE_VIEW, OPEN_TAB, @@ -21,6 +20,7 @@ import { UPDATE_LAST_ACTIVE, UPDATE_URL_VIEW_WIDTH, MAIN_WINDOW_SHOWN, + DARK_MODE_CHANGE, } from 'common/communication'; import Config from 'common/config'; import urlUtils, {equalUrlsIgnoringSubpath} from 'common/utils/url'; @@ -362,7 +362,7 @@ export class ViewManager { } if (url && url !== '') { const urlString = typeof url === 'string' ? url : url.toString(); - const preload = getLocalPreload('urlView.js'); + const preload = getLocalPreload('desktopAPI.js'); const urlView = new BrowserView({ webPreferences: { preload, @@ -427,7 +427,7 @@ export class ViewManager { } createLoadingScreen = () => { - const preload = getLocalPreload('loadingScreenPreload.js'); + const preload = getLocalPreload('desktopAPI.js'); this.loadingScreen = new BrowserView({webPreferences: { preload, @@ -490,7 +490,7 @@ export class ViewManager { updateLoadingScreenDarkMode = (darkMode: boolean) => { if (this.loadingScreen) { - this.loadingScreen.webContents.send(GET_LOADING_SCREEN_DATA, {darkMode}); + this.loadingScreen.webContents.send(DARK_MODE_CHANGE, darkMode); } } diff --git a/src/main/windows/mainWindow.ts b/src/main/windows/mainWindow.ts index 446093d0..6e1e29fa 100644 --- a/src/main/windows/mainWindow.ts +++ b/src/main/windows/mainWindow.ts @@ -46,7 +46,7 @@ function isFramelessWindow() { function createMainWindow(options: {linuxAppIcon: string; fullscreen?: boolean}) { // Create the browser window. - const preload = getLocalPreload('mainWindow.js'); + const preload = getLocalPreload('desktopAPI.js'); let savedWindowState: any; try { savedWindowState = JSON.parse(fs.readFileSync(boundsInfoPath, 'utf-8')); diff --git a/src/main/windows/settingsWindow.ts b/src/main/windows/settingsWindow.ts index 6cc5cee7..68247987 100644 --- a/src/main/windows/settingsWindow.ts +++ b/src/main/windows/settingsWindow.ts @@ -10,7 +10,7 @@ import ContextMenu from '../contextMenu'; import {getLocalPreload, getLocalURLString} from '../utils'; export function createSettingsWindow(mainWindow: BrowserWindow, withDevTools: boolean) { - const preload = getLocalPreload('mainWindow.js'); + const preload = getLocalPreload('desktopAPI.js'); const spellcheck = (typeof Config.useSpellChecker === 'undefined' ? true : Config.useSpellChecker); const settingsWindow = new BrowserWindow({ parent: mainWindow, diff --git a/src/main/windows/windowManager.ts b/src/main/windows/windowManager.ts index e8e54a1a..5ee032dd 100644 --- a/src/main/windows/windowManager.ts +++ b/src/main/windows/windowManager.ts @@ -14,7 +14,6 @@ import { import { MAXIMIZE_CHANGE, HISTORY, - GET_LOADING_SCREEN_DATA, REACT_APP_INITIALIZED, LOADING_SCREEN_ANIMATION_FINISHED, FOCUS_THREE_DOT_MENU, @@ -79,7 +78,6 @@ export class WindowManager { this.assetsDir = path.resolve(app.getAppPath(), 'assets'); ipcMain.on(HISTORY, this.handleHistory); - ipcMain.handle(GET_LOADING_SCREEN_DATA, this.handleLoadingScreenDataRequest); ipcMain.handle(GET_DARK_MODE, this.handleGetDarkMode); ipcMain.on(REACT_APP_INITIALIZED, this.handleReactAppInitialized); ipcMain.on(LOADING_SCREEN_ANIMATION_FINISHED, this.handleLoadingScreenAnimationFinished); diff --git a/src/renderer/components/ConfigureServer.tsx b/src/renderer/components/ConfigureServer.tsx index f8beb044..5b9d55b4 100644 --- a/src/renderer/components/ConfigureServer.tsx +++ b/src/renderer/components/ConfigureServer.tsx @@ -14,7 +14,6 @@ import Input, {STATUS, SIZE} from 'renderer/components/Input'; import LoadingBackground from 'renderer/components/LoadingScreen/LoadingBackground'; import SaveButton from 'renderer/components/SaveButton/SaveButton'; -import {PING_DOMAIN, PING_DOMAIN_RESPONSE} from 'common/communication'; import {MODAL_TRANSITION_TIMEOUT} from 'common/utils/constants'; import urlUtils from 'common/utils/url'; @@ -77,33 +76,15 @@ function ConfigureServer({ if (urlUtils.startsWithProtocol(checkURL)) { return Promise.resolve(checkURL); } - - return new Promise((resolve) => { - let eventCount = 0; - - const handler = (event: {data: {type: string; data: string | Error}}) => { - let newURL = checkURL; - - if (event.data.type === PING_DOMAIN_RESPONSE) { - if (event.data.data instanceof Error) { - console.error(`Could not ping url: ${checkURL}`); - } else { - newURL = `${event.data.data}://${checkURL}`; - setUrl(newURL); - } - - window.removeEventListener('message', handler); - resolve(newURL); - } else if (eventCount >= 3) { - window.removeEventListener('message', handler); - resolve(newURL); - } - - eventCount++; - }; - - window.addEventListener('message', handler); - window.postMessage({type: PING_DOMAIN, data: checkURL}, window.location.href); + return window.desktop.modals.pingDomain(checkURL).then((result: string | Error) => { + let newURL = checkURL; + if (result instanceof Error) { + console.error(`Could not ping url: ${checkURL}`); + } else { + newURL = `${result}://${checkURL}`; + setUrl(newURL); + } + return newURL; }); }; diff --git a/src/renderer/components/DownloadsDropdown/DownloadsDropdownItemFile.tsx b/src/renderer/components/DownloadsDropdown/DownloadsDropdownItemFile.tsx index 3221ee4f..8b99e6ec 100644 --- a/src/renderer/components/DownloadsDropdown/DownloadsDropdownItemFile.tsx +++ b/src/renderer/components/DownloadsDropdown/DownloadsDropdownItemFile.tsx @@ -7,8 +7,6 @@ import classNames from 'classnames'; import {useIntl} from 'react-intl'; -import {DOWNLOADS_DROPDOWN_OPEN_FILE} from 'common/communication'; - import FileSizeAndStatus from './FileSizeAndStatus'; import ProgressBar from './ProgressBar'; import ThreeDotButton from './ThreeDotButton'; @@ -26,7 +24,7 @@ const DownloadsDropdownItemFile = ({item, activeItem}: OwnProps) => { const onFileClick = (e: React.MouseEvent) => { e.preventDefault(); - window.postMessage({type: DOWNLOADS_DROPDOWN_OPEN_FILE, payload: {item}}, window.location.href); + window.desktop.downloadsDropdown.openFile(item); }; const itemFilename = item.type === 'update' ? diff --git a/src/renderer/components/DownloadsDropdown/ThreeDotButton.tsx b/src/renderer/components/DownloadsDropdown/ThreeDotButton.tsx index 7108cf79..04897453 100644 --- a/src/renderer/components/DownloadsDropdown/ThreeDotButton.tsx +++ b/src/renderer/components/DownloadsDropdown/ThreeDotButton.tsx @@ -6,8 +6,6 @@ import {DownloadedItem} from 'types/downloads'; import classNames from 'classnames'; -import {TOGGLE_DOWNLOADS_DROPDOWN_MENU} from 'common/communication'; - type OwnProps = { activeItem?: DownloadedItem; item: DownloadedItem; @@ -22,13 +20,10 @@ const ThreeDotButton = ({item, activeItem, visible}: OwnProps) => { e.stopPropagation(); const coords = buttonElement.current?.getBoundingClientRect(); - window.postMessage({ - type: TOGGLE_DOWNLOADS_DROPDOWN_MENU, - payload: { - coordinates: coords?.toJSON(), - item, - }, - }, window.location.href); + window.desktop.downloadsDropdown.toggleDownloadsDropdownMenu({ + coordinates: coords?.toJSON(), + item, + }); }; return ( diff --git a/src/renderer/components/DownloadsDropdown/Update/UpdateAvailable.tsx b/src/renderer/components/DownloadsDropdown/Update/UpdateAvailable.tsx index 14b966cd..f4ac1356 100644 --- a/src/renderer/components/DownloadsDropdown/Update/UpdateAvailable.tsx +++ b/src/renderer/components/DownloadsDropdown/Update/UpdateAvailable.tsx @@ -8,8 +8,6 @@ import {FormattedMessage} from 'react-intl'; import {Button} from 'react-bootstrap'; -import {START_UPDATE_DOWNLOAD} from 'common/communication'; - import Thumbnail from '../Thumbnail'; type OwnProps = { @@ -19,7 +17,7 @@ type OwnProps = { const UpdateAvailable = ({item}: OwnProps) => { const onButtonClick = (e: React.MouseEvent) => { e?.preventDefault?.(); - window.postMessage({type: START_UPDATE_DOWNLOAD}, window.location.href); + window.desktop.downloadsDropdown.startUpdateDownload(); }; return ( diff --git a/src/renderer/components/DownloadsDropdown/Update/UpdateDownloaded.tsx b/src/renderer/components/DownloadsDropdown/Update/UpdateDownloaded.tsx index 92aed909..dae36d7d 100644 --- a/src/renderer/components/DownloadsDropdown/Update/UpdateDownloaded.tsx +++ b/src/renderer/components/DownloadsDropdown/Update/UpdateDownloaded.tsx @@ -10,8 +10,6 @@ import {Button} from 'react-bootstrap'; import classNames from 'classnames'; -import {START_UPGRADE} from 'common/communication'; - import Thumbnail from '../Thumbnail'; import FileSizeAndStatus from '../FileSizeAndStatus'; @@ -24,7 +22,7 @@ const UpdateAvailable = ({item}: OwnProps) => { const onButtonClick = (e: React.MouseEvent) => { e?.preventDefault?.(); - window.postMessage({type: START_UPGRADE}, window.location.href); + window.desktop.downloadsDropdown.startUpgrade(); }; return ( diff --git a/src/renderer/components/NewTeamModal.tsx b/src/renderer/components/NewTeamModal.tsx index 19c1e044..a1982f47 100644 --- a/src/renderer/components/NewTeamModal.tsx +++ b/src/renderer/components/NewTeamModal.tsx @@ -9,7 +9,6 @@ import {FormattedMessage, injectIntl, IntlShape} from 'react-intl'; import {TeamWithIndex} from 'types/config'; import urlUtils from 'common/utils/url'; -import {PING_DOMAIN, PING_DOMAIN_RESPONSE} from 'common/communication'; type Props = { onClose?: () => void; @@ -157,20 +156,12 @@ class NewTeamModal extends React.PureComponent { return Promise.resolve(undefined); } - return new Promise((resolve) => { - const handler = (event: {data: {type: string; data: string | Error}}) => { - if (event.data.type === PING_DOMAIN_RESPONSE) { - if (event.data.data instanceof Error) { - console.error(`Could not ping url: ${teamUrl}`); - } else { - this.setState({teamUrl: `${event.data.data}://${this.state.teamUrl}`}); - } - window.removeEventListener('message', handler); - resolve(undefined); - } - }; - window.addEventListener('message', handler); - window.postMessage({type: PING_DOMAIN, data: teamUrl}, window.location.href); + return window.desktop.modals.pingDomain(teamUrl).then((result: string | Error) => { + if (result instanceof Error) { + console.error(`Could not ping url: ${teamUrl}`); + } else { + this.setState({teamUrl: `${result}://${this.state.teamUrl}`}); + } }); } diff --git a/src/renderer/components/urlDescription.tsx b/src/renderer/components/urlDescription.tsx index 8b28b9ec..72340aef 100644 --- a/src/renderer/components/urlDescription.tsx +++ b/src/renderer/components/urlDescription.tsx @@ -3,13 +3,11 @@ import React, {useEffect} from 'react'; -import {UPDATE_URL_VIEW_WIDTH} from 'common/communication'; - export default function UrlDescription(props: {url: string}) { const urlRef = React.createRef(); useEffect(() => { - window.postMessage({type: UPDATE_URL_VIEW_WIDTH, data: urlRef.current?.scrollWidth}, window.location.href); + window.desktop.updateURLViewWidth(urlRef.current?.scrollWidth); }, []); if (props.url) { diff --git a/src/renderer/downloadsDropdown.tsx b/src/renderer/downloadsDropdown.tsx index edb06b70..e37e3ef9 100644 --- a/src/renderer/downloadsDropdown.tsx +++ b/src/renderer/downloadsDropdown.tsx @@ -6,15 +6,7 @@ import ReactDOM from 'react-dom'; import classNames from 'classnames'; import {FormattedMessage} from 'react-intl'; -import {DownloadedItem} from 'types/downloads'; - -import { - CLOSE_DOWNLOADS_DROPDOWN, - REQUEST_CLEAR_DOWNLOADS_DROPDOWN, - REQUEST_DOWNLOADS_DROPDOWN_INFO, - SEND_DOWNLOADS_DROPDOWN_SIZE, - UPDATE_DOWNLOADS_DROPDOWN, -} from 'common/communication'; +import {DownloadedItem, DownloadedItems} from 'types/downloads'; import IntlProvider from './intl_provider'; import DownloadsDropdownItem from './components/DownloadsDropdown/DownloadsDropdownItem'; @@ -36,46 +28,51 @@ class DownloadsDropdown extends React.PureComponent, State downloads: [], }; - window.addEventListener('message', this.handleMessageEvent); + window.desktop.onUpdateDownloadsDropdown(this.handleUpdate); } componentDidMount() { - window.postMessage({type: REQUEST_DOWNLOADS_DROPDOWN_INFO}, window.location.href); + window.addEventListener('click', () => { + window.desktop.closeDownloadsDropdownMenu(); + }); + + window.addEventListener('mousemove', () => { + window.desktop.downloadsDropdown.focus(); + }); + + window.desktop.downloadsDropdown.requestInfo(); } componentDidUpdate() { - window.postMessage({type: SEND_DOWNLOADS_DROPDOWN_SIZE, data: {width: document.body.scrollWidth, height: document.body.scrollHeight}}, window.location.href); + window.desktop.downloadsDropdown.sendSize(document.body.scrollWidth, document.body.scrollHeight); } - handleMessageEvent = (event: MessageEvent) => { - if (event.data.type === UPDATE_DOWNLOADS_DROPDOWN) { - const {downloads, darkMode, windowBounds, item} = event.data.data; - const newDownloads = Object.values(downloads); - newDownloads.sort((a, b) => { - // Show App update first - if (a.type === 'update') { - return -1; - } else if (b.type === 'update') { - return 1; - } - return b?.addedAt - a?.addedAt; - }); - this.setState({ - downloads: newDownloads, - darkMode, - windowBounds, - item, - }); - } + handleUpdate = (downloads: DownloadedItems, darkMode: boolean, windowBounds: Electron.Rectangle, item?: DownloadedItem) => { + const newDownloads = Object.values(downloads); + newDownloads.sort((a, b) => { + // Show App update first + if (a.type === 'update') { + return -1; + } else if (b.type === 'update') { + return 1; + } + return b?.addedAt - a?.addedAt; + }); + this.setState({ + downloads: newDownloads, + darkMode, + windowBounds, + item, + }); } closeMenu = () => { - window.postMessage({type: CLOSE_DOWNLOADS_DROPDOWN}, window.location.href); + window.desktop.closeDownloadsDropdown(); } clearAll = () => { if (!this.clearAllButtonDisabled()) { - window.postMessage({type: REQUEST_CLEAR_DOWNLOADS_DROPDOWN}, window.location.href); + window.desktop.downloadsDropdown.requestClearDownloadsDropdown(); } } diff --git a/src/renderer/downloadsDropdownMenu.tsx b/src/renderer/downloadsDropdownMenu.tsx index d9da2ca3..13588fc7 100644 --- a/src/renderer/downloadsDropdownMenu.tsx +++ b/src/renderer/downloadsDropdownMenu.tsx @@ -8,15 +8,6 @@ import {FormattedMessage} from 'react-intl'; import {DownloadedItem} from 'types/downloads'; -import { - DOWNLOADS_DROPDOWN_MENU_CANCEL_DOWNLOAD, - DOWNLOADS_DROPDOWN_MENU_CLEAR_FILE, - DOWNLOADS_DROPDOWN_MENU_OPEN_FILE, - DOWNLOADS_DROPDOWN_MENU_SHOW_FILE_IN_FOLDER, - REQUEST_DOWNLOADS_DROPDOWN_MENU_INFO, - UPDATE_DOWNLOADS_DROPDOWN_MENU, -} from 'common/communication'; - import IntlProvider from './intl_provider'; import './css/downloadsDropdownMenu.scss'; @@ -25,20 +16,14 @@ const DownloadsDropdownMenu = () => { const [item, setItem] = useState(null); const [darkMode, setDarkMode] = useState(false); - useEffect(() => { - const handleMessageEvent = (event: MessageEvent) => { - if (event.data.type === UPDATE_DOWNLOADS_DROPDOWN_MENU) { - const {item, darkMode} = event.data.data; - setItem(item); - setDarkMode(darkMode); - } - }; + const handleUpdate = (item: DownloadedItem, darkMode: boolean) => { + setItem(item); + setDarkMode(darkMode); + }; - window.addEventListener('message', handleMessageEvent); - window.postMessage({type: REQUEST_DOWNLOADS_DROPDOWN_MENU_INFO}, window.location.href); - return () => { - window.removeEventListener('message', handleMessageEvent); - }; + useEffect(() => { + window.desktop.downloadsDropdownMenu.requestInfo(); + window.desktop.downloadsDropdownMenu.onUpdateDownloadsDropdownMenu(handleUpdate); }, []); const preventPropagation = (event: React.MouseEvent) => { @@ -76,31 +61,43 @@ const DownloadsDropdownMenu = () => { }; const openFile = useCallback(() => { + if (!item) { + return; + } if (item?.type === 'update') { return; } - window.postMessage({type: DOWNLOADS_DROPDOWN_MENU_OPEN_FILE, payload: {item}}, window.location.href); + window.desktop.downloadsDropdownMenu.openFile(item); }, [item]); const showInFolder = useCallback(() => { + if (!item) { + return; + } if (item?.type === 'update') { return; } - window.postMessage({type: DOWNLOADS_DROPDOWN_MENU_SHOW_FILE_IN_FOLDER, payload: {item}}, window.location.href); + window.desktop.downloadsDropdownMenu.showInFolder(item); }, [item]); const clearFile = useCallback(() => { + if (!item) { + return; + } if (item?.type === 'update') { return; } - window.postMessage({type: DOWNLOADS_DROPDOWN_MENU_CLEAR_FILE, payload: {item}}, window.location.href); + window.desktop.downloadsDropdownMenu.clearFile(item); }, [item]); const cancelDownload = useCallback(() => { + if (!item) { + return; + } if (item?.state !== 'progressing') { return; } - window.postMessage({type: DOWNLOADS_DROPDOWN_MENU_CANCEL_DOWNLOAD, payload: {item}}, window.location.href); + window.desktop.downloadsDropdownMenu.cancelDownload(item); }, [item]); return ( diff --git a/src/renderer/dropdown.tsx b/src/renderer/dropdown.tsx index 893b0d0f..9b1edd4d 100644 --- a/src/renderer/dropdown.tsx +++ b/src/renderer/dropdown.tsx @@ -9,16 +9,6 @@ import {DragDropContext, Draggable, DraggingStyle, Droppable, DropResult, NotDra import {Team, TeamWithTabs, TeamWithTabsAndGpo} from 'types/config'; -import { - CLOSE_TEAMS_DROPDOWN, - REQUEST_TEAMS_DROPDOWN_INFO, - SEND_DROPDOWN_MENU_SIZE, - SHOW_NEW_SERVER_MODAL, - SHOW_EDIT_SERVER_MODAL, - SHOW_REMOVE_SERVER_MODAL, - SWITCH_SERVER, UPDATE_TEAMS, - UPDATE_TEAMS_DROPDOWN, -} from 'common/communication'; import {getTabViewName} from 'common/tabs/TabView'; import {TAB_BAR_HEIGHT, THREE_DOT_MENU_WIDTH_MAC} from 'common/utils/constants'; @@ -64,30 +54,38 @@ class TeamDropdown extends React.PureComponent, State> { this.buttonRefs = new Map(); this.addServerRef = React.createRef(); - window.addEventListener('message', this.handleMessageEvent); + + window.desktop.serverDropdown.onUpdateServerDropdown(this.handleUpdate); } - handleMessageEvent = (event: MessageEvent) => { - if (event.data.type === UPDATE_TEAMS_DROPDOWN) { - const {teams, activeTeam, darkMode, enableServerManagement, hasGPOTeams, unreads, mentions, expired, windowBounds} = event.data.data; - this.setState({ - teams, - orderedTeams: teams.concat().sort((a: TeamWithTabs, b: TeamWithTabs) => a.order - b.order), - activeTeam, - darkMode, - enableServerManagement, - hasGPOTeams, - unreads, - mentions, - expired, - windowBounds, - }); - } + handleUpdate = ( + teams: TeamWithTabsAndGpo[], + darkMode: boolean, + windowBounds: Electron.Rectangle, + activeTeam?: string, + enableServerManagement?: boolean, + hasGPOTeams?: boolean, + expired?: Map, + mentions?: Map, + unreads?: Map, + ) => { + this.setState({ + teams, + orderedTeams: teams.concat().sort((a: TeamWithTabs, b: TeamWithTabs) => a.order - b.order), + activeTeam, + darkMode, + enableServerManagement, + hasGPOTeams, + unreads, + mentions, + expired, + windowBounds, + }); } selectServer = (team: Team) => { return () => { - window.postMessage({type: SWITCH_SERVER, data: team.name}, window.location.href); + window.desktop.serverDropdown.switchServer(team.name); this.closeMenu(); }; } @@ -95,7 +93,7 @@ class TeamDropdown extends React.PureComponent, State> { closeMenu = () => { if (!this.state.isAnyDragging) { (document.activeElement as HTMLElement).blur(); - window.postMessage({type: CLOSE_TEAMS_DROPDOWN}, window.location.href); + window.desktop.closeTeamsDropdown(); } } @@ -104,7 +102,7 @@ class TeamDropdown extends React.PureComponent, State> { } addServer = () => { - window.postMessage({type: SHOW_NEW_SERVER_MODAL}, window.location.href); + window.desktop.serverDropdown.showNewServerModal(); this.closeMenu(); } @@ -142,17 +140,17 @@ class TeamDropdown extends React.PureComponent, State> { teams[t.index].order = order; }); this.setState({teams, orderedTeams: teams.concat().sort((a: Team, b: Team) => a.order - b.order), isAnyDragging: false}); - window.postMessage({type: UPDATE_TEAMS, data: teams}, window.location.href); + window.desktop.updateTeams(teams); } componentDidMount() { - window.postMessage({type: REQUEST_TEAMS_DROPDOWN_INFO}, window.location.href); + window.desktop.serverDropdown.requestInfo(); window.addEventListener('click', this.closeMenu); window.addEventListener('keydown', this.handleKeyboardShortcuts); } componentDidUpdate() { - window.postMessage({type: SEND_DROPDOWN_MENU_SIZE, data: {width: document.body.scrollWidth, height: document.body.scrollHeight}}, window.location.href); + window.desktop.serverDropdown.sendSize(document.body.scrollWidth, document.body.scrollHeight); } componentWillUnmount() { @@ -218,7 +216,7 @@ class TeamDropdown extends React.PureComponent, State> { } return (event: React.MouseEvent) => { event.stopPropagation(); - window.postMessage({type: SHOW_EDIT_SERVER_MODAL, data: {name: teamName}}, window.location.href); + window.desktop.serverDropdown.showEditServerModal(teamName); this.closeMenu(); }; } @@ -229,7 +227,7 @@ class TeamDropdown extends React.PureComponent, State> { } return (event: React.MouseEvent) => { event.stopPropagation(); - window.postMessage({type: SHOW_REMOVE_SERVER_MODAL, data: {name: teamName}}, window.location.href); + window.desktop.serverDropdown.showRemoveServerModal(teamName); this.closeMenu(); }; } diff --git a/src/renderer/intl_provider.tsx b/src/renderer/intl_provider.tsx index bee9b3d3..713da240 100644 --- a/src/renderer/intl_provider.tsx +++ b/src/renderer/intl_provider.tsx @@ -4,8 +4,6 @@ import React from 'react'; import {IntlProvider as BaseIntlProvider} from 'react-intl'; -import {GET_LANGUAGE_INFORMATION, RETRIEVED_LANGUAGE_INFORMATION} from 'common/communication'; - import {Language} from '../../i18n/i18n'; type State = { @@ -18,21 +16,13 @@ export default class IntlProvider extends React.PureComponent { this.state = {}; } - componentDidMount() { - window.addEventListener('message', this.handleMessageEvent); - window.postMessage({type: GET_LANGUAGE_INFORMATION}); + async componentDidMount() { + await this.getLanguageInformation(); } - componentWillUnmount() { - window.removeEventListener('message', this.handleMessageEvent); - } - - handleMessageEvent = (event: MessageEvent<{type: string; data: Language}>) => { - if (event.data.type === RETRIEVED_LANGUAGE_INFORMATION) { - this.setState({ - language: event.data.data, - }); - } + getLanguageInformation = async () => { + const language = await window.desktop.getLanguageInformation(); + this.setState({language}); } render() { diff --git a/src/renderer/modals/certificate/certificate.tsx b/src/renderer/modals/certificate/certificate.tsx index 6206aea6..ea9a2a6e 100644 --- a/src/renderer/modals/certificate/certificate.tsx +++ b/src/renderer/modals/certificate/certificate.tsx @@ -5,12 +5,12 @@ import React from 'react'; import ReactDOM from 'react-dom'; import {Certificate} from 'electron/renderer'; -import {MODAL_CANCEL, MODAL_RESULT, RETRIEVE_MODAL_INFO} from 'common/communication'; - import 'bootstrap/dist/css/bootstrap.min.css'; import 'renderer/css/modals.css'; import 'renderer/css/components/CertificateModal.css'; +import {CertificateModalInfo} from 'types/modals'; + import setupDarkMode from '../darkMode'; import SelectCertificateModal from './certificateModal'; @@ -18,15 +18,15 @@ import SelectCertificateModal from './certificateModal'; setupDarkMode(); const handleCancel = () => { - window.postMessage({type: MODAL_CANCEL}, window.location.href); + window.desktop.modals.cancelModal(); }; const handleSelect = (cert: Certificate) => { - window.postMessage({type: MODAL_RESULT, data: {cert}}, window.location.href); + window.desktop.modals.finishModal({cert}); }; const getCertInfo = () => { - window.postMessage({type: RETRIEVE_MODAL_INFO}, window.location.href); + return window.desktop.modals.getModalInfo(); }; const start = async () => { diff --git a/src/renderer/modals/certificate/certificateModal.tsx b/src/renderer/modals/certificate/certificateModal.tsx index d52b9d2c..2a021ce7 100644 --- a/src/renderer/modals/certificate/certificateModal.tsx +++ b/src/renderer/modals/certificate/certificateModal.tsx @@ -6,11 +6,6 @@ import React, {Fragment} from 'react'; import {Modal, Button, Table, Row, Col} from 'react-bootstrap'; import {FormattedMessage} from 'react-intl'; -import {CertificateModalData} from 'types/certificate'; -import {ModalMessage} from 'types/modals'; - -import {MODAL_INFO} from 'common/communication'; - import IntlProvider from 'renderer/intl_provider'; import ShowCertificateModal from '../../components/showCertificateModal'; @@ -18,7 +13,7 @@ import ShowCertificateModal from '../../components/showCertificateModal'; type Props = { onSelect: (cert: Certificate) => void; onCancel?: () => void; - getCertInfo: () => void; + getCertInfo: () => Promise<{url: string; list: Certificate[]}>; } type State = { @@ -34,27 +29,14 @@ export default class SelectCertificateModal extends React.PureComponent}) => { - switch (event.data.type) { - case MODAL_INFO: { - const {url, list} = event.data.data; - this.setState({url, list}); - break; - } - default: - break; - } - } + getCertInfo = async () => { + const {url, list} = await this.props.getCertInfo(); + this.setState({url, list}); + }; selectfn = (index: number) => { return (() => { diff --git a/src/renderer/modals/darkMode.ts b/src/renderer/modals/darkMode.ts index f4ffe27e..d28e1d73 100644 --- a/src/renderer/modals/darkMode.ts +++ b/src/renderer/modals/darkMode.ts @@ -1,19 +1,16 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {DARK_MODE_CHANGE, GET_DARK_MODE} from 'common/communication'; - import darkStyles from 'renderer/css/lazy/modals-dark.lazy.css'; export default function addDarkModeListener() { - window.addEventListener('message', async (event) => { - if (event.data.type === DARK_MODE_CHANGE) { - if (event.data.data) { - darkStyles.use(); - } else { - darkStyles.unuse(); - } + const setDarkMode = (darkMode: boolean) => { + if (darkMode) { + darkStyles.use(); + } else { + darkStyles.unuse(); } - }); - window.postMessage({type: GET_DARK_MODE}, window.location.href); + }; + window.desktop.onDarkModeChange(setDarkMode); + window.desktop.getDarkMode().then(setDarkMode); } diff --git a/src/renderer/modals/editServer/editServer.tsx b/src/renderer/modals/editServer/editServer.tsx index 3540c1f9..68d99b44 100644 --- a/src/renderer/modals/editServer/editServer.tsx +++ b/src/renderer/modals/editServer/editServer.tsx @@ -8,9 +8,6 @@ import React, {useEffect, useState} from 'react'; import ReactDOM from 'react-dom'; import {TeamWithIndex} from 'types/config'; -import {ModalMessage} from 'types/modals'; - -import {MODAL_CANCEL, MODAL_INFO, MODAL_RESULT, RETRIEVE_MODAL_INFO} from 'common/communication'; import IntlProvider from 'renderer/intl_provider'; @@ -20,33 +17,28 @@ import setupDarkMode from '../darkMode'; setupDarkMode(); +type ModalInfo = { + team: TeamWithIndex; + currentTeams: TeamWithIndex[]; +}; + const onClose = () => { - window.postMessage({type: MODAL_CANCEL}, window.location.href); + window.desktop.modals.cancelModal(); }; const onSave = (data: TeamWithIndex) => { - window.postMessage({type: MODAL_RESULT, data}, window.location.href); + window.desktop.modals.finishModal(data); }; const EditServerModalWrapper: React.FC = () => { const [server, setServer] = useState(); const [currentTeams, setCurrentTeams] = useState(); - const handleEditServerMessage = (event: {data: ModalMessage<{currentTeams: TeamWithIndex[]; team: TeamWithIndex}>}) => { - switch (event.data.type) { - case MODAL_INFO: { - setServer(event.data.data.team); - setCurrentTeams(event.data.data.currentTeams); - break; - } - default: - break; - } - }; - useEffect(() => { - window.addEventListener('message', handleEditServerMessage); - window.postMessage({type: RETRIEVE_MODAL_INFO}, window.location.href); + window.desktop.modals.getModalInfo().then(({team, currentTeams}) => { + setServer(team); + setCurrentTeams(currentTeams); + }); }, []); return ( diff --git a/src/renderer/modals/loadingScreen/index.tsx b/src/renderer/modals/loadingScreen/index.tsx index efbeacd5..8a27a6ee 100644 --- a/src/renderer/modals/loadingScreen/index.tsx +++ b/src/renderer/modals/loadingScreen/index.tsx @@ -4,10 +4,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import {ModalMessage} from 'types/modals'; - -import {RECEIVED_LOADING_SCREEN_DATA, GET_LOADING_SCREEN_DATA, LOADING_SCREEN_ANIMATION_FINISHED, TOGGLE_LOADING_SCREEN_VISIBILITY} from 'common/communication'; - import LoadingScreen from '../../components/LoadingScreen'; import 'bootstrap/dist/css/bootstrap.min.css'; @@ -31,32 +27,29 @@ class LoadingScreenRoot extends React.PureComponent { }; } - componentDidMount() { - window.postMessage({type: GET_LOADING_SCREEN_DATA}, window.location.href); + async componentDidMount() { + window.desktop.onDarkModeChange(this.setDarkMode); + const darkMode = await window.desktop.getDarkMode(); + this.setDarkMode(darkMode); - window.addEventListener('message', this.handleMessageEvent); + window.desktop.loadingScreen.onToggleLoadingScreenVisibility(this.onToggleLoadingScreenVisibility); + + window.addEventListener('click', () => { + window.desktop.closeTeamsDropdown(); + window.desktop.closeDownloadsDropdown(); + }); } - componentWillUnmount() { - window.removeEventListener('message', this.handleMessageEvent); + setDarkMode = (darkMode: boolean) => { + this.setState({darkMode}); } - handleMessageEvent = (event: {data: ModalMessage}) => { - if (event.data.type === RECEIVED_LOADING_SCREEN_DATA) { - this.setState({ - darkMode: event.data.data.darkMode, - }); - } - - if (event.data.type === TOGGLE_LOADING_SCREEN_VISIBILITY) { - this.setState({ - showLoadingScreen: event.data.data, - }); - } + onToggleLoadingScreenVisibility = (showLoadingScreen: boolean) => { + this.setState({showLoadingScreen}); } onFadeOutComplete = () => { - window.postMessage({type: LOADING_SCREEN_ANIMATION_FINISHED}, window.location.href); + window.desktop.loadingScreen.loadingScreenAnimationFinished(); } render() { diff --git a/src/renderer/modals/login/login.tsx b/src/renderer/modals/login/login.tsx index d19b5d80..8179ca49 100644 --- a/src/renderer/modals/login/login.tsx +++ b/src/renderer/modals/login/login.tsx @@ -5,7 +5,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import {AuthenticationResponseDetails} from 'electron/renderer'; -import {MODAL_CANCEL, MODAL_RESULT, RETRIEVE_MODAL_INFO} from 'common/communication'; +import {LoginModalInfo} from 'types/modals'; import IntlProvider from 'renderer/intl_provider'; @@ -19,15 +19,15 @@ import LoginModal from './loginModal'; setupDarkMode(); const handleLoginCancel = (request: AuthenticationResponseDetails) => { - window.postMessage({type: MODAL_CANCEL, data: {request}}, window.location.href); + window.desktop.modals.cancelModal({request}); }; const handleLogin = (request: AuthenticationResponseDetails, username: string, password: string) => { - window.postMessage({type: MODAL_RESULT, data: {request, username, password}}, window.location.href); + window.desktop.modals.finishModal({request, username, password}); }; const getAuthInfo = () => { - window.postMessage({type: RETRIEVE_MODAL_INFO}, window.location.href); + return window.desktop.modals.getModalInfo(); }; const start = async () => { diff --git a/src/renderer/modals/login/loginModal.tsx b/src/renderer/modals/login/loginModal.tsx index f8ae93e8..9cde1712 100644 --- a/src/renderer/modals/login/loginModal.tsx +++ b/src/renderer/modals/login/loginModal.tsx @@ -6,17 +6,16 @@ import React from 'react'; import {Button, Col, FormLabel, Form, FormGroup, FormControl, Modal} from 'react-bootstrap'; import {FormattedMessage, injectIntl, IntlShape} from 'react-intl'; -import {LoginModalData} from 'types/auth'; -import {ModalMessage} from 'types/modals'; import {AuthenticationResponseDetails, AuthInfo} from 'electron/renderer'; +import {LoginModalInfo} from 'types/modals'; + import urlUtils from 'common/utils/url'; -import {MODAL_INFO} from 'common/communication'; type Props = { onCancel: (request: AuthenticationResponseDetails) => void; onLogin: (request: AuthenticationResponseDetails, username: string, password: string) => void; - getAuthInfo: () => void; + getAuthInfo: () => Promise; intl: IntlShape; }; @@ -36,26 +35,13 @@ class LoginModal extends React.PureComponent { }; } - componentDidMount() { - window.addEventListener('message', this.handleAuthInfoMessage); - - this.props.getAuthInfo(); + async componentDidMount() { + await this.getAuthInfo(); } - componentWillUnmount() { - window.removeEventListener('message', this.handleAuthInfoMessage); - } - - handleAuthInfoMessage = (event: {data: ModalMessage}) => { - switch (event.data.type) { - case MODAL_INFO: { - const {request, authInfo} = event.data.data; - this.setState({request, authInfo}); - break; - } - default: - break; - } + getAuthInfo = async () => { + const {request, authInfo} = await this.props.getAuthInfo(); + this.setState({request, authInfo}); } handleSubmit = (event: React.FormEvent) => { diff --git a/src/renderer/modals/newServer/newServer.tsx b/src/renderer/modals/newServer/newServer.tsx index 5f2a3616..323173a5 100644 --- a/src/renderer/modals/newServer/newServer.tsx +++ b/src/renderer/modals/newServer/newServer.tsx @@ -8,9 +8,6 @@ import React, {useEffect, useState} from 'react'; import ReactDOM from 'react-dom'; import {TeamWithIndex} from 'types/config'; -import {ModalMessage} from 'types/modals'; - -import {GET_MODAL_UNCLOSEABLE, MODAL_CANCEL, MODAL_INFO, MODAL_RESULT, MODAL_UNCLOSEABLE, RETRIEVE_MODAL_INFO} from 'common/communication'; import IntlProvider from 'renderer/intl_provider'; @@ -21,39 +18,24 @@ import setupDarkMode from '../darkMode'; setupDarkMode(); const onClose = () => { - window.postMessage({type: MODAL_CANCEL}, window.location.href); + window.desktop.modals.cancelModal(); }; const onSave = (data: TeamWithIndex) => { - window.postMessage({type: MODAL_RESULT, data}, window.location.href); + window.desktop.modals.finishModal(data); }; const NewServerModalWrapper: React.FC = () => { const [unremoveable, setUnremovable] = useState(); const [currentTeams, setCurrentTeams] = useState(); - const handleNewServerMessage = (event: {data: ModalMessage}) => { - switch (event.data.type) { - case MODAL_UNCLOSEABLE: { - setUnremovable(event.data.data as boolean); - break; - } - case MODAL_INFO: - setCurrentTeams(event.data.data as TeamWithIndex[]); - break; - default: - break; - } - }; - useEffect(() => { - window.addEventListener('message', handleNewServerMessage); - window.postMessage({type: GET_MODAL_UNCLOSEABLE}, window.location.href); - window.postMessage({type: RETRIEVE_MODAL_INFO}, window.location.href); - - return () => { - window.removeEventListener('message', handleNewServerMessage); - }; + window.desktop.modals.isModalUncloseable().then((uncloseable) => { + setUnremovable(uncloseable); + }); + window.desktop.modals.getModalInfo().then((teams) => { + setCurrentTeams(teams); + }); }, []); return ( diff --git a/src/renderer/modals/permission/permission.tsx b/src/renderer/modals/permission/permission.tsx index bc82cb26..3e61ded8 100644 --- a/src/renderer/modals/permission/permission.tsx +++ b/src/renderer/modals/permission/permission.tsx @@ -4,7 +4,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import {MODAL_CANCEL, MODAL_RESULT, RETRIEVE_MODAL_INFO, MODAL_SEND_IPC_MESSAGE} from 'common/communication'; +import {PermissionModalInfo} from 'types/modals'; import IntlProvider from 'renderer/intl_provider'; @@ -18,19 +18,19 @@ import PermissionModal from './permissionModal'; setupDarkMode(); const handleDeny = () => { - window.postMessage({type: MODAL_CANCEL}, window.location.href); + window.desktop.modals.cancelModal(); }; const handleGrant = () => { - window.postMessage({type: MODAL_RESULT}, window.location.href); + window.desktop.modals.finishModal(); }; const getPermissionInfo = () => { - window.postMessage({type: RETRIEVE_MODAL_INFO}, window.location.href); + return window.desktop.modals.getModalInfo(); }; const openExternalLink = (protocol: string, url: string) => { - window.postMessage({type: MODAL_SEND_IPC_MESSAGE, data: {type: 'confirm-protocol', args: [protocol, url]}}, window.location.href); + window.desktop.modals.confirmProtocol(protocol, url); }; const start = async () => { diff --git a/src/renderer/modals/permission/permissionModal.tsx b/src/renderer/modals/permission/permissionModal.tsx index e8eebf91..098be8bf 100644 --- a/src/renderer/modals/permission/permissionModal.tsx +++ b/src/renderer/modals/permission/permissionModal.tsx @@ -5,27 +5,21 @@ import React from 'react'; import {Modal, Button} from 'react-bootstrap'; import {FormattedMessage, injectIntl, IntlShape} from 'react-intl'; -import {PermissionType} from 'types/trustedOrigin'; - -import {ModalMessage} from 'types/modals'; +import {PermissionModalInfo} from 'types/modals'; import urlUtil from 'common/utils/url'; import {t} from 'common/utils/util'; -import {MODAL_INFO} from 'common/communication'; import {PERMISSION_DESCRIPTION} from 'common/permissions'; type Props = { handleDeny: React.MouseEventHandler; handleGrant: React.MouseEventHandler; - getPermissionInfo: () => void; + getPermissionInfo: () => Promise; openExternalLink: (protocol: string, url: string) => void; intl: IntlShape; }; -type State = { - url?: string; - permission?: PermissionType; -} +type State = Partial; class PermissionModal extends React.PureComponent { constructor(props: Props) { @@ -33,26 +27,13 @@ class PermissionModal extends React.PureComponent { this.state = {}; } - componentDidMount() { - window.addEventListener('message', this.handlePermissionInfoMessage); - - this.props.getPermissionInfo(); + getPermissionInfo = async () => { + const {url, permission} = await this.props.getPermissionInfo(); + this.setState({url, permission}); } - componentWillUnmount() { - window.removeEventListener('message', this.handlePermissionInfoMessage); - } - - handlePermissionInfoMessage = (event: {data: ModalMessage<{url: string; permission: PermissionType}>}) => { - switch (event.data.type) { - case MODAL_INFO: { - const {url, permission} = event.data.data; - this.setState({url, permission}); - break; - } - default: - break; - } + async componentDidMount() { + await this.getPermissionInfo(); } getModalTitle() { diff --git a/src/renderer/modals/removeServer/removeServer.tsx b/src/renderer/modals/removeServer/removeServer.tsx index 6f1909a6..4e724652 100644 --- a/src/renderer/modals/removeServer/removeServer.tsx +++ b/src/renderer/modals/removeServer/removeServer.tsx @@ -7,10 +7,6 @@ import 'renderer/css/modals.css'; import React, {useEffect, useState} from 'react'; import ReactDOM from 'react-dom'; -import {ModalMessage} from 'types/modals'; - -import {MODAL_CANCEL, MODAL_INFO, MODAL_RESULT, RETRIEVE_MODAL_INFO} from 'common/communication'; - import IntlProvider from 'renderer/intl_provider'; import RemoveServerModal from '../../components/RemoveServerModal'; @@ -20,30 +16,20 @@ import setupDarkMode from '../darkMode'; setupDarkMode(); const onClose = () => { - window.postMessage({type: MODAL_CANCEL}, window.location.href); + window.desktop.modals.cancelModal(); }; const onSave = (data: boolean) => { - window.postMessage({type: MODAL_RESULT, data}, window.location.href); + window.desktop.modals.finishModal(data); }; const RemoveServerModalWrapper: React.FC = () => { const [serverName, setServerName] = useState(''); - const handleRemoveServerMessage = (event: {data: ModalMessage}) => { - switch (event.data.type) { - case MODAL_INFO: { - setServerName(event.data.data); - break; - } - default: - break; - } - }; - useEffect(() => { - window.addEventListener('message', handleRemoveServerMessage); - window.postMessage({type: RETRIEVE_MODAL_INFO}, window.location.href); + window.desktop.modals.getModalInfo<{name: string}>().then(({name}) => { + setServerName(name); + }); }, []); return ( diff --git a/src/renderer/modals/welcomeScreen/welcomeScreen.tsx b/src/renderer/modals/welcomeScreen/welcomeScreen.tsx index 37cd4916..05c9642f 100644 --- a/src/renderer/modals/welcomeScreen/welcomeScreen.tsx +++ b/src/renderer/modals/welcomeScreen/welcomeScreen.tsx @@ -5,16 +5,9 @@ import React, {useEffect, useState} from 'react'; import ReactDOM from 'react-dom'; import {TeamWithIndex} from 'types/config'; -import {ModalMessage} from 'types/modals'; -import { - MODAL_RESULT, - GET_MODAL_UNCLOSEABLE, - GET_DARK_MODE, - DARK_MODE_CHANGE, - MODAL_INFO, -} from 'common/communication'; import IntlProvider from 'renderer/intl_provider'; + import WelcomeScreen from '../../components/WelcomeScreen'; import ConfigureServer from '../../components/ConfigureServer'; @@ -23,7 +16,7 @@ import 'bootstrap/dist/css/bootstrap.min.css'; const MOBILE_SCREEN_WIDTH = 1200; const onConnect = (data: TeamWithIndex) => { - window.postMessage({type: MODAL_RESULT, data}, window.location.href); + window.desktop.modals.finishModal(data); }; const WelcomeScreenModalWrapper = () => { @@ -37,32 +30,26 @@ const WelcomeScreenModalWrapper = () => { }; useEffect(() => { - window.postMessage({type: GET_MODAL_UNCLOSEABLE}, window.location.href); - window.postMessage({type: GET_DARK_MODE}, window.location.href); + window.desktop.getDarkMode().then((result) => { + setDarkMode(result); + }); + + window.desktop.onDarkModeChange((result) => { + setDarkMode(result); + }); + + window.desktop.modals.getModalInfo().then((result) => { + setCurrentTeams(result); + }); handleWindowResize(); - window.addEventListener('resize', handleWindowResize); - window.addEventListener('message', handleMessageEvent); return () => { - window.removeEventListener('message', handleMessageEvent); + window.removeEventListener('resize', handleWindowResize); }; }, []); - const handleMessageEvent = (event: {data: ModalMessage}) => { - switch (event.data.type) { - case DARK_MODE_CHANGE: - setDarkMode(event.data.data as boolean); - break; - case MODAL_INFO: - setCurrentTeams(event.data.data as TeamWithIndex[]); - break; - default: - break; - } - }; - const onGetStarted = () => { setGetStarted(true); }; diff --git a/src/types/modals.ts b/src/types/modals.ts index d1245aa4..f375503f 100644 --- a/src/types/modals.ts +++ b/src/types/modals.ts @@ -1,7 +1,25 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -export type ModalMessage = { - type: string; - data: T; +import { + AuthInfo, + AuthenticationResponseDetails, + Certificate, +} from 'electron/common'; + +import {PermissionType} from './trustedOrigin'; + +export type CertificateModalInfo = { + url: string; + list: Certificate[]; +} + +export type LoginModalInfo = { + request: AuthenticationResponseDetails; + authInfo: AuthInfo; +} + +export type PermissionModalInfo = { + url: string; + permission: PermissionType; } diff --git a/src/types/window.ts b/src/types/window.ts index de648319..a01cf117 100644 --- a/src/types/window.ts +++ b/src/types/window.ts @@ -1,10 +1,12 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {ipcRenderer} from 'electron/renderer'; +import {ipcRenderer, Rectangle} from 'electron/renderer'; -import {CombinedConfig, LocalConfiguration, Team} from './config'; -import {DownloadedItems} from './downloads'; +import {Language} from '../../i18n/i18n'; + +import {CombinedConfig, LocalConfiguration, Team, TeamWithTabsAndGpo} from './config'; +import {DownloadedItem, DownloadedItems, DownloadsMenuOpenEventPayload} from './downloads'; import {SaveQueueItem} from './settings'; declare global { @@ -58,6 +60,7 @@ declare global { getAvailableLanguages: () => Promise; getLocalConfiguration: (option?: keyof LocalConfiguration) => Promise>; getDownloadLocation: (downloadLocation?: string) => Promise; + getLanguageInformation: () => Promise; onSynchronizeConfig: (listener: () => void) => void; onReloadConfiguration: (listener: () => void) => void; @@ -80,9 +83,67 @@ declare global { onOpenDownloadsDropdown: (listener: () => void) => void; onShowDownloadsDropdownButtonBadge: (listener: () => void) => void; onHideDownloadsDropdownButtonBadge: (listener: () => void) => void; - onUpdateDownloadsDropdown: (listener: (downloads: DownloadedItems) => void) => void; + onUpdateDownloadsDropdown: (listener: (downloads: DownloadedItems, darkMode: boolean, windowBounds: Rectangle, item: DownloadedItem) => void) => void; onAppMenuWillClose: (listener: () => void) => void; onFocusThreeDotMenu: (listener: () => void) => void; + + updateURLViewWidth: (width?: number) => void; + + modals: { + cancelModal: (data?: T) => void; + finishModal: (data?: T) => void; + getModalInfo: () => Promise; + isModalUncloseable: () => Promise; + confirmProtocol: (protocol: string, url: string) => void; + pingDomain: (url: string) => Promise; + }; + + loadingScreen: { + loadingScreenAnimationFinished: () => void; + onToggleLoadingScreenVisibility: (listener: (toggle: boolean) => void) => void; + }; + + downloadsDropdown: { + requestInfo: () => void; + sendSize: (width: number, height: number) => void; + openFile: (item: DownloadedItem) => void; + startUpdateDownload: () => void; + startUpgrade: () => void; + requestClearDownloadsDropdown: () => void; + toggleDownloadsDropdownMenu: (payload: DownloadsMenuOpenEventPayload) => void; + focus: () => void; + }; + + downloadsDropdownMenu: { + requestInfo: () => void; + showInFolder: (item: DownloadedItem) => void; + cancelDownload: (item: DownloadedItem) => void; + clearFile: (item: DownloadedItem) => void; + openFile: (item: DownloadedItem) => void; + + onUpdateDownloadsDropdownMenu: (listener: (item: DownloadedItem, darkMode: boolean) => void) => void; + }; + + serverDropdown: { + requestInfo: () => void; + sendSize: (width: number, height: number) => void; + switchServer: (serverName: string) => void; + showNewServerModal: () => void; + showEditServerModal: (serverName: string) => void; + showRemoveServerModal: (serverName: string) => void; + + onUpdateServerDropdown: (listener: ( + teams: TeamWithTabsAndGpo[], + darkMode: boolean, + windowBounds: Rectangle, + activeTeam?: string, + enableServerManagement?: boolean, + hasGPOTeams?: boolean, + expired?: Map, + mentions?: Map, + unreads?: Map, + ) => void) => void; + }; }; } } diff --git a/webpack.config.main.js b/webpack.config.main.js index 84f0a40e..7d8d2178 100644 --- a/webpack.config.main.js +++ b/webpack.config.main.js @@ -15,14 +15,8 @@ const base = require('./webpack.config.base'); module.exports = merge(base, { entry: { index: './src/main/app/index.ts', - mainWindow: './src/main/preload/mainWindow.js', - dropdown: './src/main/preload/dropdown.js', - downloadsDropdown: './src/main/preload/downloadsDropdown.js', - downloadsDropdownMenu: './src/main/preload/downloadsDropdownMenu.js', + desktopAPI: './src/main/preload/desktopAPI.js', preload: './src/main/preload/mattermost.js', - modalPreload: './src/main/preload/modalPreload.js', - loadingScreenPreload: './src/main/preload/loadingScreenPreload.js', - urlView: './src/main/preload/urlView.js', callsWidget: './src/main/preload/callsWidget.js', }, externals: {