diff --git a/src/main/index.ts b/src/main/index.ts index dcb8c60f8b..8a95ad02db 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -10,12 +10,15 @@ import * as LensExtensionsCommonApi from "../extensions/common-api"; import * as LensExtensionsMainApi from "../extensions/main-api"; import { getDi } from "./getDi"; import startMainApplicationInjectable from "./start-main-application/start-main-application.injectable"; +import shouldStartHiddenInjectable from "./electron-app/features/should-start-hidden.injectable"; const di = getDi(); +const shouldStartHidden = di.inject(shouldStartHiddenInjectable); + const startApplication = di.inject(startMainApplicationInjectable); -void startApplication(); +void startApplication(!shouldStartHidden); /** * Exports for virtual package "@k8slens/extensions" for main-process. diff --git a/src/main/menu/application-menu-items.injectable.ts b/src/main/menu/application-menu-items.injectable.ts index b96cfabfad..34d0955d77 100644 --- a/src/main/menu/application-menu-items.injectable.ts +++ b/src/main/menu/application-menu-items.injectable.ts @@ -20,8 +20,7 @@ import stopServicesAndExitAppInjectable from "../stop-services-and-exit-app.inje import isMacInjectable from "../../common/vars/is-mac.injectable"; import { computed } from "mobx"; import showAboutInjectable from "./show-about.injectable"; -import applicationWindowInjectable from "../start-main-application/lens-window/application-window/application-window.injectable"; -import reloadWindowInjectable from "../start-main-application/lens-window/reload-window.injectable"; +import reloadCurrentApplicationWindowInjectable from "../start-main-application/lens-window/reload-current-application-window.injectable"; import showApplicationWindowInjectable from "../start-main-application/lens-window/show-application-window.injectable"; import processCheckingForUpdatesInjectable from "../application-update/check-for-updates/process-checking-for-updates.injectable"; import openLinkInBrowserInjectable from "../../common/utils/open-link-in-browser.injectable"; @@ -44,9 +43,8 @@ const applicationMenuItemsInjectable = getInjectable({ const updatingIsEnabled = di.inject(updatingIsEnabledInjectable); const electronMenuItems = di.inject(electronMenuItemsInjectable); const showAbout = di.inject(showAboutInjectable); - const applicationWindow = di.inject(applicationWindowInjectable); const showApplicationWindow = di.inject(showApplicationWindowInjectable); - const reloadApplicationWindow = di.inject(reloadWindowInjectable, applicationWindow); + const reloadApplicationWindow = di.inject(reloadCurrentApplicationWindowInjectable); const navigateToPreferences = di.inject(navigateToPreferencesInjectable); const navigateToExtensions = di.inject(navigateToExtensionsInjectable); const navigateToCatalog = di.inject(navigateToCatalogInjectable); diff --git a/src/main/start-main-application/lens-window/application-window/application-window-injection-token.ts b/src/main/start-main-application/lens-window/application-window/application-window-injection-token.ts new file mode 100644 index 0000000000..da469a0b7c --- /dev/null +++ b/src/main/start-main-application/lens-window/application-window/application-window-injection-token.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { LensWindow } from "./create-lens-window.injectable"; + +export const applicationWindowInjectionToken = getInjectionToken({ + id: "application-window-injection-token", +}); diff --git a/src/main/start-main-application/lens-window/application-window/application-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/application-window.injectable.ts deleted file mode 100644 index 45d7631415..0000000000 --- a/src/main/start-main-application/lens-window/application-window/application-window.injectable.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable } from "@ogre-tools/injectable"; -import { lensWindowInjectionToken } from "./lens-window-injection-token"; -import createLensWindowInjectable from "./create-lens-window.injectable"; -import lensProxyPortInjectable from "../../../lens-proxy/lens-proxy-port.injectable"; -import isMacInjectable from "../../../../common/vars/is-mac.injectable"; -import appNameInjectable from "../../../app-paths/app-name/app-name.injectable"; -import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable"; -import waitUntilBundledExtensionsAreLoadedInjectable from "./wait-until-bundled-extensions-are-loaded.injectable"; - -const applicationWindowInjectable = getInjectable({ - id: "application-window", - - instantiate: (di) => { - const createLensWindow = di.inject(createLensWindowInjectable); - const isMac = di.inject(isMacInjectable); - const applicationName = di.inject(appNameInjectable); - const appEventBus = di.inject(appEventBusInjectable); - const waitUntilBundledExtensionsAreLoaded = di.inject(waitUntilBundledExtensionsAreLoadedInjectable); - const lensProxyPort = di.inject(lensProxyPortInjectable); - - return createLensWindow({ - id: "only-application-window", - title: applicationName, - defaultHeight: 900, - defaultWidth: 1440, - getContentSource: () => ({ - url: `http://localhost:${lensProxyPort.get()}`, - }), - resizable: true, - windowFrameUtilitiesAreShown: isMac, - titleBarStyle: isMac ? "hiddenInset" : "hidden", - centered: false, - onFocus: () => { - appEventBus.emit({ name: "app", action: "focus" }); - }, - onBlur: () => { - appEventBus.emit({ name: "app", action: "blur" }); - }, - onDomReady: () => { - appEventBus.emit({ name: "app", action: "dom-ready" }); - }, - beforeOpen: waitUntilBundledExtensionsAreLoaded, - }); - }, - - injectionToken: lensWindowInjectionToken, -}); - -export default applicationWindowInjectable; diff --git a/src/main/start-main-application/lens-window/application-window/create-application-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/create-application-window.injectable.ts new file mode 100644 index 0000000000..91975c314d --- /dev/null +++ b/src/main/start-main-application/lens-window/application-window/create-application-window.injectable.ts @@ -0,0 +1,68 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import createLensWindowInjectable from "./create-lens-window.injectable"; +import lensProxyPortInjectable from "../../../lens-proxy/lens-proxy-port.injectable"; +import isMacInjectable from "../../../../common/vars/is-mac.injectable"; +import appNameInjectable from "../../../app-paths/app-name/app-name.injectable"; +import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable"; +import waitUntilBundledExtensionsAreLoadedInjectable from "./wait-until-bundled-extensions-are-loaded.injectable"; +import { applicationWindowInjectionToken } from "./application-window-injection-token"; + +const createApplicationWindowInjectable = getInjectable({ + id: "create-application-window", + + instantiate: (parentDi) => (id: string) => { + const windowInjectable = getInjectable({ + id: `application-window-for-${id}`, + + instantiate: (di) => { + const createLensWindow = di.inject(createLensWindowInjectable); + const isMac = di.inject(isMacInjectable); + const applicationName = di.inject(appNameInjectable); + const appEventBus = di.inject(appEventBusInjectable); + const waitUntilBundledExtensionsAreLoaded = di.inject(waitUntilBundledExtensionsAreLoadedInjectable); + const lensProxyPort = di.inject(lensProxyPortInjectable); + + return createLensWindow({ + id, + title: applicationName, + defaultHeight: 900, + defaultWidth: 1440, + getContentSource: () => ({ + url: `http://localhost:${lensProxyPort.get()}`, + }), + resizable: true, + windowFrameUtilitiesAreShown: isMac, + titleBarStyle: isMac ? "hiddenInset" : "hidden", + centered: false, + onFocus: () => { + appEventBus.emit({ name: "app", action: "focus" }); + }, + onBlur: () => { + appEventBus.emit({ name: "app", action: "blur" }); + }, + onDomReady: () => { + appEventBus.emit({ name: "app", action: "dom-ready" }); + }, + + onClose: () => { + parentDi.deregister(windowInjectable); + }, + + beforeOpen: waitUntilBundledExtensionsAreLoaded, + }); + }, + + injectionToken: applicationWindowInjectionToken, + }); + + parentDi.register(windowInjectable); + + return parentDi.inject(windowInjectable); + }, +}); + +export default createApplicationWindowInjectable; diff --git a/src/main/start-main-application/lens-window/application-window/create-electron-window.global-override-for-injectable.ts b/src/main/start-main-application/lens-window/application-window/create-electron-window.global-override-for-injectable.ts new file mode 100644 index 0000000000..ef33b43c8e --- /dev/null +++ b/src/main/start-main-application/lens-window/application-window/create-electron-window.global-override-for-injectable.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getGlobalOverride } from "../../../../common/test-utils/get-global-override"; +import createElectronWindowInjectable from "./create-electron-window.injectable"; + +export default getGlobalOverride(createElectronWindowInjectable, () => () => ({ + loadFile: async () => {}, + loadUrl: async () => {}, + show: () => {}, + close: () => {}, + send: () => {}, + reload: () => {}, +})); diff --git a/src/main/start-main-application/lens-window/application-window/create-electron-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/create-electron-window.injectable.ts index 7521a64696..0319b9aa71 100644 --- a/src/main/start-main-application/lens-window/application-window/create-electron-window.injectable.ts +++ b/src/main/start-main-application/lens-window/application-window/create-electron-window.injectable.ts @@ -187,7 +187,14 @@ const createElectronWindowInjectable = getInjectable({ show: () => browserWindow.show(), close: () => browserWindow.close(), - send: (args) => sendToChannelInLensWindow(browserWindow, args), + send: (args) => sendToChannelInLensWindow(configuration.id, browserWindow, args), + + reload: () => { + const wc = browserWindow.webContents; + + wc.reload(); + wc.clearHistory(); + }, }; }; }, diff --git a/src/main/start-main-application/lens-window/application-window/create-first-application-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/create-first-application-window.injectable.ts new file mode 100644 index 0000000000..4e6ad80afa --- /dev/null +++ b/src/main/start-main-application/lens-window/application-window/create-first-application-window.injectable.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import createApplicationWindowInjectable from "./create-application-window.injectable"; + +// Note: Motivation is to create the window with same ID to use stored dimensions +const createFirstApplicationWindowInjectable = getInjectable({ + id: "create-first-application-window", + + instantiate: (di) => { + const createApplicationWindow = di.inject(createApplicationWindowInjectable); + + return () => createApplicationWindow("first-application-window"); + }, +}); + +export default createFirstApplicationWindowInjectable; diff --git a/src/main/start-main-application/lens-window/application-window/create-lens-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/create-lens-window.injectable.ts index fe43f2e41e..6dcf6b0174 100644 --- a/src/main/start-main-application/lens-window/application-window/create-lens-window.injectable.ts +++ b/src/main/start-main-application/lens-window/application-window/create-lens-window.injectable.ts @@ -3,10 +3,10 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { LensWindow, SendToViewArgs } from "./lens-window-injection-token"; import type { ContentSource, ElectronWindowTitleBarStyle } from "./create-electron-window.injectable"; import createElectronWindowForInjectable from "./create-electron-window.injectable"; import assert from "assert"; +import type { ClusterFrameInfo } from "../../../../common/cluster-frames"; export interface ElectronWindow { show: () => void; @@ -14,6 +14,24 @@ export interface ElectronWindow { send: (args: SendToViewArgs) => void; loadFile: (filePath: string) => Promise; loadUrl: (url: string) => Promise; + reload: () => void; +} + +export interface SendToViewArgs { + channel: string; + frameInfo?: ClusterFrameInfo; + data?: unknown[]; +} + +export interface LensWindow { + id: string; + start: () => Promise; + close: () => void; + show: () => void; + send: (args: SendToViewArgs) => void; + isVisible: boolean; + isStarting: boolean; + reload: () => void; } export interface LensWindowConfiguration { @@ -30,6 +48,7 @@ export interface LensWindowConfiguration { onFocus?: () => void; onBlur?: () => void; onDomReady?: () => void; + onClose?: () => void; } const createLensWindowInjectable = getInjectable({ @@ -97,6 +116,7 @@ const createLensWindowInjectable = getInjectable({ browserWindow?.close(); browserWindow = undefined; windowIsShown = false; + configuration.onClose?.(); }, send: (args: SendToViewArgs) => { @@ -106,6 +126,14 @@ const createLensWindowInjectable = getInjectable({ return browserWindow.send(args); }, + + reload: () => { + if (!browserWindow) { + throw new Error(`Tried to reload window "${configuration.id}" but the window was closed`); + } + + return browserWindow.reload(); + }, }; }; }, diff --git a/src/main/start-main-application/lens-window/application-window/get-current-application-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/get-current-application-window.injectable.ts new file mode 100644 index 0000000000..756f7ee8c1 --- /dev/null +++ b/src/main/start-main-application/lens-window/application-window/get-current-application-window.injectable.ts @@ -0,0 +1,16 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { first } from "lodash/fp"; +import { applicationWindowInjectionToken } from "./application-window-injection-token"; + +const getCurrentApplicationWindowInjectable = getInjectable({ + id: "get-current-application-window", + + instantiate: (di) => () => + first(di.injectMany(applicationWindowInjectionToken)), +}); + +export default getCurrentApplicationWindowInjectable; diff --git a/src/main/start-main-application/lens-window/application-window/lens-window-injection-token.ts b/src/main/start-main-application/lens-window/application-window/lens-window-injection-token.ts deleted file mode 100644 index 04c0939a6a..0000000000 --- a/src/main/start-main-application/lens-window/application-window/lens-window-injection-token.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectionToken } from "@ogre-tools/injectable"; -import type { ClusterFrameInfo } from "../../../../common/cluster-frames"; - -export interface SendToViewArgs { - channel: string; - frameInfo?: ClusterFrameInfo; - data?: unknown[]; -} - -export interface LensWindow { - id: string; - start: () => Promise; - close: () => void; - show: () => void; - send: (args: SendToViewArgs) => void; - isVisible: boolean; - isStarting: boolean; -} - -export const lensWindowInjectionToken = getInjectionToken({ - id: "lens-window", -}); diff --git a/src/main/start-main-application/lens-window/application-window/send-to-channel-in-electron-browser-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/send-to-channel-in-electron-browser-window.injectable.ts index 32422b6a94..08de6fec46 100644 --- a/src/main/start-main-application/lens-window/application-window/send-to-channel-in-electron-browser-window.injectable.ts +++ b/src/main/start-main-application/lens-window/application-window/send-to-channel-in-electron-browser-window.injectable.ts @@ -4,7 +4,7 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import type { BrowserWindow } from "electron"; -import type { SendToViewArgs } from "./lens-window-injection-token"; +import type { SendToViewArgs } from "./create-lens-window.injectable"; const sendToChannelInElectronBrowserWindowInjectable = getInjectable({ id: "send-to-channel-in-electron-browser-window", @@ -12,6 +12,7 @@ const sendToChannelInElectronBrowserWindowInjectable = getInjectable({ instantiate: () => ( + windowId: string, browserWindow: BrowserWindow, { channel, frameInfo, data = [] }: SendToViewArgs, ) => { diff --git a/src/main/start-main-application/lens-window/get-visible-windows.injectable.ts b/src/main/start-main-application/lens-window/get-visible-windows.injectable.ts index 0179bdb377..f8e1ceb562 100644 --- a/src/main/start-main-application/lens-window/get-visible-windows.injectable.ts +++ b/src/main/start-main-application/lens-window/get-visible-windows.injectable.ts @@ -5,13 +5,13 @@ import { pipeline } from "@ogre-tools/fp"; import { getInjectable } from "@ogre-tools/injectable"; import { filter } from "lodash/fp"; -import { lensWindowInjectionToken } from "./application-window/lens-window-injection-token"; +import { applicationWindowInjectionToken } from "./application-window/application-window-injection-token"; const getVisibleWindowsInjectable = getInjectable({ id: "get-visible-windows", instantiate: (di) => { - const getAllLensWindows = () => di.injectMany(lensWindowInjectionToken); + const getAllLensWindows = () => di.injectMany(applicationWindowInjectionToken); return () => pipeline( diff --git a/src/main/start-main-application/lens-window/hide-all-windows/close-all-windows.injectable.ts b/src/main/start-main-application/lens-window/hide-all-windows/close-all-windows.injectable.ts index f9bbd34935..38f6fec7b9 100644 --- a/src/main/start-main-application/lens-window/hide-all-windows/close-all-windows.injectable.ts +++ b/src/main/start-main-application/lens-window/hide-all-windows/close-all-windows.injectable.ts @@ -3,13 +3,13 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { lensWindowInjectionToken } from "../application-window/lens-window-injection-token"; +import { applicationWindowInjectionToken } from "../application-window/application-window-injection-token"; const closeAllWindowsInjectable = getInjectable({ id: "close-all-windows", instantiate: (di) => () => { - const lensWindows = di.injectMany(lensWindowInjectionToken); + const lensWindows = di.injectMany(applicationWindowInjectionToken); lensWindows.forEach((lensWindow) => { lensWindow.close(); diff --git a/src/main/start-main-application/lens-window/navigate-for-extension.injectable.ts b/src/main/start-main-application/lens-window/navigate-for-extension.injectable.ts index 7bada3f3bd..8022647f8b 100644 --- a/src/main/start-main-application/lens-window/navigate-for-extension.injectable.ts +++ b/src/main/start-main-application/lens-window/navigate-for-extension.injectable.ts @@ -6,7 +6,8 @@ import { getInjectable } from "@ogre-tools/injectable"; import { iter } from "../../../common/utils"; import clusterFramesInjectable from "../../../common/cluster-frames.injectable"; import showApplicationWindowInjectable from "./show-application-window.injectable"; -import applicationWindowInjectable from "./application-window/application-window.injectable"; +import getCurrentApplicationWindowInjectable from "./application-window/get-current-application-window.injectable"; +import assert from "assert"; export type NavigateForExtension = ( extId: string, @@ -19,7 +20,7 @@ const navigateForExtensionInjectable = getInjectable({ id: "navigate-for-extension", instantiate: (di): NavigateForExtension => { - const applicationWindow = di.inject(applicationWindowInjectable); + const getApplicationWindow = di.inject(getCurrentApplicationWindowInjectable); const clusterFrames = di.inject(clusterFramesInjectable); const showApplicationWindow = di.inject(showApplicationWindowInjectable); @@ -31,6 +32,10 @@ const navigateForExtensionInjectable = getInjectable({ ) => { await showApplicationWindow(); + const applicationWindow = getApplicationWindow(); + + assert(applicationWindow); + const frameInfo = iter.find( clusterFrames.values(), (frameInfo) => frameInfo.frameId === frameId, diff --git a/src/main/start-main-application/lens-window/navigate.injectable.ts b/src/main/start-main-application/lens-window/navigate.injectable.ts index f9d80e4205..1916b8205f 100644 --- a/src/main/start-main-application/lens-window/navigate.injectable.ts +++ b/src/main/start-main-application/lens-window/navigate.injectable.ts @@ -4,22 +4,27 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { iter } from "../../../common/utils"; -import applicationWindowInjectable from "./application-window/application-window.injectable"; import clusterFramesInjectable from "../../../common/cluster-frames.injectable"; import { IpcRendererNavigationEvents } from "../../../renderer/navigation/events"; import showApplicationWindowInjectable from "./show-application-window.injectable"; +import getCurrentApplicationWindowInjectable from "./application-window/get-current-application-window.injectable"; +import assert from "assert"; const navigateInjectable = getInjectable({ id: "navigate", instantiate: (di) => { - const applicationWindow = di.inject(applicationWindowInjectable); + const getApplicationWindow = di.inject(getCurrentApplicationWindowInjectable); const showApplicationWindow = di.inject(showApplicationWindowInjectable); const clusterFrames = di.inject(clusterFramesInjectable); return async (url: string, frameId?: number) => { await showApplicationWindow(); + const applicationWindow = getApplicationWindow(); + + assert(applicationWindow); + const frameInfo = iter.find( clusterFrames.values(), (frameInfo) => frameInfo.frameId === frameId, diff --git a/src/main/start-main-application/lens-window/reload-all-windows.injectable.ts b/src/main/start-main-application/lens-window/reload-all-windows.injectable.ts deleted file mode 100644 index fca4da5e13..0000000000 --- a/src/main/start-main-application/lens-window/reload-all-windows.injectable.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable } from "@ogre-tools/injectable"; -import { webContents } from "electron"; - -const reloadAllWindowsInjectable = getInjectable({ - id: "reload-all-windows", - - instantiate: () => () => { - webContents - .getAllWebContents() - .filter((wc) => wc.getType() === "window") - .forEach((wc) => { - wc.reload(); - wc.clearHistory(); - }); - }, - - causesSideEffects: true, -}); - -export default reloadAllWindowsInjectable; diff --git a/src/main/start-main-application/lens-window/reload-current-application-window.injectable.ts b/src/main/start-main-application/lens-window/reload-current-application-window.injectable.ts new file mode 100644 index 0000000000..daaf88a24c --- /dev/null +++ b/src/main/start-main-application/lens-window/reload-current-application-window.injectable.ts @@ -0,0 +1,38 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { IpcRendererNavigationEvents } from "../../../renderer/navigation/events"; +import currentClusterFrameInjectable from "./current-cluster-frame/current-cluster-frame.injectable"; +import getCurrentApplicationWindowInjectable from "./application-window/get-current-application-window.injectable"; + +const reloadCurrentApplicationWindowInjectable = getInjectable({ + id: "reload-current-application-window", + + instantiate: (di) => { + const getCurrentApplicationWindow = di.inject(getCurrentApplicationWindowInjectable); + const currentClusterIframe = di.inject(currentClusterFrameInjectable); + + return () => { + const lensWindow = getCurrentApplicationWindow(); + + if (!lensWindow) { + return; + } + + const frameInfo = currentClusterIframe.get(); + + if (frameInfo) { + lensWindow.send({ + channel: IpcRendererNavigationEvents.RELOAD_PAGE, + frameInfo, + }); + } else { + lensWindow.reload(); + } + }; + }, +}); + +export default reloadCurrentApplicationWindowInjectable; diff --git a/src/main/start-main-application/lens-window/reload-window.injectable.ts b/src/main/start-main-application/lens-window/reload-window.injectable.ts deleted file mode 100644 index 99d3f22f14..0000000000 --- a/src/main/start-main-application/lens-window/reload-window.injectable.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; -import type { LensWindow } from "./application-window/lens-window-injection-token"; -import { IpcRendererNavigationEvents } from "../../../renderer/navigation/events"; -import currentClusterFrameInjectable from "./current-cluster-frame/current-cluster-frame.injectable"; -import reloadAllWindowsInjectable from "./reload-all-windows.injectable"; - -const reloadWindowInjectable = getInjectable({ - id: "reload-window", - - instantiate: (di, lensWindow: LensWindow) => () => { - const currentClusterIframe = di.inject(currentClusterFrameInjectable); - const reloadAllWindows = di.inject(reloadAllWindowsInjectable); - - const frameInfo = currentClusterIframe.get(); - - if (frameInfo) { - lensWindow.send({ - channel: IpcRendererNavigationEvents.RELOAD_PAGE, - frameInfo, - }); - } else { - reloadAllWindows(); - } - }, - - lifecycle: lifecycleEnum.transient, -}); - -export default reloadWindowInjectable; diff --git a/src/main/start-main-application/lens-window/show-application-window.injectable.ts b/src/main/start-main-application/lens-window/show-application-window.injectable.ts index bc14a1a2f2..b3d66cd113 100644 --- a/src/main/start-main-application/lens-window/show-application-window.injectable.ts +++ b/src/main/start-main-application/lens-window/show-application-window.injectable.ts @@ -4,22 +4,31 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import splashWindowInjectable from "./splash-window/splash-window.injectable"; -import applicationWindowInjectable from "./application-window/application-window.injectable"; import { identity, some } from "lodash/fp"; import focusApplicationInjectable from "../../electron-app/features/focus-application.injectable"; +import getCurrentApplicationWindowInjectable from "./application-window/get-current-application-window.injectable"; +import type { LensWindow } from "./application-window/create-lens-window.injectable"; +import createFirstApplicationWindowInjectable from "./application-window/create-first-application-window.injectable"; const someIsTruthy = some(identity); const showApplicationWindowInjectable = getInjectable({ id: "show-application-window", instantiate: (di) => { - const applicationWindow = di.inject(applicationWindowInjectable); + const getApplicationWindow = di.inject(getCurrentApplicationWindowInjectable); + const createFirstApplicationWindow = di.inject(createFirstApplicationWindowInjectable); const splashWindow = di.inject(splashWindowInjectable); const focusApplication = di.inject(focusApplicationInjectable); return async () => { focusApplication(); + let applicationWindow: LensWindow | undefined = getApplicationWindow(); + + if (!applicationWindow) { + applicationWindow = createFirstApplicationWindow(); + } + if (applicationWindow.isStarting) { applicationWindow.show(); splashWindow.close(); diff --git a/src/main/start-main-application/lens-window/splash-window/splash-window.injectable.ts b/src/main/start-main-application/lens-window/splash-window/splash-window.injectable.ts index ab8c2c0c35..72c65d6c8d 100644 --- a/src/main/start-main-application/lens-window/splash-window/splash-window.injectable.ts +++ b/src/main/start-main-application/lens-window/splash-window/splash-window.injectable.ts @@ -3,7 +3,6 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { lensWindowInjectionToken } from "../application-window/lens-window-injection-token"; import createLensWindowInjectable from "../application-window/create-lens-window.injectable"; import staticFilesDirectoryInjectable from "../../../../common/vars/static-files-directory.injectable"; import getAbsolutePathInjectable from "../../../../common/path/get-absolute-path.injectable"; @@ -30,8 +29,6 @@ const splashWindowInjectable = getInjectable({ centered: true, }); }, - - injectionToken: lensWindowInjectionToken, }); export default splashWindowInjectable; diff --git a/src/main/start-main-application/start-main-application.injectable.ts b/src/main/start-main-application/start-main-application.injectable.ts index fa85d9f029..0bf77b2fcd 100644 --- a/src/main/start-main-application/start-main-application.injectable.ts +++ b/src/main/start-main-application/start-main-application.injectable.ts @@ -12,13 +12,12 @@ import { onLoadOfApplicationInjectionToken } from "./runnable-tokens/on-load-of- import { afterApplicationIsLoadedInjectionToken } from "./runnable-tokens/after-application-is-loaded-injection-token"; import splashWindowInjectable from "./lens-window/splash-window/splash-window.injectable"; -import applicationWindowInjectable from "./lens-window/application-window/application-window.injectable"; -import shouldStartHiddenInjectable from "../electron-app/features/should-start-hidden.injectable"; import openDeepLinkInjectable from "../protocol-handler/lens-protocol-router-main/open-deep-link-for-url/open-deep-link.injectable"; import { pipeline } from "@ogre-tools/fp"; import { find, map, startsWith, toLower } from "lodash/fp"; import commandLineArgumentsInjectable from "../utils/command-line-arguments.injectable"; import waitForElectronToBeReadyInjectable from "../electron-app/features/wait-for-electron-to-be-ready.injectable"; +import createFirstApplicationWindowInjectable from "./lens-window/application-window/create-first-application-window.injectable"; const startMainApplicationInjectable = getInjectable({ id: "start-main-application", @@ -27,9 +26,8 @@ const startMainApplicationInjectable = getInjectable({ const runMany = runManyFor(di); const runManySync = runManySyncFor(di); const waitForElectronToBeReady = di.inject(waitForElectronToBeReadyInjectable); - const applicationWindow = di.inject(applicationWindowInjectable); + const createFirstApplicationWindow = di.inject(createFirstApplicationWindowInjectable); const splashWindow = di.inject(splashWindowInjectable); - const shouldStartHidden = di.inject(shouldStartHiddenInjectable); const openDeepLink = di.inject(openDeepLinkInjectable); const commandLineArguments = di.inject(commandLineArgumentsInjectable); @@ -38,7 +36,7 @@ const startMainApplicationInjectable = getInjectable({ const onLoadOfApplication = runMany(onLoadOfApplicationInjectionToken); const afterApplicationIsLoaded = runMany(afterApplicationIsLoadedInjectionToken); - return () => { + return (shouldStartWindow: boolean) => { // Stuff happening before application is ready needs to be synchronous because of // https://github.com/electron/electron/issues/21370 beforeElectronIsReady(); @@ -48,18 +46,20 @@ const startMainApplicationInjectable = getInjectable({ await beforeApplicationIsLoading(); - if (!shouldStartHidden) { + if (shouldStartWindow) { await splashWindow.start(); } await onLoadOfApplication(); - if (!shouldStartHidden) { + if (shouldStartWindow) { const deepLinkUrl = getDeepLinkUrl(commandLineArguments); if (deepLinkUrl) { await openDeepLink(deepLinkUrl); } else { + const applicationWindow = createFirstApplicationWindow(); + await applicationWindow.start(); } diff --git a/src/renderer/components/dialog/dialog.tsx b/src/renderer/components/dialog/dialog.tsx index 1adc01dd22..a8f8c93bdc 100644 --- a/src/renderer/components/dialog/dialog.tsx +++ b/src/renderer/components/dialog/dialog.tsx @@ -14,6 +14,7 @@ import { cssNames, noop, stopPropagation } from "../../utils"; import type { ObservableHistory } from "mobx-observable-history"; import { withInjectables } from "@ogre-tools/injectable-react"; import observableHistoryInjectable from "../../navigation/observable-history.injectable"; +import requestAnimationFrameInjectable from "../animate/request-animation-frame.injectable"; // todo: refactor + handle animation-end in props.onClose()? @@ -37,6 +38,7 @@ interface DialogState { interface Dependencies { navigation: ObservableHistory; + requestAnimationFrame: (callback: () => void) => void; } @observer @@ -95,7 +97,7 @@ class NonInjectedDialog extends React.PureComponent((props) => ({ ...props, navigation: di.inject(observableHistoryInjectable), + requestAnimationFrame: di.inject(requestAnimationFrameInjectable), }), }); diff --git a/src/renderer/stores-apis-can-be-created.injectable.ts b/src/renderer/stores-apis-can-be-created.injectable.ts index b2e99767b1..87e3bf323a 100644 --- a/src/renderer/stores-apis-can-be-created.injectable.ts +++ b/src/renderer/stores-apis-can-be-created.injectable.ts @@ -4,11 +4,17 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { storesAndApisCanBeCreatedInjectionToken } from "../common/k8s-api/stores-apis-can-be-created.token"; -import { getClusterIdFromHost } from "./utils"; +import hostedClusterIdInjectable from "./cluster-frame-context/hosted-cluster-id.injectable"; const storesAndApisCanBeCreatedInjectable = getInjectable({ id: "create-stores-and-apis", - instantiate: () => Boolean(getClusterIdFromHost(location.host)), + + instantiate: (di) => { + const hostedClusterId = di.inject(hostedClusterIdInjectable); + + return !!hostedClusterId; + }, + injectionToken: storesAndApisCanBeCreatedInjectionToken, });