diff --git a/.yarnrc b/.yarnrc index 756f21586a..f86ea8e49f 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,3 +1,3 @@ disturl "https://atom.io/download/electron" -target "13.6.1" +target "14.2.1" runtime "electron" diff --git a/package.json b/package.json index 03ff28fa93..05cb2bcfa9 100644 --- a/package.json +++ b/package.json @@ -191,7 +191,6 @@ } }, "dependencies": { - "@electron/remote": "^1.2.2", "@hapi/call": "^8.0.1", "@hapi/subtext": "^7.0.3", "@kubernetes/client-node": "^0.16.1", @@ -334,7 +333,7 @@ "css-loader": "^5.2.7", "deepdash": "^5.3.9", "dompurify": "^2.3.4", - "electron": "^13.6.1", + "electron": "^14.2.1", "electron-builder": "^22.14.5", "electron-notarize": "^0.3.0", "esbuild": "^0.13.15", diff --git a/src/common/ipc/dialog.ts b/src/common/ipc/dialog.ts new file mode 100644 index 0000000000..416714f041 --- /dev/null +++ b/src/common/ipc/dialog.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +export const enum IpcMainDialogEvents { + SHOW_OPEN = "dialog:show-open", +} diff --git a/src/common/ipc/index.ts b/src/common/ipc/index.ts index 9b5bb3a663..9762cd75e5 100644 --- a/src/common/ipc/index.ts +++ b/src/common/ipc/index.ts @@ -13,3 +13,4 @@ export * from "./cluster.ipc"; export * from "./type-enforced-ipc"; export * from "./hotbar"; export * from "./extension-loader.ipc"; +export * from "./window"; diff --git a/src/common/ipc/ipc.ts b/src/common/ipc/ipc.ts index 78ef1f3a16..2b81345a49 100644 --- a/src/common/ipc/ipc.ts +++ b/src/common/ipc/ipc.ts @@ -12,21 +12,8 @@ import { toJS } from "../utils/toJS"; import logger from "../../main/logger"; import { ClusterFrameInfo, clusterFrameMap } from "../cluster-frames"; import type { Disposer } from "../utils"; -import type remote from "@electron/remote"; -const electronRemote = (() => { - if (ipcRenderer) { - try { - return require("@electron/remote"); - } catch { - // ignore temp - } - } - - return null; -})(); - -const subFramesChannel = "ipc:get-sub-frames"; +export const broadcastMainChannel = "ipc:broadcast-main"; export async function requestMain(channel: string, ...args: any[]) { return ipcRenderer.invoke(channel, ...args.map(sanitizePayload)); @@ -42,51 +29,48 @@ function getSubFrames(): ClusterFrameInfo[] { return Array.from(clusterFrameMap.values()); } -export function broadcastMessage(channel: string, ...args: any[]) { - const subFramesP = ipcRenderer - ? requestMain(subFramesChannel) - : Promise.resolve(getSubFrames()); +export async function broadcastMessage(channel: string, ...args: any[]): Promise { + if (ipcRenderer) { + return requestMain(broadcastMainChannel, ...args); + } - subFramesP - .then(subFrames => { - const views: undefined | ReturnType | ReturnType = (webContents || electronRemote?.webContents)?.getAllWebContents(); + const subFrames = getSubFrames(); + const views = webContents.getAllWebContents(); - if (!views || !Array.isArray(views) || views.length === 0) return; - args = args.map(sanitizePayload); + if (!views || !Array.isArray(views) || views.length === 0) return; + args = args.map(sanitizePayload); - ipcRenderer?.send(channel, ...args); - ipcMain?.emit(channel, ...args); + ipcMain?.emit(channel, ...args); - for (const view of views) { - let viewType = "unknown"; + for (const view of views) { + let viewType = "unknown"; - // There will be a uncaught exception if the view is destroyed. - try { - viewType = view.getType(); - } catch { - // We can ignore the view destroyed exception as viewType is only used for logging. - } + // There will be a uncaught exception if the view is destroyed. + try { + viewType = view.getType(); + } catch { + // We can ignore the view destroyed exception as viewType is only used for logging. + } - // Send message to views. - try { - logger.silly(`[IPC]: broadcasting "${channel}" to ${viewType}=${view.id}`, { args }); - view.send(channel, ...args); - } catch (error) { - logger.error(`[IPC]: failed to send IPC message "${channel}" to view "${viewType}=${view.id}"`, { error: String(error) }); - } + // Send message to views. + try { + logger.silly(`[IPC]: broadcasting "${channel}" to ${viewType}=${view.id}`, { args }); + view.send(channel, ...args); + } catch (error) { + logger.error(`[IPC]: failed to send IPC message "${channel}" to view "${viewType}=${view.id}"`, { error: String(error) }); + } - // Send message to subFrames of views. - for (const frameInfo of subFrames) { - logger.silly(`[IPC]: broadcasting "${channel}" to subframe "frameInfo.processId"=${frameInfo.processId} "frameInfo.frameId"=${frameInfo.frameId}`, { args }); + // Send message to subFrames of views. + for (const frameInfo of subFrames) { + logger.silly(`[IPC]: broadcasting "${channel}" to subframe "frameInfo.processId"=${frameInfo.processId} "frameInfo.frameId"=${frameInfo.frameId}`, { args }); - try { - view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args); - } catch (error) { - logger.error(`[IPC]: failed to send IPC message "${channel}" to view "${viewType}=${view.id}"'s subframe "frameInfo.processId"=${frameInfo.processId} "frameInfo.frameId"=${frameInfo.frameId}`, { error: String(error) }); - } - } + try { + view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args); + } catch (error) { + logger.error(`[IPC]: failed to send IPC message "${channel}" to view "${viewType}=${view.id}"'s subframe "frameInfo.processId"=${frameInfo.processId} "frameInfo.frameId"=${frameInfo.frameId}`, { error: String(error) }); } - }); + } + } } export function ipcMainOn(channel: string, listener: (event: Electron.IpcMainEvent, ...args: any[]) => any): Disposer { @@ -101,10 +85,6 @@ export function ipcRendererOn(channel: string, listener: (event: Electron.IpcRen return () => ipcRenderer.off(channel, listener); } -export function bindBroadcastHandlers() { - ipcMainHandle(subFramesChannel, () => getSubFrames()); -} - /** * Sanitizing data for IPC-messaging before send. * Removes possible observable values to avoid exceptions like "can't clone object". diff --git a/src/common/ipc/window.ts b/src/common/ipc/window.ts new file mode 100644 index 0000000000..2846a841f0 --- /dev/null +++ b/src/common/ipc/window.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +export const enum IpcMainWindowEvents { + OPEN_CONTEXT_MENU = "window:open-context-menu", + WINDOW_ACTION = "window:window-action", + LOCATION_CHANGED = "window:location-changed", +} diff --git a/src/main/index.ts b/src/main/index.ts index 663e7d8f53..473a92c370 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -6,7 +6,6 @@ // Main process import { injectSystemCAs } from "../common/system-ca"; -import { initialize as initializeRemote } from "@electron/remote/main"; import * as Mobx from "mobx"; import * as LensExtensionsCommonApi from "../extensions/common-api"; import * as LensExtensionsMainApi from "../extensions/main-api"; @@ -24,7 +23,7 @@ import type { InstalledExtension } from "../extensions/extension-discovery/exten import type { LensExtensionId } from "../extensions/lens-extension"; import { installDeveloperTools } from "./developer-tools"; import { disposer, getAppVersion, getAppVersionFromProxyServer } from "../common/utils"; -import { bindBroadcastHandlers, ipcMainOn } from "../common/ipc"; +import { ipcMainOn } from "../common/ipc"; import { startUpdateChecking } from "./app-updater"; import { IpcRendererNavigationEvents } from "../renderer/navigation/events"; import { pushCatalogToRenderer } from "./catalog-pusher"; @@ -81,9 +80,6 @@ di.runSetups().then(() => { app.disableHardwareAcceleration(); } - logger.debug("[APP-MAIN] initializing remote"); - initializeRemote(); - logger.debug("[APP-MAIN] configuring packages"); configurePackages(); @@ -131,8 +127,6 @@ di.runSetups().then(() => { logger.info("🐚 Syncing shell environment"); await shellSync(); - bindBroadcastHandlers(); - powerMonitor.on("shutdown", () => app.exit()); registerFileProtocol("static", __static); diff --git a/src/main/initializers/init-ipc-main-handlers/init-ipc-main-handlers.ts b/src/main/initializers/init-ipc-main-handlers/init-ipc-main-handlers.ts index 53d2ed9567..1dbc4a01be 100644 --- a/src/main/initializers/init-ipc-main-handlers/init-ipc-main-handlers.ts +++ b/src/main/initializers/init-ipc-main-handlers/init-ipc-main-handlers.ts @@ -9,17 +9,20 @@ import { clusterActivateHandler, clusterSetFrameIdHandler, clusterVisibilityHand import type { ClusterId } from "../../../common/cluster-types"; import { ClusterStore } from "../../../common/cluster-store/cluster-store"; import { appEventBus } from "../../../common/app-event-bus/event-bus"; -import { dialogShowOpenDialogHandler, ipcMainHandle, ipcMainOn } from "../../../common/ipc"; +import { broadcastMainChannel, broadcastMessage, dialogShowOpenDialogHandler, ipcMainHandle, ipcMainOn, IpcMainWindowEvents } from "../../../common/ipc"; import { catalogEntityRegistry } from "../../catalog"; import { pushCatalogToRenderer } from "../../catalog-pusher"; import { ClusterManager } from "../../cluster-manager"; import { ResourceApplier } from "../../resource-applier"; -import { IpcMainWindowEvents, WindowManager } from "../../window-manager"; +import { WindowManager } from "../../window-manager"; import path from "path"; import { remove } from "fs-extra"; import { getAppMenu } from "../../menu/menu"; import type { MenuRegistration } from "../../menu/menu-registration"; import type { IComputedValue } from "mobx"; +import { onLocationChange, windowAction } from "../../ipc/window"; +import { IpcMainDialogEvents } from "../../../common/ipc/dialog"; +import { showOpenDialog } from "../../ipc/dialog"; interface Dependencies { electronMenuItems: IComputedValue, @@ -142,6 +145,14 @@ export const initIpcMainHandlers = ({ electronMenuItems, directoryForLensLocalSt return dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), dialogOpts); }); + ipcMainHandle(IpcMainWindowEvents.WINDOW_ACTION, (event, action) => windowAction(action)); + + ipcMainHandle(IpcMainWindowEvents.LOCATION_CHANGED, () => onLocationChange()); + + ipcMainHandle(IpcMainDialogEvents.SHOW_OPEN, (event, opts) => showOpenDialog(opts)); + + ipcMainHandle(broadcastMainChannel, (event, channel, ...args) => broadcastMessage(channel, ...args)); + ipcMainOn(IpcMainWindowEvents.OPEN_CONTEXT_MENU, async (event) => { const menu = Menu.buildFromTemplate(getAppMenu(WindowManager.getInstance(), electronMenuItems.get())); const options = { diff --git a/src/main/ipc/dialog.ts b/src/main/ipc/dialog.ts new file mode 100644 index 0000000000..fe58bcf677 --- /dev/null +++ b/src/main/ipc/dialog.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { BrowserWindow, dialog, OpenDialogOptions } from "electron"; + +export async function showOpenDialog(dialogOptions: OpenDialogOptions) { + const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), dialogOptions); + + return { canceled, filePaths }; +} diff --git a/src/main/ipc/window.ts b/src/main/ipc/window.ts new file mode 100644 index 0000000000..b7d10e65c6 --- /dev/null +++ b/src/main/ipc/window.ts @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { BrowserWindow, webContents } from "electron"; +import { broadcastMessage } from "../../common/ipc"; + +type WindowAction = "goBack" | "goForward" | "minimize" | "toggleMaximize" | "close"; + +export function windowAction(action: WindowAction) { + const window = BrowserWindow.getFocusedWindow(); + + if (!window) return; + + switch (action) { + case "goBack": { + window.webContents.goBack(); + break; + } + + case "goForward": { + window.webContents.goForward(); + break; + } + + case "minimize": { + window.minimize(); + break; + } + + case "toggleMaximize": { + if (window.isMaximized()) { + window.unmaximize(); + } else { + window.maximize(); + } + break; + } + + case "close": { + window.close(); + break; + } + } + + if (action === "goBack") { + window.webContents.goBack(); + } else if (action === "goForward") { + window.webContents.goForward(); + } else if (action === "toggleMaximize") { + if (window.isMaximized()) { + window.unmaximize(); + } else { + window.maximize(); + } + } +} + +export function onLocationChange() { + const getAllWebContents = webContents.getAllWebContents(); + + const canGoBack = getAllWebContents.some((webContent) => { + if (webContent.getType() === "window") { + return webContent.canGoBack(); + } + + return false; + }); + + const canGoForward = getAllWebContents.some((webContent) => { + if (webContent.getType() === "window") { + return webContent.canGoForward(); + } + + return false; + }); + + broadcastMessage("history:can-go-back", canGoBack); + broadcastMessage("history:can-go-forward", canGoForward); +} diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index 116f02aefe..ab6025d0a3 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -16,10 +16,6 @@ import logger from "./logger"; import { isMac, productName } from "../common/vars"; import { LensProxy } from "./lens-proxy"; -export const enum IpcMainWindowEvents { - OPEN_CONTEXT_MENU = "window:open-context-menu", -} - function isHideable(window: BrowserWindow | null): boolean { return Boolean(window && !window.isDestroyed()); } @@ -75,7 +71,6 @@ export class WindowManager extends Singleton { webPreferences: { nodeIntegration: true, nodeIntegrationInSubFrames: true, - enableRemoteModule: true, webviewTag: true, contextIsolation: false, }, @@ -249,7 +244,6 @@ export class WindowManager extends Singleton { show: false, webPreferences: { nodeIntegration: true, - enableRemoteModule: true, contextIsolation: false, nodeIntegrationInSubFrames: true, }, diff --git a/src/renderer/components/layout/top-bar/top-bar-win-linux.test.tsx b/src/renderer/components/layout/top-bar/top-bar-win-linux.test.tsx index 3cc3a75b3f..e59b54cb0d 100644 --- a/src/renderer/components/layout/top-bar/top-bar-win-linux.test.tsx +++ b/src/renderer/components/layout/top-bar/top-bar-win-linux.test.tsx @@ -7,7 +7,7 @@ import React from "react"; import { fireEvent } from "@testing-library/react"; import "@testing-library/jest-dom/extend-expect"; import { TopBar } from "./top-bar"; -import { IpcMainWindowEvents } from "../../../../main/window-manager"; +import { IpcMainWindowEvents } from "../../../../common/ipc"; import { broadcastMessage } from "../../../../common/ipc"; import * as vars from "../../../../common/vars"; import { getDiForUnitTesting } from "../../../getDiForUnitTesting"; diff --git a/src/renderer/components/layout/top-bar/top-bar.tsx b/src/renderer/components/layout/top-bar/top-bar.tsx index 9a122250d4..9f354167ff 100644 --- a/src/renderer/components/layout/top-bar/top-bar.tsx +++ b/src/renderer/components/layout/top-bar/top-bar.tsx @@ -4,17 +4,15 @@ */ import styles from "./top-bar.module.scss"; -import React, { useEffect, useMemo, useRef } from "react"; +import React, { useEffect, useRef } from "react"; import { observer } from "mobx-react"; import type { IComputedValue } from "mobx"; import { Icon } from "../../icon"; -import { webContents, getCurrentWindow } from "@electron/remote"; import { observable } from "mobx"; -import { broadcastMessage, ipcRendererOn } from "../../../../common/ipc"; +import { broadcastMessage, IpcMainWindowEvents, ipcRendererOn, requestMain } from "../../../../common/ipc"; import { watchHistoryState } from "../../../remote-helpers/history-updater"; import { isActiveRoute, navigate } from "../../../navigation"; import { catalogRoute, catalogURL } from "../../../../common/routes"; -import { IpcMainWindowEvents } from "../../../../main/window-manager"; import { isLinux, isWindows } from "../../../../common/vars"; import { cssNames } from "../../../utils"; import topBarItemsInjectable from "./top-bar-items/top-bar-items.injectable"; @@ -40,7 +38,6 @@ ipcRendererOn("history:can-go-forward", (event, state: boolean) => { const NonInjectedTopBar = (({ items, children, ...rest }: Props & Dependencies) => { const elem = useRef(); - const window = useMemo(() => getCurrentWindow(), []); const openContextMenu = () => { broadcastMessage(IpcMainWindowEvents.OPEN_CONTEXT_MENU); @@ -51,11 +48,11 @@ const NonInjectedTopBar = (({ items, children, ...rest }: Props & Dependencies) }; const goBack = () => { - webContents.getAllWebContents().find((webContent) => webContent.getType() === "window")?.goBack(); + requestMain(IpcMainWindowEvents.WINDOW_ACTION, "back"); }; const goForward = () => { - webContents.getAllWebContents().find((webContent) => webContent.getType() === "window")?.goForward(); + requestMain(IpcMainWindowEvents.WINDOW_ACTION, "forward"); }; const windowSizeToggle = (evt: React.MouseEvent) => { @@ -68,19 +65,15 @@ const NonInjectedTopBar = (({ items, children, ...rest }: Props & Dependencies) }; const minimizeWindow = () => { - window.minimize(); + requestMain(IpcMainWindowEvents.WINDOW_ACTION, "minimize"); }; const toggleMaximize = () => { - if (window.isMaximized()) { - window.unmaximize(); - } else { - window.maximize(); - } + requestMain(IpcMainWindowEvents.WINDOW_ACTION, "toggleMaximize"); }; const closeWindow = () => { - window.close(); + requestMain(IpcMainWindowEvents.WINDOW_ACTION, "close"); }; useEffect(() => { diff --git a/src/renderer/components/path-picker/path-picker.tsx b/src/renderer/components/path-picker/path-picker.tsx index 9a0d81f597..c9be7cfed6 100644 --- a/src/renderer/components/path-picker/path-picker.tsx +++ b/src/renderer/components/path-picker/path-picker.tsx @@ -3,11 +3,13 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { FileFilter, OpenDialogOptions, remote } from "electron"; +import type { FileFilter, OpenDialogOptions } from "electron"; import { observer } from "mobx-react"; import React from "react"; import { cssNames } from "../../utils"; import { Button } from "../button"; +import { requestMain } from "../../../common/ipc"; +import { IpcMainDialogEvents } from "../../../common/ipc/dialog"; export interface PathPickOpts { label: string; @@ -29,8 +31,8 @@ export interface PathPickerProps extends PathPickOpts { export class PathPicker extends React.Component { static async pick(opts: PathPickOpts) { const { onPick, onCancel, label, ...dialogOptions } = opts; - const { dialog, BrowserWindow } = remote; - const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), { + + const { canceled, filePaths } = await requestMain(IpcMainDialogEvents.SHOW_OPEN, { message: label, ...dialogOptions, }); diff --git a/src/renderer/remote-helpers/history-updater.ts b/src/renderer/remote-helpers/history-updater.ts index d0bbe9384a..f066e5df3c 100644 --- a/src/renderer/remote-helpers/history-updater.ts +++ b/src/renderer/remote-helpers/history-updater.ts @@ -3,32 +3,12 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { webContents } from "@electron/remote"; import { reaction } from "mobx"; -import { broadcastMessage } from "../../common/ipc"; +import { IpcMainWindowEvents, requestMain } from "../../common/ipc"; import { navigation } from "../navigation"; export function watchHistoryState() { - return reaction(() => navigation.location, () => { - const getAllWebContents = webContents.getAllWebContents(); - - const canGoBack = getAllWebContents.some((webContent) => { - if (webContent.getType() === "window") { - return webContent.canGoBack(); - } - - return false; - }); - - const canGoForward = getAllWebContents.some((webContent) => { - if (webContent.getType() === "window") { - return webContent.canGoForward(); - } - - return false; - }); - - broadcastMessage("history:can-go-back", canGoBack); - broadcastMessage("history:can-go-forward", canGoForward); + return reaction(() => navigation.location, (location) => { + requestMain(IpcMainWindowEvents.LOCATION_CHANGED, location); }); } diff --git a/yarn.lock b/yarn.lock index db6e481d1f..5dc6e815a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -396,11 +396,6 @@ global-agent "^2.0.2" global-tunnel-ng "^2.7.1" -"@electron/remote@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@electron/remote/-/remote-1.2.2.tgz#4c390a2e669df47af973c09eec106162a296c323" - integrity sha512-PfnXpQGWh4vpX866NNucJRnNOzDRZcsLcLaT32fUth9k0hccsohfxprqEDYLzRg+ZK2xRrtyUN5wYYoHimMCJg== - "@electron/universal@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.0.5.tgz#b812340e4ef21da2b3ee77b2b4d35c9b86defe37" @@ -5055,10 +5050,10 @@ electron-window-state@^5.0.3: jsonfile "^4.0.0" mkdirp "^0.5.1" -electron@^13.6.1: - version "13.6.1" - resolved "https://registry.yarnpkg.com/electron/-/electron-13.6.1.tgz#f61c4f269b57c7dc27e0d5476216a988caa9c752" - integrity sha512-rZ6Y7RberigruefQpWOiI4bA9ppyT88GQF8htY6N1MrAgal5RrBc+Mh92CcGU7zT9QO+XO3DarSgZafNTepffQ== +electron@^14.2.1: + version "14.2.3" + resolved "https://registry.yarnpkg.com/electron/-/electron-14.2.3.tgz#3facf572c57cefe8ce80154ad3e63f937784644b" + integrity sha512-7wBqvzUKhK1tw544w3+F8J7NajnqURGC4pH3VFTiBHU5ayiI/oaTTXJxyFLZ54zsR7xwon/3dYEVjIm2i68+Zg== dependencies: "@electron/get" "^1.0.1" "@types/node" "^14.6.2"