mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Extract responsibilities of WindowManager as injectables
Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
5842db2cc3
commit
5ac9b2aa87
14
src/common/cluster-frames.injectable.ts
Normal file
14
src/common/cluster-frames.injectable.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* 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 { clusterFrameMap } from "./cluster-frames";
|
||||||
|
|
||||||
|
const clusterFramesInjectable = getInjectable({
|
||||||
|
id: "cluster-frames",
|
||||||
|
instantiate: () => clusterFrameMap,
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default clusterFramesInjectable;
|
||||||
@ -3,13 +3,13 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import type { DiContainer } from "@ogre-tools/injectable";
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
import { beforeApplicationIsReadyInjectionToken } from "../../main/start-main-application/before-application-is-ready/before-application-is-ready-injection-token";
|
import { beforeElectronIsReadyInjectionToken } from "../../main/start-main-application/before-electron-is-ready/before-electron-is-ready-injection-token";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../../main/start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
import { afterApplicationIsReadyInjectionToken } from "../../main/start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
||||||
|
|
||||||
export const runSetups = async (di: DiContainer) => {
|
export const runSetups = async (di: DiContainer) => {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
di
|
di
|
||||||
.injectMany(beforeApplicationIsReadyInjectionToken)
|
.injectMany(beforeElectronIsReadyInjectionToken)
|
||||||
.map((setupable) => setupable.run()),
|
.map((setupable) => setupable.run()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -10,8 +10,8 @@ import type { MenuRegistration } from "../main/menu/menu-registration";
|
|||||||
import type { TrayMenuRegistration } from "../main/tray/tray-menu-registration";
|
import type { TrayMenuRegistration } from "../main/tray/tray-menu-registration";
|
||||||
import type { ShellEnvModifier } from "../main/shell-session/shell-env-modifier/shell-env-modifier-registration";
|
import type { ShellEnvModifier } from "../main/shell-session/shell-env-modifier/shell-env-modifier-registration";
|
||||||
import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
import windowManagerInjectable from "../main/window-manager.injectable";
|
|
||||||
import catalogEntityRegistryInjectable from "../main/catalog/catalog-entity-registry.injectable";
|
import catalogEntityRegistryInjectable from "../main/catalog/catalog-entity-registry.injectable";
|
||||||
|
import navigateForExtensionInjectable from "../main/start-main-application/lens-window/navigate-for-extension.injectable";
|
||||||
|
|
||||||
export class LensMainExtension extends LensExtension {
|
export class LensMainExtension extends LensExtension {
|
||||||
appMenus: MenuRegistration[] = [];
|
appMenus: MenuRegistration[] = [];
|
||||||
@ -35,9 +35,9 @@ export class LensMainExtension extends LensExtension {
|
|||||||
async navigate(pageId?: string, params?: Record<string, any>, frameId?: number) {
|
async navigate(pageId?: string, params?: Record<string, any>, frameId?: number) {
|
||||||
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main);
|
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main);
|
||||||
|
|
||||||
const windowManager = di.inject(windowManagerInjectable);
|
const navigate = di.inject(navigateForExtensionInjectable);
|
||||||
|
|
||||||
return windowManager.navigateExtension(this.id, pageId, params, frameId);
|
return navigate(this.id, pageId, params, frameId);
|
||||||
}
|
}
|
||||||
|
|
||||||
addCatalogSource(id: string, source: IObservableArray<CatalogEntity>) {
|
addCatalogSource(id: string, source: IObservableArray<CatalogEntity>) {
|
||||||
|
|||||||
@ -8,12 +8,12 @@ import {
|
|||||||
getEnvironmentSpecificLegacyGlobalDiForExtensionApi,
|
getEnvironmentSpecificLegacyGlobalDiForExtensionApi,
|
||||||
} from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
} from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
|
|
||||||
import windowManagerInjectable from "../../main/window-manager.injectable";
|
import navigateInjectable from "../../main/start-main-application/lens-window/navigate.injectable";
|
||||||
|
|
||||||
export function navigate(url: string) {
|
export function navigate(url: string) {
|
||||||
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main);
|
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main);
|
||||||
|
|
||||||
const windowManager = di.inject(windowManagerInjectable);
|
const navigate = di.inject(navigateInjectable);
|
||||||
|
|
||||||
return windowManager.navigate(url);
|
return navigate(url);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,8 +16,8 @@ import { appPathsIpcChannel } from "../../common/app-paths/app-path-injection-to
|
|||||||
import registerChannelInjectable from "./register-channel/register-channel.injectable";
|
import registerChannelInjectable from "./register-channel/register-channel.injectable";
|
||||||
import joinPathsInjectable from "../../common/path/join-paths.injectable";
|
import joinPathsInjectable from "../../common/path/join-paths.injectable";
|
||||||
import {
|
import {
|
||||||
beforeApplicationIsReadyInjectionToken,
|
beforeElectronIsReadyInjectionToken,
|
||||||
} from "../start-main-application/before-application-is-ready/before-application-is-ready-injection-token";
|
} from "../start-main-application/before-electron-is-ready/before-electron-is-ready-injection-token";
|
||||||
|
|
||||||
const setupAppPathsInjectable = getInjectable({
|
const setupAppPathsInjectable = getInjectable({
|
||||||
id: "setup-app-paths",
|
id: "setup-app-paths",
|
||||||
@ -54,7 +54,7 @@ const setupAppPathsInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: beforeApplicationIsReadyInjectionToken,
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupAppPathsInjectable;
|
export default setupAppPathsInjectable;
|
||||||
|
|||||||
@ -6,12 +6,11 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import electronAppInjectable from "../electron-app.injectable";
|
import electronAppInjectable from "../electron-app.injectable";
|
||||||
import openDeepLinkInjectable from "../../protocol-handler/lens-protocol-router-main/open-deep-link-for-url/open-deep-link.injectable";
|
import openDeepLinkInjectable from "../../protocol-handler/lens-protocol-router-main/open-deep-link-for-url/open-deep-link.injectable";
|
||||||
import loggerInjectable from "../../../common/logger.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../../start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
|
||||||
import commandLineArgumentsInjectable from "../../utils/command-line-arguments.injectable";
|
import commandLineArgumentsInjectable from "../../utils/command-line-arguments.injectable";
|
||||||
import { pipeline } from "@ogre-tools/fp";
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
import { find, startsWith, toLower, map } from "lodash/fp";
|
import { find, startsWith, toLower, map } from "lodash/fp";
|
||||||
import ensureMainWindowInjectable from "../../ensure-main-window/ensure-main-window.injectable";
|
import { whenApplicationIsLoadingInjectionToken } from "../../start-main-application/when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
import enforceSingleApplicationInstanceInjectable from "./enforce-single-application-instance.injectable";
|
import applicationWindowInjectable from "../../start-main-application/lens-window/application-window/application-window.injectable";
|
||||||
|
|
||||||
const setupDeepLinkingInjectable = getInjectable({
|
const setupDeepLinkingInjectable = getInjectable({
|
||||||
id: "setup-deep-linking",
|
id: "setup-deep-linking",
|
||||||
@ -20,18 +19,14 @@ const setupDeepLinkingInjectable = getInjectable({
|
|||||||
const app = di.inject(electronAppInjectable);
|
const app = di.inject(electronAppInjectable);
|
||||||
const logger = di.inject(loggerInjectable);
|
const logger = di.inject(loggerInjectable);
|
||||||
const openDeepLinkForUrl = di.inject(openDeepLinkInjectable);
|
const openDeepLinkForUrl = di.inject(openDeepLinkInjectable);
|
||||||
|
const applicationWindow = di.inject(applicationWindowInjectable);
|
||||||
|
|
||||||
const firstInstanceCommandLineArguments = di.inject(
|
const firstInstanceCommandLineArguments = di.inject(
|
||||||
commandLineArgumentsInjectable,
|
commandLineArgumentsInjectable,
|
||||||
);
|
);
|
||||||
|
|
||||||
const ensureMainWindow = di.inject(ensureMainWindowInjectable);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
runAfter: di.inject(enforceSingleApplicationInstanceInjectable),
|
|
||||||
|
|
||||||
run: async () => {
|
run: async () => {
|
||||||
{
|
|
||||||
logger.info(`📟 Setting protocol client for lens://`);
|
logger.info(`📟 Setting protocol client for lens://`);
|
||||||
|
|
||||||
if (app.setAsDefaultProtocolClient("lens")) {
|
if (app.setAsDefaultProtocolClient("lens")) {
|
||||||
@ -40,6 +35,12 @@ const setupDeepLinkingInjectable = getInjectable({
|
|||||||
logger.info("📟 Protocol client register failed ❗");
|
logger.info("📟 Protocol client register failed ❗");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const url = getDeepLinkUrl(firstInstanceCommandLineArguments);
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
await openDeepLinkForUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
app.on("open-url", async (event, url) => {
|
app.on("open-url", async (event, url) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
@ -52,25 +53,18 @@ const setupDeepLinkingInjectable = getInjectable({
|
|||||||
async (_, secondInstanceCommandLineArguments) => {
|
async (_, secondInstanceCommandLineArguments) => {
|
||||||
const url = getDeepLinkUrl(secondInstanceCommandLineArguments);
|
const url = getDeepLinkUrl(secondInstanceCommandLineArguments);
|
||||||
|
|
||||||
await ensureMainWindow();
|
await applicationWindow.show();
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
await openDeepLinkForUrl(url);
|
await openDeepLinkForUrl(url);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const url = getDeepLinkUrl(firstInstanceCommandLineArguments);
|
|
||||||
|
|
||||||
if (url) {
|
|
||||||
await openDeepLinkForUrl(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupDeepLinkingInjectable;
|
export default setupDeepLinkingInjectable;
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../../start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
|
||||||
import loggerInjectable from "../../../common/logger.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../../start-main-application/when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupDeveloperToolsInDevelopmentEnvironmentInjectable = getInjectable({
|
const setupDeveloperToolsInDevelopmentEnvironmentInjectable = getInjectable({
|
||||||
id: "setup-developer-tools-in-development-environment",
|
id: "setup-developer-tools-in-development-environment",
|
||||||
@ -34,7 +34,7 @@ const setupDeveloperToolsInDevelopmentEnvironmentInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupDeveloperToolsInDevelopmentEnvironmentInjectable;
|
export default setupDeveloperToolsInDevelopmentEnvironmentInjectable;
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../../start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
|
||||||
import powerMonitorInjectable from "../features/power-monitor.injectable";
|
import powerMonitorInjectable from "../features/power-monitor.injectable";
|
||||||
import exitAppInjectable from "../features/exit-app.injectable";
|
import exitAppInjectable from "../features/exit-app.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../../start-main-application/when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupDeviceShutdownInjectable = getInjectable({
|
const setupDeviceShutdownInjectable = getInjectable({
|
||||||
id: "setup-device-shutdown",
|
id: "setup-device-shutdown",
|
||||||
@ -23,7 +23,7 @@ const setupDeviceShutdownInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupDeviceShutdownInjectable;
|
export default setupDeviceShutdownInjectable;
|
||||||
|
|||||||
@ -9,9 +9,9 @@ import loggerInjectable from "../../../../common/logger.injectable";
|
|||||||
import clusterManagerInjectable from "../../../cluster-manager.injectable";
|
import clusterManagerInjectable from "../../../cluster-manager.injectable";
|
||||||
import applicationMenuItemsInjectable from "../../../menu/application-menu-items.injectable";
|
import applicationMenuItemsInjectable from "../../../menu/application-menu-items.injectable";
|
||||||
import getAbsolutePathInjectable from "../../../../common/path/get-absolute-path.injectable";
|
import getAbsolutePathInjectable from "../../../../common/path/get-absolute-path.injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../../../start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
|
||||||
import catalogEntityRegistryInjectable from "../../../catalog/catalog-entity-registry.injectable";
|
import catalogEntityRegistryInjectable from "../../../catalog/catalog-entity-registry.injectable";
|
||||||
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
|
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../../../start-main-application/when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupIpcMainHandlersInjectable = getInjectable({
|
const setupIpcMainHandlersInjectable = getInjectable({
|
||||||
id: "setup-ipc-main-handlers",
|
id: "setup-ipc-main-handlers",
|
||||||
@ -45,7 +45,7 @@ const setupIpcMainHandlersInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupIpcMainHandlersInjectable;
|
export default setupIpcMainHandlersInjectable;
|
||||||
|
|||||||
@ -4,16 +4,16 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import electronAppInjectable from "../electron-app.injectable";
|
import electronAppInjectable from "../electron-app.injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../../start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
|
||||||
import ensureMainWindowInjectable from "../../ensure-main-window/ensure-main-window.injectable";
|
|
||||||
import loggerInjectable from "../../../common/logger.injectable";
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../../start-main-application/when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
|
import applicationWindowInjectable from "../../start-main-application/lens-window/application-window/application-window.injectable";
|
||||||
|
|
||||||
const setupMainWindowVisibilityAfterActivationInjectable = getInjectable({
|
const setupMainWindowVisibilityAfterActivationInjectable = getInjectable({
|
||||||
id: "setup-main-window-visibility-after-activation",
|
id: "setup-main-window-visibility-after-activation",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const app = di.inject(electronAppInjectable);
|
const app = di.inject(electronAppInjectable);
|
||||||
const ensureMainWindow = di.inject(ensureMainWindowInjectable);
|
const applicationWindow = di.inject(applicationWindowInjectable);
|
||||||
const logger = di.inject(loggerInjectable);
|
const logger = di.inject(loggerInjectable);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -22,14 +22,14 @@ const setupMainWindowVisibilityAfterActivationInjectable = getInjectable({
|
|||||||
logger.info("APP:ACTIVATE", { hasVisibleWindows: windowIsVisible });
|
logger.info("APP:ACTIVATE", { hasVisibleWindows: windowIsVisible });
|
||||||
|
|
||||||
if (!windowIsVisible) {
|
if (!windowIsVisible) {
|
||||||
await ensureMainWindow(false);
|
await applicationWindow.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupMainWindowVisibilityAfterActivationInjectable;
|
export default setupMainWindowVisibilityAfterActivationInjectable;
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { broadcastNativeThemeOnUpdate } from "../../native-theme";
|
import { broadcastNativeThemeOnUpdate } from "../../native-theme";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../../start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
import { whenApplicationIsLoadingInjectionToken } from "../../start-main-application/when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupOsThemeUpdatesInjectable = getInjectable({
|
const setupOsThemeUpdatesInjectable = getInjectable({
|
||||||
id: "setup-os-theme-updates",
|
id: "setup-os-theme-updates",
|
||||||
@ -18,7 +18,7 @@ const setupOsThemeUpdatesInjectable = getInjectable({
|
|||||||
// Todo: remove explicit usage of IPC to get rid of this.
|
// Todo: remove explicit usage of IPC to get rid of this.
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupOsThemeUpdatesInjectable;
|
export default setupOsThemeUpdatesInjectable;
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { beforeApplicationIsReadyInjectionToken } from "../../start-main-application/before-application-is-ready/before-application-is-ready-injection-token";
|
import { beforeElectronIsReadyInjectionToken } from "../../start-main-application/before-electron-is-ready/before-electron-is-ready-injection-token";
|
||||||
import requestSingleInstanceLockInjectable from "../features/request-single-instance-lock.injectable";
|
import requestSingleInstanceLockInjectable from "../features/request-single-instance-lock.injectable";
|
||||||
import exitAppInjectable from "../features/exit-app.injectable";
|
import exitAppInjectable from "../features/exit-app.injectable";
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ const enforceSingleApplicationInstanceInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: beforeApplicationIsReadyInjectionToken,
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default enforceSingleApplicationInstanceInjectable;
|
export default enforceSingleApplicationInstanceInjectable;
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import appNameInjectable from "../../app-paths/app-name/app-name.injectable";
|
import appNameInjectable from "../../app-paths/app-name/app-name.injectable";
|
||||||
import { beforeApplicationIsReadyInjectionToken } from "../../start-main-application/before-application-is-ready/before-application-is-ready-injection-token";
|
import { beforeElectronIsReadyInjectionToken } from "../../start-main-application/before-electron-is-ready/before-electron-is-ready-injection-token";
|
||||||
import electronAppInjectable from "../electron-app.injectable";
|
import electronAppInjectable from "../electron-app.injectable";
|
||||||
|
|
||||||
const setupApplicationNameInjectable = getInjectable({
|
const setupApplicationNameInjectable = getInjectable({
|
||||||
@ -21,7 +21,7 @@ const setupApplicationNameInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: beforeApplicationIsReadyInjectionToken,
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupApplicationNameInjectable;
|
export default setupApplicationNameInjectable;
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { beforeApplicationIsReadyInjectionToken } from "../../start-main-application/before-application-is-ready/before-application-is-ready-injection-token";
|
import { beforeElectronIsReadyInjectionToken } from "../../start-main-application/before-electron-is-ready/before-electron-is-ready-injection-token";
|
||||||
import { beforeQuitOfFrontEndInjectionToken } from "../../start-main-application/before-quit-of-front-end/before-quit-of-front-end-injection-token";
|
import { beforeQuitOfFrontEndInjectionToken } from "../../start-main-application/before-quit-of-front-end/before-quit-of-front-end-injection-token";
|
||||||
import { beforeQuitOfBackEndInjectionToken } from "../../start-main-application/before-quit-of-back-end/before-quit-of-back-end-injection-token";
|
import { beforeQuitOfBackEndInjectionToken } from "../../start-main-application/before-quit-of-back-end/before-quit-of-back-end-injection-token";
|
||||||
import electronAppInjectable from "../electron-app.injectable";
|
import electronAppInjectable from "../electron-app.injectable";
|
||||||
@ -54,7 +54,7 @@ const setupRunnablesBeforeClosingOfApplicationInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: beforeApplicationIsReadyInjectionToken,
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupRunnablesBeforeClosingOfApplicationInjectable;
|
export default setupRunnablesBeforeClosingOfApplicationInjectable;
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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 electronDialogInjectable from "./electron-dialog.injectable";
|
||||||
|
|
||||||
|
export type ShowMessagePopup = (title: string, message: string, detail: string) => void;
|
||||||
|
|
||||||
|
const showMessagePopupInjectable = getInjectable({
|
||||||
|
id: "show-message-popup",
|
||||||
|
|
||||||
|
instantiate: (di): ShowMessagePopup => {
|
||||||
|
const dialog = di.inject(electronDialogInjectable);
|
||||||
|
|
||||||
|
return async (title, message, detail) => {
|
||||||
|
await dialog.showMessageBox({
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
detail,
|
||||||
|
type: "info",
|
||||||
|
buttons: ["Close"],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default showMessagePopupInjectable;
|
||||||
@ -1,20 +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 windowManagerInjectable from "../window-manager.injectable";
|
|
||||||
|
|
||||||
const ensureMainWindowInjectable = getInjectable({
|
|
||||||
id: "ensure-main-window",
|
|
||||||
|
|
||||||
instantiate: (di) => {
|
|
||||||
const windowManager = di.inject(windowManagerInjectable);
|
|
||||||
|
|
||||||
return async (showSplash = true) => {
|
|
||||||
await windowManager.ensureMainWindow(showSplash);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default ensureMainWindowInjectable;
|
|
||||||
@ -38,25 +38,24 @@ import appEventBusInjectable from "../common/app-event-bus/app-event-bus.injecta
|
|||||||
import { EventEmitter } from "../common/event-emitter";
|
import { EventEmitter } from "../common/event-emitter";
|
||||||
import type { AppEvent } from "../common/app-event-bus/event-bus";
|
import type { AppEvent } from "../common/app-event-bus/event-bus";
|
||||||
import commandLineArgumentsInjectable from "./utils/command-line-arguments.injectable";
|
import commandLineArgumentsInjectable from "./utils/command-line-arguments.injectable";
|
||||||
import initializeExtensionsInjectable from "./start-main-application/after-application-is-ready/implementations/initialize-extensions.injectable";
|
import initializeExtensionsInjectable from "./start-main-application/when-application-is-loading/implementations/initialize-extensions.injectable";
|
||||||
import lensResourcesDirInjectable from "../common/vars/lens-resources-dir.injectable";
|
import lensResourcesDirInjectable from "../common/vars/lens-resources-dir.injectable";
|
||||||
import registerFileProtocolInjectable from "./electron-app/features/register-file-protocol.injectable";
|
import registerFileProtocolInjectable from "./electron-app/features/register-file-protocol.injectable";
|
||||||
import environmentVariablesInjectable from "../common/utils/environment-variables.injectable";
|
import environmentVariablesInjectable from "../common/utils/environment-variables.injectable";
|
||||||
import { CatalogCategoryRegistry } from "../common/catalog";
|
import { CatalogCategoryRegistry } from "../common/catalog";
|
||||||
import catalogCategoryRegistryInjectable from "../common/catalog/catalog-category-registry.injectable";
|
import catalogCategoryRegistryInjectable from "../common/catalog/catalog-category-registry.injectable";
|
||||||
import setupIpcMainHandlersInjectable from "./electron-app/after-application-is-ready/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable";
|
import setupIpcMainHandlersInjectable from "./electron-app/after-application-is-ready/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable";
|
||||||
import setupLensProxyInjectable from "./start-main-application/after-application-is-ready/implementations/setup-lens-proxy.injectable";
|
import setupLensProxyInjectable from "./start-main-application/before-application-is-loading/implementations/setup-lens-proxy.injectable";
|
||||||
import setupRunnablesForAfterRootFrameIsReadyInjectable from "./start-main-application/after-application-is-ready/implementations/setup-runnables-for-after-root-frame-is-ready.injectable";
|
import setupRunnablesForAfterRootFrameIsReadyInjectable from "./start-main-application/when-application-is-loading/implementations/setup-runnables-for-after-root-frame-is-ready.injectable";
|
||||||
import setupOsThemeUpdatesInjectable from "./electron-app/after-application-is-ready/setup-os-theme-updates.injectable";
|
import setupOsThemeUpdatesInjectable from "./electron-app/after-application-is-ready/setup-os-theme-updates.injectable";
|
||||||
import setupSentryInjectable from "./start-main-application/after-application-is-ready/implementations/setup-sentry.injectable";
|
import setupSentryInjectable from "./start-main-application/when-application-is-loading/implementations/setup-sentry.injectable";
|
||||||
import setupShellInjectable from "./start-main-application/after-application-is-ready/implementations/setup-shell.injectable";
|
import setupShellInjectable from "./start-main-application/when-application-is-loading/implementations/setup-shell.injectable";
|
||||||
import setupSyncingOfWeblinksInjectable from "./start-main-application/after-application-is-ready/implementations/setup-syncing-of-weblinks.injectable";
|
import setupSyncingOfWeblinksInjectable from "./start-main-application/when-application-is-loading/implementations/setup-syncing-of-weblinks.injectable";
|
||||||
import stopServicesAndExitAppInjectable from "./stop-services-and-exit-app.injectable";
|
import stopServicesAndExitAppInjectable from "./stop-services-and-exit-app.injectable";
|
||||||
import trayInjectable from "./tray/tray.injectable";
|
import trayInjectable from "./tray/tray.injectable";
|
||||||
import applicationMenuInjectable from "./menu/application-menu.injectable";
|
import applicationMenuInjectable from "./menu/application-menu.injectable";
|
||||||
import windowManagerInjectable from "./window-manager.injectable";
|
|
||||||
import isDevelopmentInjectable from "../common/vars/is-development.injectable";
|
import isDevelopmentInjectable from "../common/vars/is-development.injectable";
|
||||||
import setupSystemCaInjectable from "./start-main-application/after-application-is-ready/implementations/setup-system-ca.injectable";
|
import setupSystemCaInjectable from "./start-main-application/before-application-is-loading/implementations/setup-system-ca.injectable";
|
||||||
import setupDeepLinkingInjectable from "./electron-app/after-application-is-ready/setup-deep-linking.injectable";
|
import setupDeepLinkingInjectable from "./electron-app/after-application-is-ready/setup-deep-linking.injectable";
|
||||||
import exitAppInjectable from "./electron-app/features/exit-app.injectable";
|
import exitAppInjectable from "./electron-app/features/exit-app.injectable";
|
||||||
import getCommandLineSwitchInjectable from "./electron-app/features/get-command-line-switch.injectable";
|
import getCommandLineSwitchInjectable from "./electron-app/features/get-command-line-switch.injectable";
|
||||||
@ -69,6 +68,12 @@ import setupMainWindowVisibilityAfterActivationInjectable from "./electron-app/a
|
|||||||
import setupDeviceShutdownInjectable from "./electron-app/after-application-is-ready/setup-device-shutdown.injectable";
|
import setupDeviceShutdownInjectable from "./electron-app/after-application-is-ready/setup-device-shutdown.injectable";
|
||||||
import setupApplicationNameInjectable from "./electron-app/before-application-is-ready/setup-application-name.injectable";
|
import setupApplicationNameInjectable from "./electron-app/before-application-is-ready/setup-application-name.injectable";
|
||||||
import setupRunnablesBeforeClosingOfApplicationInjectable from "./electron-app/before-application-is-ready/setup-runnables-before-closing-of-application.injectable";
|
import setupRunnablesBeforeClosingOfApplicationInjectable from "./electron-app/before-application-is-ready/setup-runnables-before-closing-of-application.injectable";
|
||||||
|
import showMessagePopupInjectable from "./electron-app/features/show-message-popup.injectable";
|
||||||
|
import clusterFramesInjectable from "../common/cluster-frames.injectable";
|
||||||
|
import type { ClusterFrameInfo } from "../common/cluster-frames";
|
||||||
|
import { observable } from "mobx";
|
||||||
|
import createBrowserWindowInjectable from "./start-main-application/lens-window/application-window/create-browser-window.injectable";
|
||||||
|
import type { BrowserWindow } from "electron";
|
||||||
|
|
||||||
export const getDiForUnitTesting = (
|
export const getDiForUnitTesting = (
|
||||||
{ doGeneralOverrides } = { doGeneralOverrides: false },
|
{ doGeneralOverrides } = { doGeneralOverrides: false },
|
||||||
@ -98,9 +103,10 @@ export const getDiForUnitTesting = (
|
|||||||
di.override(environmentVariablesInjectable, () => ({}));
|
di.override(environmentVariablesInjectable, () => ({}));
|
||||||
di.override(commandLineArgumentsInjectable, () => []);
|
di.override(commandLineArgumentsInjectable, () => []);
|
||||||
|
|
||||||
|
di.override(clusterFramesInjectable, () => observable.map<string, ClusterFrameInfo>());
|
||||||
|
|
||||||
di.override(stopServicesAndExitAppInjectable, () => () => {});
|
di.override(stopServicesAndExitAppInjectable, () => () => {});
|
||||||
di.override(lensResourcesDirInjectable, () => "/irrelevant");
|
di.override(lensResourcesDirInjectable, () => "/irrelevant");
|
||||||
di.override(windowManagerInjectable, () => ({ ensureMainWindow: () => Promise.resolve(null) }));
|
|
||||||
|
|
||||||
di.override(trayInjectable, () => ({ start: () => {}, stop: () => {} }));
|
di.override(trayInjectable, () => ({ start: () => {}, stop: () => {} }));
|
||||||
di.override(applicationMenuInjectable, () => ({ start: () => {}, stop: () => {} }));
|
di.override(applicationMenuInjectable, () => ({ start: () => {}, stop: () => {} }));
|
||||||
@ -204,6 +210,12 @@ const overrideElectronFeatures = (di: DiContainer) => {
|
|||||||
di.override(requestSingleInstanceLockInjectable, () => () => true);
|
di.override(requestSingleInstanceLockInjectable, () => () => true);
|
||||||
di.override(disableHardwareAccelerationInjectable, () => () => {});
|
di.override(disableHardwareAccelerationInjectable, () => () => {});
|
||||||
di.override(shouldStartHiddenInjectable, () => true);
|
di.override(shouldStartHiddenInjectable, () => true);
|
||||||
|
di.override(showMessagePopupInjectable, () => () => {});
|
||||||
|
|
||||||
|
di.override(createBrowserWindowInjectable, () => async () => ({
|
||||||
|
show: () => {},
|
||||||
|
hide: () => {},
|
||||||
|
}) as unknown as BrowserWindow);
|
||||||
|
|
||||||
di.override(
|
di.override(
|
||||||
getElectronAppPathInjectable,
|
getElectronAppPathInjectable,
|
||||||
|
|||||||
@ -7,12 +7,8 @@ import { checkForUpdates } from "../app-updater";
|
|||||||
import { docsUrl, productName, supportUrl } from "../../common/vars";
|
import { docsUrl, productName, supportUrl } from "../../common/vars";
|
||||||
import { broadcastMessage } from "../../common/ipc";
|
import { broadcastMessage } from "../../common/ipc";
|
||||||
import { openBrowser } from "../../common/utils";
|
import { openBrowser } from "../../common/utils";
|
||||||
import { showAbout } from "./menu";
|
|
||||||
import windowManagerInjectable from "../window-manager.injectable";
|
|
||||||
import type { MenuItemConstructorOptions } from "electron";
|
import type { MenuItemConstructorOptions } from "electron";
|
||||||
import {
|
import { webContents } from "electron";
|
||||||
webContents,
|
|
||||||
} from "electron";
|
|
||||||
import loggerInjectable from "../../common/logger.injectable";
|
import loggerInjectable from "../../common/logger.injectable";
|
||||||
import appNameInjectable from "../app-paths/app-name/app-name.injectable";
|
import appNameInjectable from "../app-paths/app-name/app-name.injectable";
|
||||||
import electronMenuItemsInjectable from "./electron-menu-items.injectable";
|
import electronMenuItemsInjectable from "./electron-menu-items.injectable";
|
||||||
@ -25,6 +21,9 @@ import navigateToAddClusterInjectable from "../../common/front-end-routing/route
|
|||||||
import stopServicesAndExitAppInjectable from "../stop-services-and-exit-app.injectable";
|
import stopServicesAndExitAppInjectable from "../stop-services-and-exit-app.injectable";
|
||||||
import isMacInjectable from "../../common/vars/is-mac.injectable";
|
import isMacInjectable from "../../common/vars/is-mac.injectable";
|
||||||
import { computed } from "mobx";
|
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";
|
||||||
|
|
||||||
function ignoreIf(check: boolean, menuItems: MenuItemConstructorOptions[]) {
|
function ignoreIf(check: boolean, menuItems: MenuItemConstructorOptions[]) {
|
||||||
return check ? [] : menuItems;
|
return check ? [] : menuItems;
|
||||||
@ -43,12 +42,14 @@ const applicationMenuItemsInjectable = getInjectable({
|
|||||||
const isMac = di.inject(isMacInjectable);
|
const isMac = di.inject(isMacInjectable);
|
||||||
const isAutoUpdateEnabled = di.inject(isAutoUpdateEnabledInjectable);
|
const isAutoUpdateEnabled = di.inject(isAutoUpdateEnabledInjectable);
|
||||||
const electronMenuItems = di.inject(electronMenuItemsInjectable);
|
const electronMenuItems = di.inject(electronMenuItemsInjectable);
|
||||||
|
const showAbout = di.inject(showAboutInjectable);
|
||||||
|
const applicationWindow = di.inject(applicationWindowInjectable);
|
||||||
|
const reloadApplicationWindow = di.inject(reloadWindowInjectable, applicationWindow);
|
||||||
|
|
||||||
return computed((): MenuItemOpts[] => {
|
return computed((): MenuItemOpts[] => {
|
||||||
|
|
||||||
// TODO: These injects should happen outside of the computed.
|
// TODO: These injects should happen outside of the computed.
|
||||||
// TODO: Remove temporal dependencies in WindowManager to make sure timing is correct.
|
// TODO: Remove temporal dependencies in WindowManager to make sure timing is correct.
|
||||||
const windowManager = di.inject(windowManagerInjectable);
|
|
||||||
const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable);
|
const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable);
|
||||||
const navigateToPreferences = di.inject(navigateToPreferencesInjectable);
|
const navigateToPreferences = di.inject(navigateToPreferencesInjectable);
|
||||||
const navigateToExtensions = di.inject(navigateToExtensionsInjectable);
|
const navigateToExtensions = di.inject(navigateToExtensionsInjectable);
|
||||||
@ -75,7 +76,7 @@ const applicationMenuItemsInjectable = getInjectable({
|
|||||||
{
|
{
|
||||||
label: "Check for updates",
|
label: "Check for updates",
|
||||||
click() {
|
click() {
|
||||||
checkForUpdates().then(() => windowManager.ensureMainWindow());
|
checkForUpdates().then(() => applicationWindow.show());
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
@ -239,7 +240,7 @@ const applicationMenuItemsInjectable = getInjectable({
|
|||||||
accelerator: "CmdOrCtrl+R",
|
accelerator: "CmdOrCtrl+R",
|
||||||
id: "reload",
|
id: "reload",
|
||||||
click() {
|
click() {
|
||||||
windowManager.reload();
|
reloadApplicationWindow();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ role: "toggleDevTools" },
|
{ role: "toggleDevTools" },
|
||||||
@ -293,7 +294,7 @@ const applicationMenuItemsInjectable = getInjectable({
|
|||||||
label: "Check for updates",
|
label: "Check for updates",
|
||||||
click() {
|
click() {
|
||||||
checkForUpdates().then(() =>
|
checkForUpdates().then(() =>
|
||||||
windowManager.ensureMainWindow(),
|
applicationWindow.show(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,14 +2,19 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { app, dialog, Menu } from "electron";
|
import { app, Menu } from "electron";
|
||||||
import { appName, isWindows, productName } from "../../common/vars";
|
import { appName, isWindows, productName } from "../../common/vars";
|
||||||
import packageJson from "../../../package.json";
|
import packageJson from "../../../package.json";
|
||||||
import type { MenuItemOpts } from "./application-menu-items.injectable";
|
import type { MenuItemOpts } from "./application-menu-items.injectable";
|
||||||
|
import type { ShowMessagePopup } from "../electron-app/features/show-message-popup.injectable";
|
||||||
|
|
||||||
export type MenuTopId = "mac" | "file" | "edit" | "view" | "help";
|
export type MenuTopId = "mac" | "file" | "edit" | "view" | "help";
|
||||||
|
|
||||||
export function showAbout() {
|
interface Dependencies {
|
||||||
|
showMessagePopup: ShowMessagePopup;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const showAbout = ({ showMessagePopup }: Dependencies) => async () => {
|
||||||
const appInfo = [
|
const appInfo = [
|
||||||
`${appName}: ${app.getVersion()}`,
|
`${appName}: ${app.getVersion()}`,
|
||||||
`Electron: ${process.versions.electron}`,
|
`Electron: ${process.versions.electron}`,
|
||||||
@ -18,14 +23,12 @@ export function showAbout() {
|
|||||||
packageJson.copyright,
|
packageJson.copyright,
|
||||||
];
|
];
|
||||||
|
|
||||||
dialog.showMessageBoxSync({
|
await showMessagePopup(
|
||||||
title: `${isWindows ? " ".repeat(2) : ""}${appName}`,
|
`${isWindows ? " ".repeat(2) : ""}${appName}`,
|
||||||
type: "info",
|
productName,
|
||||||
buttons: ["Close"],
|
appInfo.join("\r\n"),
|
||||||
message: productName,
|
);
|
||||||
detail: appInfo.join("\r\n"),
|
};
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function buildMenu(
|
export function buildMenu(
|
||||||
applicationMenuItems: MenuItemOpts[],
|
applicationMenuItems: MenuItemOpts[],
|
||||||
|
|||||||
16
src/main/menu/show-about.injectable.ts
Normal file
16
src/main/menu/show-about.injectable.ts
Normal file
@ -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 { showAbout } from "./menu";
|
||||||
|
import showMessagePopupInjectable from "../electron-app/features/show-message-popup.injectable";
|
||||||
|
|
||||||
|
const showAboutInjectable = getInjectable({
|
||||||
|
id: "show-about",
|
||||||
|
|
||||||
|
instantiate: (di) =>
|
||||||
|
showAbout({ showMessagePopup: di.inject(showMessagePopupInjectable) }),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default showAboutInjectable;
|
||||||
@ -3,8 +3,8 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
|
||||||
import applicationMenuInjectable from "./application-menu.injectable";
|
import applicationMenuInjectable from "./application-menu.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../start-main-application/when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const startApplicationMenuInjectable = getInjectable({
|
const startApplicationMenuInjectable = getInjectable({
|
||||||
id: "start-application-menu",
|
id: "start-application-menu",
|
||||||
@ -21,7 +21,7 @@ const startApplicationMenuInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default startApplicationMenuInjectable;
|
export default startApplicationMenuInjectable;
|
||||||
|
|||||||
@ -3,17 +3,17 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import windowManagerInjectable from "../window-manager.injectable";
|
|
||||||
import { navigateToUrlInjectionToken } from "../../common/front-end-routing/navigate-to-url-injection-token";
|
import { navigateToUrlInjectionToken } from "../../common/front-end-routing/navigate-to-url-injection-token";
|
||||||
|
import navigateInjectable from "../start-main-application/lens-window/navigate.injectable";
|
||||||
|
|
||||||
const navigateToUrlInjectable = getInjectable({
|
const navigateToUrlInjectable = getInjectable({
|
||||||
id: "navigate-to-url",
|
id: "navigate-to-url",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const windowManager = di.inject(windowManagerInjectable);
|
const navigate = di.inject(navigateInjectable);
|
||||||
|
|
||||||
return (url) => {
|
return (url) => {
|
||||||
windowManager.navigateSync(url);
|
navigate(url);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import extensionLoaderInjectable from "../../../extensions/extension-loader/extension-loader.injectable";
|
import extensionLoaderInjectable from "../../../extensions/extension-loader/extension-loader.injectable";
|
||||||
import { LensProtocolRouterMain } from "./lens-protocol-router-main";
|
import { LensProtocolRouterMain } from "./lens-protocol-router-main";
|
||||||
import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable";
|
import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable";
|
||||||
import windowManagerInjectable from "../../window-manager.injectable";
|
import applicationWindowInjectable from "../../start-main-application/lens-window/application-window/application-window.injectable";
|
||||||
|
|
||||||
const lensProtocolRouterMainInjectable = getInjectable({
|
const lensProtocolRouterMainInjectable = getInjectable({
|
||||||
id: "lens-protocol-router-main",
|
id: "lens-protocol-router-main",
|
||||||
@ -15,7 +15,7 @@ const lensProtocolRouterMainInjectable = getInjectable({
|
|||||||
new LensProtocolRouterMain({
|
new LensProtocolRouterMain({
|
||||||
extensionLoader: di.inject(extensionLoaderInjectable),
|
extensionLoader: di.inject(extensionLoaderInjectable),
|
||||||
extensionsStore: di.inject(extensionsStoreInjectable),
|
extensionsStore: di.inject(extensionsStoreInjectable),
|
||||||
windowManager: di.inject(windowManagerInjectable),
|
applicationWindow: di.inject(applicationWindowInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -12,9 +12,11 @@ import { observable, when, makeObservable } from "mobx";
|
|||||||
import type { RouteAttempt } from "../../../common/protocol-handler";
|
import type { RouteAttempt } from "../../../common/protocol-handler";
|
||||||
import { ProtocolHandlerInvalid } from "../../../common/protocol-handler";
|
import { ProtocolHandlerInvalid } from "../../../common/protocol-handler";
|
||||||
import { disposer, noop } from "../../../common/utils";
|
import { disposer, noop } from "../../../common/utils";
|
||||||
import type { WindowManager } from "../../window-manager";
|
|
||||||
import type { ExtensionLoader } from "../../../extensions/extension-loader";
|
import type { ExtensionLoader } from "../../../extensions/extension-loader";
|
||||||
import type { ExtensionsStore } from "../../../extensions/extensions-store/extensions-store";
|
import type { ExtensionsStore } from "../../../extensions/extensions-store/extensions-store";
|
||||||
|
import type {
|
||||||
|
LensWindow,
|
||||||
|
} from "../../start-main-application/lens-window/application-window/lens-window-injection-token";
|
||||||
|
|
||||||
export interface FallbackHandler {
|
export interface FallbackHandler {
|
||||||
(name: string): Promise<boolean>;
|
(name: string): Promise<boolean>;
|
||||||
@ -40,7 +42,7 @@ function checkHost<Query>(url: URLParse<Query>): boolean {
|
|||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
extensionLoader: ExtensionLoader;
|
extensionLoader: ExtensionLoader;
|
||||||
extensionsStore: ExtensionsStore;
|
extensionsStore: ExtensionsStore;
|
||||||
windowManager: WindowManager;
|
applicationWindow: LensWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LensProtocolRouterMain extends proto.LensProtocolRouter {
|
export class LensProtocolRouterMain extends proto.LensProtocolRouter {
|
||||||
@ -77,7 +79,7 @@ export class LensProtocolRouterMain extends proto.LensProtocolRouter {
|
|||||||
throw new proto.RoutingError(proto.RoutingErrorType.INVALID_PROTOCOL, url);
|
throw new proto.RoutingError(proto.RoutingErrorType.INVALID_PROTOCOL, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dependencies.windowManager.ensureMainWindow().catch(noop);
|
this.dependencies.applicationWindow.show().catch(noop);
|
||||||
const routeInternally = checkHost(url);
|
const routeInternally = checkHost(url);
|
||||||
|
|
||||||
logger.info(`${proto.LensProtocolRouter.LoggingPrefix}: routing ${url.toString()}`);
|
logger.info(`${proto.LensProtocolRouter.LoggingPrefix}: routing ${url.toString()}`);
|
||||||
|
|||||||
@ -9,10 +9,10 @@ const openDeepLinkInjectable = getInjectable({
|
|||||||
id: "open-deep-link",
|
id: "open-deep-link",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const protocolRouter = di.inject(lensProtocolRouterMainInjectable);
|
const getProtocolRouter = () => di.inject(lensProtocolRouterMainInjectable);
|
||||||
|
|
||||||
return async (url: string) => {
|
return async (url: string) => {
|
||||||
await protocolRouter.route(url);
|
await getProtocolRouter().route(url);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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 { Runnable } from "../run-many-for";
|
||||||
|
|
||||||
|
export const afterApplicationIsLoadedInjectionToken = getInjectionToken<Runnable>({
|
||||||
|
id: "after-application-is-loaded",
|
||||||
|
});
|
||||||
@ -3,8 +3,8 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
||||||
|
import { afterApplicationIsLoadedInjectionToken } from "../after-application-is-loaded-injection-token";
|
||||||
|
|
||||||
const emitServiceStartToCommandBusInjectable = getInjectable({
|
const emitServiceStartToCommandBusInjectable = getInjectable({
|
||||||
id: "emit-service-start-to-command-bus",
|
id: "emit-service-start-to-command-bus",
|
||||||
@ -19,7 +19,7 @@ const emitServiceStartToCommandBusInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: afterApplicationIsLoadedInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default emitServiceStartToCommandBusInjectable;
|
export default emitServiceStartToCommandBusInjectable;
|
||||||
@ -1,36 +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 windowManagerInjectable from "../../../window-manager.injectable";
|
|
||||||
import loggerInjectable from "../../../../common/logger.injectable";
|
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import shouldStartHiddenInjectable from "../../../electron-app/features/should-start-hidden.injectable";
|
|
||||||
import setupLensProxyInjectable from "./setup-lens-proxy.injectable";
|
|
||||||
|
|
||||||
const startMainWindowInjectable = getInjectable({
|
|
||||||
id: "start-main-window",
|
|
||||||
|
|
||||||
instantiate: (di) => {
|
|
||||||
const windowManager = di.inject(windowManagerInjectable);
|
|
||||||
const logger = di.inject(loggerInjectable);
|
|
||||||
const shouldStartHidden = di.inject(shouldStartHiddenInjectable);
|
|
||||||
|
|
||||||
return {
|
|
||||||
runAfter: di.inject(setupLensProxyInjectable),
|
|
||||||
|
|
||||||
run: async () => {
|
|
||||||
logger.info("🖥️ Starting WindowManager");
|
|
||||||
|
|
||||||
if (!shouldStartHidden) {
|
|
||||||
await windowManager.ensureMainWindow();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default startMainWindowInjectable;
|
|
||||||
@ -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 { Runnable } from "../run-many-for";
|
||||||
|
|
||||||
|
export const beforeApplicationIsLoadingInjectionToken = getInjectionToken<Runnable>({
|
||||||
|
id: "before-application-is-loading",
|
||||||
|
});
|
||||||
@ -3,9 +3,9 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import registerFileProtocolInjectable from "../../../electron-app/features/register-file-protocol.injectable";
|
import registerFileProtocolInjectable from "../../../electron-app/features/register-file-protocol.injectable";
|
||||||
import staticFilesDirectoryInjectable from "../../../../common/vars/static-files-directory.injectable";
|
import staticFilesDirectoryInjectable from "../../../../common/vars/static-files-directory.injectable";
|
||||||
|
import { beforeApplicationIsLoadingInjectionToken } from "../before-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupFileProtocolInjectable = getInjectable({
|
const setupFileProtocolInjectable = getInjectable({
|
||||||
id: "setup-file-protocol",
|
id: "setup-file-protocol",
|
||||||
@ -21,7 +21,7 @@ const setupFileProtocolInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: beforeApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupFileProtocolInjectable;
|
export default setupFileProtocolInjectable;
|
||||||
@ -3,7 +3,6 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import {
|
import {
|
||||||
getAppVersion,
|
getAppVersion,
|
||||||
getAppVersionFromProxyServer,
|
getAppVersionFromProxyServer,
|
||||||
@ -14,6 +13,7 @@ import loggerInjectable from "../../../../common/logger.injectable";
|
|||||||
import lensProxyPortNumberStateInjectable from "../../../lens-proxy-port-number-state.injectable";
|
import lensProxyPortNumberStateInjectable from "../../../lens-proxy-port-number-state.injectable";
|
||||||
import isWindowsInjectable from "../../../../common/vars/is-windows.injectable";
|
import isWindowsInjectable from "../../../../common/vars/is-windows.injectable";
|
||||||
import showErrorPopupInjectable from "../../../electron-app/features/show-error-popup.injectable";
|
import showErrorPopupInjectable from "../../../electron-app/features/show-error-popup.injectable";
|
||||||
|
import { beforeApplicationIsLoadingInjectionToken } from "../before-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupLensProxyInjectable = getInjectable({
|
const setupLensProxyInjectable = getInjectable({
|
||||||
id: "setup-lens-proxy",
|
id: "setup-lens-proxy",
|
||||||
@ -74,7 +74,7 @@ const setupLensProxyInjectable = getInjectable({
|
|||||||
|
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: beforeApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupLensProxyInjectable;
|
export default setupLensProxyInjectable;
|
||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import { injectSystemCAs } from "../../../../common/system-ca";
|
import { injectSystemCAs } from "../../../../common/system-ca";
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
import { beforeApplicationIsLoadingInjectionToken } from "../before-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupSystemCaInjectable = getInjectable({
|
const setupSystemCaInjectable = getInjectable({
|
||||||
id: "setup-system-ca",
|
id: "setup-system-ca",
|
||||||
@ -17,7 +17,7 @@ const setupSystemCaInjectable = getInjectable({
|
|||||||
|
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: beforeApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupSystemCaInjectable;
|
export default setupSystemCaInjectable;
|
||||||
@ -5,7 +5,7 @@
|
|||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { RunnableSync } from "../run-many-sync-for";
|
import type { RunnableSync } from "../run-many-sync-for";
|
||||||
|
|
||||||
export const beforeApplicationIsReadyInjectionToken =
|
export const beforeElectronIsReadyInjectionToken =
|
||||||
getInjectionToken<RunnableSync>({
|
getInjectionToken<RunnableSync>({
|
||||||
id: "before-application-is-ready",
|
id: "before-electron-is-ready",
|
||||||
});
|
});
|
||||||
@ -5,7 +5,7 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import environmentVariablesInjectable from "../../../../common/utils/environment-variables.injectable";
|
import environmentVariablesInjectable from "../../../../common/utils/environment-variables.injectable";
|
||||||
import disableHardwareAccelerationInjectable from "../../../electron-app/features/disable-hardware-acceleration.injectable";
|
import disableHardwareAccelerationInjectable from "../../../electron-app/features/disable-hardware-acceleration.injectable";
|
||||||
import { beforeApplicationIsReadyInjectionToken } from "../before-application-is-ready-injection-token";
|
import { beforeElectronIsReadyInjectionToken } from "../before-electron-is-ready-injection-token";
|
||||||
|
|
||||||
const setupHardwareAccelerationInjectable = getInjectable({
|
const setupHardwareAccelerationInjectable = getInjectable({
|
||||||
id: "setup-hardware-acceleration",
|
id: "setup-hardware-acceleration",
|
||||||
@ -23,7 +23,7 @@ const setupHardwareAccelerationInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: beforeApplicationIsReadyInjectionToken,
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupHardwareAccelerationInjectable;
|
export default setupHardwareAccelerationInjectable;
|
||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import * as Immer from "immer";
|
import * as Immer from "immer";
|
||||||
import { beforeApplicationIsReadyInjectionToken } from "../before-application-is-ready-injection-token";
|
import { beforeElectronIsReadyInjectionToken } from "../before-electron-is-ready-injection-token";
|
||||||
|
|
||||||
const setupImmerInjectable = getInjectable({
|
const setupImmerInjectable = getInjectable({
|
||||||
id: "setup-immer",
|
id: "setup-immer",
|
||||||
@ -18,7 +18,7 @@ const setupImmerInjectable = getInjectable({
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
injectionToken: beforeApplicationIsReadyInjectionToken,
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupImmerInjectable;
|
export default setupImmerInjectable;
|
||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import * as Mobx from "mobx";
|
import * as Mobx from "mobx";
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { beforeApplicationIsReadyInjectionToken } from "../before-application-is-ready-injection-token";
|
import { beforeElectronIsReadyInjectionToken } from "../before-electron-is-ready-injection-token";
|
||||||
|
|
||||||
const setupMobxInjectable = getInjectable({
|
const setupMobxInjectable = getInjectable({
|
||||||
id: "setup-mobx",
|
id: "setup-mobx",
|
||||||
@ -23,7 +23,7 @@ const setupMobxInjectable = getInjectable({
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
injectionToken: beforeApplicationIsReadyInjectionToken,
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupMobxInjectable;
|
export default setupMobxInjectable;
|
||||||
@ -3,7 +3,7 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { beforeApplicationIsReadyInjectionToken } from "../before-application-is-ready-injection-token";
|
import { beforeElectronIsReadyInjectionToken } from "../before-electron-is-ready-injection-token";
|
||||||
import getCommandLineSwitchInjectable from "../../../electron-app/features/get-command-line-switch.injectable";
|
import getCommandLineSwitchInjectable from "../../../electron-app/features/get-command-line-switch.injectable";
|
||||||
|
|
||||||
const setupProxyEnvInjectable = getInjectable({
|
const setupProxyEnvInjectable = getInjectable({
|
||||||
@ -37,7 +37,7 @@ const setupProxyEnvInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: beforeApplicationIsReadyInjectionToken,
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupProxyEnvInjectable;
|
export default setupProxyEnvInjectable;
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* 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 { BrowserWindow } from "electron";
|
||||||
|
import type {
|
||||||
|
SendToViewArgs,
|
||||||
|
} from "../application-window/lens-window-injection-token";
|
||||||
|
import {
|
||||||
|
lensWindowInjectionToken,
|
||||||
|
} from "../application-window/lens-window-injection-token";
|
||||||
|
|
||||||
|
const applicationIsLoadingWindowInjectable = getInjectable({
|
||||||
|
id: "application-is-loading-window",
|
||||||
|
|
||||||
|
instantiate: () => {
|
||||||
|
let loadingWindow: BrowserWindow;
|
||||||
|
|
||||||
|
const hideWindow = () => {
|
||||||
|
loadingWindow?.hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
show: async () => {
|
||||||
|
if (!loadingWindow) {
|
||||||
|
loadingWindow = await createLoadingWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingWindow.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: hideWindow,
|
||||||
|
|
||||||
|
close: () => {
|
||||||
|
hideWindow();
|
||||||
|
|
||||||
|
loadingWindow = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
send: async ({ channel, frameInfo, data = [] }: SendToViewArgs) => {
|
||||||
|
if (!loadingWindow) {
|
||||||
|
loadingWindow = await createLoadingWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frameInfo) {
|
||||||
|
loadingWindow.webContents.sendToFrame(
|
||||||
|
[frameInfo.processId, frameInfo.frameId],
|
||||||
|
channel,
|
||||||
|
...data,
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
loadingWindow.webContents.send(channel, ...data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: lensWindowInjectionToken,
|
||||||
|
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default applicationIsLoadingWindowInjectable;
|
||||||
|
|
||||||
|
const createLoadingWindow = async () => {
|
||||||
|
const loadingWindow = new BrowserWindow({
|
||||||
|
width: 500,
|
||||||
|
height: 300,
|
||||||
|
backgroundColor: "#1e2124",
|
||||||
|
center: true,
|
||||||
|
frame: false,
|
||||||
|
resizable: false,
|
||||||
|
show: false,
|
||||||
|
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false,
|
||||||
|
nodeIntegrationInSubFrames: true,
|
||||||
|
nativeWindowOpen: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await loadingWindow.loadURL("static://splash.html");
|
||||||
|
|
||||||
|
return loadingWindow;
|
||||||
|
};
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* 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 windowStateKeeper from "electron-window-state";
|
||||||
|
|
||||||
|
const applicationWindowStateInjectable = getInjectable({
|
||||||
|
id: "application-window-state",
|
||||||
|
|
||||||
|
instantiate: () => {
|
||||||
|
console.log("asdasd");
|
||||||
|
|
||||||
|
return windowStateKeeper({
|
||||||
|
defaultHeight: 900,
|
||||||
|
defaultWidth: 1440,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default applicationWindowStateInjectable;
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* 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 createBrowserWindowInjectable from "./create-browser-window.injectable";
|
||||||
|
import type {
|
||||||
|
SendToViewArgs } from "./lens-window-injection-token";
|
||||||
|
import {
|
||||||
|
lensWindowInjectionToken,
|
||||||
|
} from "./lens-window-injection-token";
|
||||||
|
import type { BrowserWindow } from "electron";
|
||||||
|
import sendToChannelInElectronBrowserWindowInjectable from "./send-to-channel-in-electron-browser-window.injectable";
|
||||||
|
|
||||||
|
const applicationWindowInjectable = getInjectable({
|
||||||
|
id: "application-window",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const createBrowserWindow = di.inject(createBrowserWindowInjectable);
|
||||||
|
|
||||||
|
let browserWindow: BrowserWindow = null;
|
||||||
|
|
||||||
|
const hideWindow = () => {
|
||||||
|
browserWindow?.hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
const sendToChannelInLensWindow = di.inject(
|
||||||
|
sendToChannelInElectronBrowserWindowInjectable,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
show: async () => {
|
||||||
|
if (!browserWindow) {
|
||||||
|
browserWindow = await createBrowserWindow("only-application-window");
|
||||||
|
}
|
||||||
|
|
||||||
|
browserWindow.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: hideWindow,
|
||||||
|
|
||||||
|
close: () => {
|
||||||
|
hideWindow();
|
||||||
|
|
||||||
|
browserWindow = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
send: async (args: SendToViewArgs) => {
|
||||||
|
if (!browserWindow) {
|
||||||
|
browserWindow = await createBrowserWindow("only-application-window");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendToChannelInLensWindow(browserWindow, args);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: lensWindowInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default applicationWindowInjectable;
|
||||||
@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* 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 loggerInjectable from "../../../../common/logger.injectable";
|
||||||
|
import appNameInjectable from "../../../app-paths/app-name/app-name.injectable";
|
||||||
|
import applicationWindowStateInjectable from "./application-window-state.injectable";
|
||||||
|
import lensProxyPortNumberStateInjectable from "../../../lens-proxy-port-number-state.injectable";
|
||||||
|
import isMacInjectable from "../../../../common/vars/is-mac.injectable";
|
||||||
|
import { BrowserWindow, ipcMain } from "electron";
|
||||||
|
import { delay, openBrowser } from "../../../../common/utils";
|
||||||
|
import { bundledExtensionsLoaded } from "../../../../common/ipc/extension-handling";
|
||||||
|
import electronAppInjectable from "../../../electron-app/electron-app.injectable";
|
||||||
|
import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
||||||
|
|
||||||
|
const createBrowserWindowInjectable = getInjectable({
|
||||||
|
id: "create-browser-window",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const logger = di.inject(loggerInjectable);
|
||||||
|
const applicationName = di.inject(appNameInjectable);
|
||||||
|
const isMac = di.inject(isMacInjectable);
|
||||||
|
const appEventBus = di.inject(appEventBusInjectable);
|
||||||
|
|
||||||
|
const lensProxyPortNumberState = di.inject(
|
||||||
|
lensProxyPortNumberStateInjectable,
|
||||||
|
);
|
||||||
|
|
||||||
|
return async (id: string) => {
|
||||||
|
const applicationWindowState = di.inject(applicationWindowStateInjectable);
|
||||||
|
const app = di.inject(electronAppInjectable);
|
||||||
|
|
||||||
|
const { width, height, x, y } = applicationWindowState;
|
||||||
|
|
||||||
|
const browserWindow = new BrowserWindow({
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
title: applicationName,
|
||||||
|
show: false,
|
||||||
|
minWidth: 700, // accommodate 800 x 600 display minimum
|
||||||
|
minHeight: 500, // accommodate 800 x 600 display minimum
|
||||||
|
titleBarStyle: isMac ? "hiddenInset" : "hidden",
|
||||||
|
frame: isMac,
|
||||||
|
backgroundColor: "#1e2124",
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
nodeIntegrationInSubFrames: true,
|
||||||
|
webviewTag: true,
|
||||||
|
contextIsolation: false,
|
||||||
|
nativeWindowOpen: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
applicationWindowState.manage(browserWindow);
|
||||||
|
|
||||||
|
// open external links in default browser (target=_blank, window.open)
|
||||||
|
browserWindow
|
||||||
|
.on("focus", () => {
|
||||||
|
appEventBus.emit({ name: "app", action: "focus" });
|
||||||
|
})
|
||||||
|
|
||||||
|
.on("blur", () => {
|
||||||
|
appEventBus.emit({ name: "app", action: "blur" });
|
||||||
|
})
|
||||||
|
|
||||||
|
.on("closed", () => {
|
||||||
|
// clean up
|
||||||
|
applicationWindowState.unmanage();
|
||||||
|
// this.mainWindow = null;
|
||||||
|
// this.splashWindow = null;
|
||||||
|
app.dock?.hide(); // hide icon in dock (mac-os)
|
||||||
|
})
|
||||||
|
|
||||||
|
.webContents.on("dom-ready", () => {
|
||||||
|
appEventBus.emit({ name: "app", action: "dom-ready" });
|
||||||
|
})
|
||||||
|
|
||||||
|
.on("did-fail-load", (_event, code, desc) => {
|
||||||
|
logger.error(`[WINDOW-MANAGER]: Failed to load Main window`, {
|
||||||
|
code,
|
||||||
|
desc,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.on("did-finish-load", () => {
|
||||||
|
logger.info("[WINDOW-MANAGER]: Main window loaded");
|
||||||
|
})
|
||||||
|
|
||||||
|
.on("will-attach-webview", (event, webPreferences, params) => {
|
||||||
|
logger.debug("[WINDOW-MANAGER]: Attaching webview");
|
||||||
|
// Following is security recommendations because we allow webview tag (webviewTag: true)
|
||||||
|
// suggested by https://www.electronjs.org/docs/tutorial/security#11-verify-webview-options-before-creation
|
||||||
|
// and https://www.electronjs.org/docs/tutorial/security#10-do-not-use-allowpopups
|
||||||
|
|
||||||
|
if (webPreferences.preload) {
|
||||||
|
logger.warn(
|
||||||
|
"[WINDOW-MANAGER]: Strip away preload scripts of webview",
|
||||||
|
);
|
||||||
|
delete webPreferences.preload;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-expect-error some electron version uses webPreferences.preloadURL/webPreferences.preload
|
||||||
|
if (webPreferences.preloadURL) {
|
||||||
|
logger.warn(
|
||||||
|
"[WINDOW-MANAGER]: Strip away preload scripts of webview",
|
||||||
|
);
|
||||||
|
delete webPreferences.preload;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.allowpopups) {
|
||||||
|
logger.warn(
|
||||||
|
"[WINDOW-MANAGER]: We do not allow allowpopups props, stop webview from renderer",
|
||||||
|
);
|
||||||
|
|
||||||
|
// event.preventDefault() will destroy the guest page.
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always disable Node.js integration for all webviews
|
||||||
|
webPreferences.nodeIntegration = false;
|
||||||
|
})
|
||||||
|
|
||||||
|
.setWindowOpenHandler((details) => {
|
||||||
|
openBrowser(details.url).catch((error) => {
|
||||||
|
logger.error("[WINDOW-MANAGER]: failed to open browser", { error });
|
||||||
|
});
|
||||||
|
|
||||||
|
return { action: "deny" };
|
||||||
|
});
|
||||||
|
|
||||||
|
const contentUrl = `http://localhost:${lensProxyPortNumberState.get()}`;
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
`[WINDOW-MANAGER]: Loading Main window from url: ${contentUrl} ...`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await browserWindow.loadURL(contentUrl);
|
||||||
|
|
||||||
|
const viewHasLoaded = new Promise<void>((resolve) => {
|
||||||
|
ipcMain.once(bundledExtensionsLoaded, () => resolve());
|
||||||
|
});
|
||||||
|
|
||||||
|
await viewHasLoaded;
|
||||||
|
await delay(50); // wait just a bit longer to let the first round of rendering happen
|
||||||
|
|
||||||
|
return browserWindow;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default createBrowserWindowInjectable;
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 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?: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LensWindow {
|
||||||
|
show: () => Promise<void>;
|
||||||
|
hide: () => void;
|
||||||
|
close: () => void;
|
||||||
|
send: (args: SendToViewArgs) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const lensWindowInjectionToken = getInjectionToken<LensWindow>({
|
||||||
|
id: "lens-window",
|
||||||
|
});
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { BrowserWindow } from "electron";
|
||||||
|
import type { SendToViewArgs } from "./lens-window-injection-token";
|
||||||
|
|
||||||
|
const sendToChannelInElectronBrowserWindowInjectable = getInjectable({
|
||||||
|
id: "send-to-channel-in-electron-browser-window",
|
||||||
|
|
||||||
|
instantiate:
|
||||||
|
() =>
|
||||||
|
async (
|
||||||
|
browserWindow: BrowserWindow,
|
||||||
|
{ channel, frameInfo, data = [] }: SendToViewArgs,
|
||||||
|
) => {
|
||||||
|
if (frameInfo) {
|
||||||
|
browserWindow.webContents.sendToFrame(
|
||||||
|
[frameInfo.processId, frameInfo.frameId],
|
||||||
|
channel,
|
||||||
|
...data,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
browserWindow.webContents.send(channel, ...data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default sendToChannelInElectronBrowserWindowInjectable;
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* 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 { observable } from "mobx";
|
||||||
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
|
|
||||||
|
const currentClusterFrameClusterIdStateInjectable = getInjectable({
|
||||||
|
id: "current-cluster-frame-cluster-id-state",
|
||||||
|
|
||||||
|
instantiate: () => observable.box<ClusterId>(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default currentClusterFrameClusterIdStateInjectable;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* 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 { computed } from "mobx";
|
||||||
|
import currentClusterFrameClusterIdStateInjectable from "./current-cluster-frame-cluster-id-state.injectable";
|
||||||
|
import clusterFramesInjectable from "../../../../common/cluster-frames.injectable";
|
||||||
|
|
||||||
|
const currentClusterFrameInjectable = getInjectable({
|
||||||
|
id: "current-cluster-frame",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const currentClusterFrameState = di.inject(currentClusterFrameClusterIdStateInjectable);
|
||||||
|
const clusterFrames = di.inject(clusterFramesInjectable);
|
||||||
|
|
||||||
|
return computed(() => {
|
||||||
|
const clusterId = currentClusterFrameState.get();
|
||||||
|
|
||||||
|
return clusterFrames.get(clusterId);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default currentClusterFrameInjectable;
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { ipcMainOn } from "../../../../common/ipc";
|
||||||
|
import { IpcRendererNavigationEvents } from "../../../../renderer/navigation/events";
|
||||||
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
|
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../../when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
|
import currentClusterFrameClusterIdStateInjectable from "./current-cluster-frame-cluster-id-state.injectable";
|
||||||
|
|
||||||
|
const setupListenerForCurrentClusterFrameInjectable = getInjectable({
|
||||||
|
id: "setup-listener-for-current-cluster-frame",
|
||||||
|
|
||||||
|
instantiate: (di) => ({
|
||||||
|
run: () => {
|
||||||
|
const currentClusterFrameState = di.inject(currentClusterFrameClusterIdStateInjectable);
|
||||||
|
|
||||||
|
ipcMainOn(
|
||||||
|
IpcRendererNavigationEvents.CLUSTER_VIEW_CURRENT_ID,
|
||||||
|
(event, clusterId: ClusterId) => {
|
||||||
|
currentClusterFrameState.set(clusterId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default setupListenerForCurrentClusterFrameInjectable;
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* 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 "../application-window/lens-window-injection-token";
|
||||||
|
|
||||||
|
const hideAllWindowsInjectable = getInjectable({
|
||||||
|
id: "hide-all-windows",
|
||||||
|
|
||||||
|
instantiate: (di) => () => {
|
||||||
|
const lensWindows = di.injectMany(lensWindowInjectionToken);
|
||||||
|
|
||||||
|
lensWindows.forEach((lensWindow) => {
|
||||||
|
lensWindow.hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default hideAllWindowsInjectable;
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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 { iter } from "../../../common/utils";
|
||||||
|
import applicationWindowInjectable from "./application-window/application-window.injectable";
|
||||||
|
import clusterFramesInjectable from "../../../common/cluster-frames.injectable";
|
||||||
|
|
||||||
|
const navigateForExtensionInjectable = getInjectable({
|
||||||
|
id: "navigate-for-extension",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const applicationWindow = di.inject(applicationWindowInjectable);
|
||||||
|
const clusterFrames = di.inject(clusterFramesInjectable);
|
||||||
|
|
||||||
|
return async (
|
||||||
|
extId: string,
|
||||||
|
pageId?: string,
|
||||||
|
params?: Record<string, any>,
|
||||||
|
frameId?: number,
|
||||||
|
) => {
|
||||||
|
await applicationWindow.show();
|
||||||
|
|
||||||
|
const frameInfo = iter.find(
|
||||||
|
clusterFrames.values(),
|
||||||
|
(frameInfo) => frameInfo.frameId === frameId,
|
||||||
|
);
|
||||||
|
|
||||||
|
await applicationWindow.send({
|
||||||
|
channel: "extension:navigate",
|
||||||
|
frameInfo,
|
||||||
|
data: [extId, pageId, params],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default navigateForExtensionInjectable;
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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 { 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";
|
||||||
|
|
||||||
|
const navigateInjectable = getInjectable({
|
||||||
|
id: "navigate",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const applicationWindow = di.inject(applicationWindowInjectable);
|
||||||
|
const clusterFrames = di.inject(clusterFramesInjectable);
|
||||||
|
|
||||||
|
return async (url: string, frameId?: number) => {
|
||||||
|
await applicationWindow.show();
|
||||||
|
|
||||||
|
const frameInfo = iter.find(
|
||||||
|
clusterFrames.values(),
|
||||||
|
(frameInfo) => frameInfo.frameId === frameId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const channel = frameInfo
|
||||||
|
? IpcRendererNavigationEvents.NAVIGATE_IN_CLUSTER
|
||||||
|
: IpcRendererNavigationEvents.NAVIGATE_IN_APP;
|
||||||
|
|
||||||
|
await applicationWindow.send({
|
||||||
|
channel,
|
||||||
|
frameInfo,
|
||||||
|
data: [url],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default navigateInjectable;
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
@ -5,10 +5,20 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
import electronAppInjectable from "../electron-app/electron-app.injectable";
|
import electronAppInjectable from "../electron-app/electron-app.injectable";
|
||||||
import { beforeApplicationIsReadyInjectionToken } from "./before-application-is-ready/before-application-is-ready-injection-token";
|
|
||||||
import { afterApplicationIsReadyInjectionToken } from "./after-application-is-ready/after-application-is-ready-injection-token";
|
|
||||||
import { runManyFor } from "./run-many-for";
|
import { runManyFor } from "./run-many-for";
|
||||||
import { runManySyncFor } from "./run-many-sync-for";
|
import { runManySyncFor } from "./run-many-sync-for";
|
||||||
|
import { beforeElectronIsReadyInjectionToken } from "./before-electron-is-ready/before-electron-is-ready-injection-token";
|
||||||
|
import { beforeApplicationIsLoadingInjectionToken } from "./before-application-is-loading/before-application-is-loading-injection-token";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "./when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
|
import { afterApplicationIsLoadedInjectionToken } from "./after-application-is-loaded/after-application-is-loaded-injection-token";
|
||||||
|
import applicationIsLoadingWindowInjectable from "./lens-window/application-is-loading-window/application-is-loading-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";
|
||||||
|
|
||||||
const startMainApplicationInjectable = getInjectable({
|
const startMainApplicationInjectable = getInjectable({
|
||||||
id: "start-main-application",
|
id: "start-main-application",
|
||||||
@ -16,21 +26,52 @@ const startMainApplicationInjectable = getInjectable({
|
|||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const runMany = runManyFor(di);
|
const runMany = runManyFor(di);
|
||||||
const runManySync = runManySyncFor(di);
|
const runManySync = runManySyncFor(di);
|
||||||
const app = di.inject(electronAppInjectable);
|
const electronApp = di.inject(electronAppInjectable);
|
||||||
|
const applicationWindow = di.inject(applicationWindowInjectable);
|
||||||
|
const applicationIsLoadingWindow = di.inject(applicationIsLoadingWindowInjectable);
|
||||||
|
const shouldStartHidden = di.inject(shouldStartHiddenInjectable);
|
||||||
|
const openDeepLink = di.inject(openDeepLinkInjectable);
|
||||||
|
const commandLineArguments = di.inject(commandLineArgumentsInjectable);
|
||||||
|
|
||||||
|
const beforeElectronIsReady = runManySync(beforeElectronIsReadyInjectionToken);
|
||||||
|
const beforeApplicationIsLoading = runMany(beforeApplicationIsLoadingInjectionToken);
|
||||||
|
const whenApplicationIsLoading = runMany(whenApplicationIsLoadingInjectionToken);
|
||||||
|
const afterApplicationIsLoaded = runMany(afterApplicationIsLoadedInjectionToken);
|
||||||
|
|
||||||
return async () => {
|
return async () => {
|
||||||
// Stuff happening before application is ready needs to be synchronous because of
|
// Stuff happening before application is ready needs to be synchronous because of
|
||||||
// https://github.com/electron/electron/issues/21370
|
// https://github.com/electron/electron/issues/21370
|
||||||
runManySync(beforeApplicationIsReadyInjectionToken)();
|
beforeElectronIsReady();
|
||||||
|
|
||||||
await app.whenReady();
|
await electronApp.whenReady();
|
||||||
|
|
||||||
await runMany(afterApplicationIsReadyInjectionToken)();
|
await beforeApplicationIsLoading();
|
||||||
|
|
||||||
|
if (!shouldStartHidden) {
|
||||||
|
await applicationIsLoadingWindow.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
await whenApplicationIsLoading();
|
||||||
|
|
||||||
|
if (!shouldStartHidden) {
|
||||||
|
const url = getDeepLinkUrl(commandLineArguments);
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
await openDeepLink(url);
|
||||||
|
} else {
|
||||||
|
await applicationWindow.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
applicationIsLoadingWindow.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
await afterApplicationIsLoaded();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getDeepLinkUrl = (commandLineArguments: string[]) =>
|
||||||
|
pipeline(commandLineArguments, map(toLower), find(startsWith("lens://")));
|
||||||
|
|
||||||
|
|
||||||
export default startMainApplicationInjectable;
|
export default startMainApplicationInjectable;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,13 +3,13 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import type { InstalledExtension } from "../../../../extensions/extension-discovery/extension-discovery";
|
import type { InstalledExtension } from "../../../../extensions/extension-discovery/extension-discovery";
|
||||||
import type { LensExtensionId } from "../../../../extensions/lens-extension";
|
import type { LensExtensionId } from "../../../../extensions/lens-extension";
|
||||||
import loggerInjectable from "../../../../common/logger.injectable";
|
import loggerInjectable from "../../../../common/logger.injectable";
|
||||||
import extensionDiscoveryInjectable from "../../../../extensions/extension-discovery/extension-discovery.injectable";
|
import extensionDiscoveryInjectable from "../../../../extensions/extension-discovery/extension-discovery.injectable";
|
||||||
import extensionLoaderInjectable from "../../../../extensions/extension-loader/extension-loader.injectable";
|
import extensionLoaderInjectable from "../../../../extensions/extension-loader/extension-loader.injectable";
|
||||||
import showErrorPopupInjectable from "../../../electron-app/features/show-error-popup.injectable";
|
import showErrorPopupInjectable from "../../../electron-app/features/show-error-popup.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const initializeExtensionsInjectable = getInjectable({
|
const initializeExtensionsInjectable = getInjectable({
|
||||||
id: "initialize-extensions",
|
id: "initialize-extensions",
|
||||||
@ -61,7 +61,7 @@ const initializeExtensionsInjectable = getInjectable({
|
|||||||
|
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default initializeExtensionsInjectable;
|
export default initializeExtensionsInjectable;
|
||||||
@ -3,13 +3,13 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import { ClusterIdDetector } from "../../../cluster-detectors/cluster-id-detector";
|
import { ClusterIdDetector } from "../../../cluster-detectors/cluster-id-detector";
|
||||||
import { LastSeenDetector } from "../../../cluster-detectors/last-seen-detector";
|
import { LastSeenDetector } from "../../../cluster-detectors/last-seen-detector";
|
||||||
import { VersionDetector } from "../../../cluster-detectors/version-detector";
|
import { VersionDetector } from "../../../cluster-detectors/version-detector";
|
||||||
import { DistributionDetector } from "../../../cluster-detectors/distribution-detector";
|
import { DistributionDetector } from "../../../cluster-detectors/distribution-detector";
|
||||||
import { NodesCountDetector } from "../../../cluster-detectors/nodes-count-detector";
|
import { NodesCountDetector } from "../../../cluster-detectors/nodes-count-detector";
|
||||||
import detectorRegistryInjectable from "../../../cluster-detectors/detector-registry.injectable";
|
import detectorRegistryInjectable from "../../../cluster-detectors/detector-registry.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupDetectorRegistryInjectable = getInjectable({
|
const setupDetectorRegistryInjectable = getInjectable({
|
||||||
id: "setup-detector-registry",
|
id: "setup-detector-registry",
|
||||||
@ -29,7 +29,7 @@ const setupDetectorRegistryInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupDetectorRegistryInjectable;
|
export default setupDetectorRegistryInjectable;
|
||||||
@ -3,9 +3,9 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import hotbarStoreInjectable from "../../../../common/hotbar-store.injectable";
|
import hotbarStoreInjectable from "../../../../common/hotbar-store.injectable";
|
||||||
import setupSyncingOfGeneralCatalogEntitiesInjectable from "./setup-syncing-of-general-catalog-entities.injectable";
|
import setupSyncingOfGeneralCatalogEntitiesInjectable from "./setup-syncing-of-general-catalog-entities.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupHotbarStoreInjectable = getInjectable({
|
const setupHotbarStoreInjectable = getInjectable({
|
||||||
id: "setup-hotbar-store",
|
id: "setup-hotbar-store",
|
||||||
@ -20,7 +20,7 @@ const setupHotbarStoreInjectable = getInjectable({
|
|||||||
runAfter: di.inject(setupSyncingOfGeneralCatalogEntitiesInjectable),
|
runAfter: di.inject(setupSyncingOfGeneralCatalogEntitiesInjectable),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupHotbarStoreInjectable;
|
export default setupHotbarStoreInjectable;
|
||||||
@ -3,12 +3,12 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import { PrometheusLens } from "../../../prometheus/lens";
|
import { PrometheusLens } from "../../../prometheus/lens";
|
||||||
import { PrometheusHelm } from "../../../prometheus/helm";
|
import { PrometheusHelm } from "../../../prometheus/helm";
|
||||||
import { PrometheusOperator } from "../../../prometheus/operator";
|
import { PrometheusOperator } from "../../../prometheus/operator";
|
||||||
import { PrometheusStacklight } from "../../../prometheus/stacklight";
|
import { PrometheusStacklight } from "../../../prometheus/stacklight";
|
||||||
import prometheusProviderRegistryInjectable from "../../../prometheus/prometheus-provider-registry.injectable";
|
import prometheusProviderRegistryInjectable from "../../../prometheus/prometheus-provider-registry.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupPrometheusRegistryInjectable = getInjectable({
|
const setupPrometheusRegistryInjectable = getInjectable({
|
||||||
id: "setup-prometheus-registry",
|
id: "setup-prometheus-registry",
|
||||||
@ -27,7 +27,7 @@ const setupPrometheusRegistryInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupPrometheusRegistryInjectable;
|
export default setupPrometheusRegistryInjectable;
|
||||||
@ -3,8 +3,8 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import userStoreInjectable from "../../../../common/user-store/user-store.injectable";
|
import userStoreInjectable from "../../../../common/user-store/user-store.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupReactionsInUserStoreInjectable = getInjectable({
|
const setupReactionsInUserStoreInjectable = getInjectable({
|
||||||
id: "setup-reactions-in-user-store",
|
id: "setup-reactions-in-user-store",
|
||||||
@ -19,7 +19,7 @@ const setupReactionsInUserStoreInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupReactionsInUserStoreInjectable;
|
export default setupReactionsInUserStoreInjectable;
|
||||||
@ -6,8 +6,8 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import { ipcMainOn } from "../../../../common/ipc";
|
import { ipcMainOn } from "../../../../common/ipc";
|
||||||
import { IpcRendererNavigationEvents } from "../../../../renderer/navigation/events";
|
import { IpcRendererNavigationEvents } from "../../../../renderer/navigation/events";
|
||||||
import { afterRootFrameIsReadyInjectionToken } from "../../after-root-frame-is-ready/after-root-frame-is-ready-injection-token";
|
import { afterRootFrameIsReadyInjectionToken } from "../../after-root-frame-is-ready/after-root-frame-is-ready-injection-token";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import { runManyFor } from "../../run-many-for";
|
import { runManyFor } from "../../run-many-for";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupRunnablesForAfterRootFrameIsReadyInjectable = getInjectable({
|
const setupRunnablesForAfterRootFrameIsReadyInjectable = getInjectable({
|
||||||
id: "setup-runnables-for-after-root-frame-is-ready",
|
id: "setup-runnables-for-after-root-frame-is-ready",
|
||||||
@ -31,7 +31,7 @@ const setupRunnablesForAfterRootFrameIsReadyInjectable = getInjectable({
|
|||||||
// Direct usage of IPC
|
// Direct usage of IPC
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupRunnablesForAfterRootFrameIsReadyInjectable;
|
export default setupRunnablesForAfterRootFrameIsReadyInjectable;
|
||||||
@ -3,9 +3,9 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import { initializeSentryReporting } from "../../../../common/sentry";
|
import { initializeSentryReporting } from "../../../../common/sentry";
|
||||||
import { init } from "@sentry/electron/main";
|
import { init } from "@sentry/electron/main";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupSentryInjectable = getInjectable({
|
const setupSentryInjectable = getInjectable({
|
||||||
id: "setup-sentry",
|
id: "setup-sentry",
|
||||||
@ -18,7 +18,7 @@ const setupSentryInjectable = getInjectable({
|
|||||||
|
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupSentryInjectable;
|
export default setupSentryInjectable;
|
||||||
@ -3,9 +3,9 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import { shellSync } from "../../../shell-sync";
|
import { shellSync } from "../../../shell-sync";
|
||||||
import loggerInjectable from "../../../../common/logger.injectable";
|
import loggerInjectable from "../../../../common/logger.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupShellInjectable = getInjectable({
|
const setupShellInjectable = getInjectable({
|
||||||
id: "setup-shell",
|
id: "setup-shell",
|
||||||
@ -22,7 +22,7 @@ const setupShellInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3,8 +3,8 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import syncGeneralCatalogEntitiesInjectable from "../../../catalog-sources/sync-general-catalog-entities.injectable";
|
import syncGeneralCatalogEntitiesInjectable from "../../../catalog-sources/sync-general-catalog-entities.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupSyncingOfGeneralCatalogEntitiesInjectable = getInjectable({
|
const setupSyncingOfGeneralCatalogEntitiesInjectable = getInjectable({
|
||||||
id: "setup-syncing-of-general-catalog-entities",
|
id: "setup-syncing-of-general-catalog-entities",
|
||||||
@ -21,7 +21,7 @@ const setupSyncingOfGeneralCatalogEntitiesInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupSyncingOfGeneralCatalogEntitiesInjectable;
|
export default setupSyncingOfGeneralCatalogEntitiesInjectable;
|
||||||
@ -3,10 +3,10 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
|
|
||||||
import { syncWeblinks } from "../../../catalog-sources";
|
import { syncWeblinks } from "../../../catalog-sources";
|
||||||
import weblinkStoreInjectable from "../../../../common/weblink-store.injectable";
|
import weblinkStoreInjectable from "../../../../common/weblink-store.injectable";
|
||||||
import catalogEntityRegistryInjectable from "../../../catalog/catalog-entity-registry.injectable";
|
import catalogEntityRegistryInjectable from "../../../catalog/catalog-entity-registry.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const setupSyncingOfWeblinksInjectable = getInjectable({
|
const setupSyncingOfWeblinksInjectable = getInjectable({
|
||||||
id: "setup-syncing-of-weblinks",
|
id: "setup-syncing-of-weblinks",
|
||||||
@ -22,7 +22,7 @@ const setupSyncingOfWeblinksInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default setupSyncingOfWeblinksInjectable;
|
export default setupSyncingOfWeblinksInjectable;
|
||||||
@ -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 { Runnable } from "../run-many-for";
|
||||||
|
|
||||||
|
export const whenApplicationIsLoadingInjectionToken = getInjectionToken<Runnable>({
|
||||||
|
id: "when-application-is-loading",
|
||||||
|
});
|
||||||
@ -5,23 +5,23 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import exitAppInjectable from "./electron-app/features/exit-app.injectable";
|
import exitAppInjectable from "./electron-app/features/exit-app.injectable";
|
||||||
import clusterManagerInjectable from "./cluster-manager.injectable";
|
import clusterManagerInjectable from "./cluster-manager.injectable";
|
||||||
import windowManagerInjectable from "./window-manager.injectable";
|
|
||||||
import appEventBusInjectable from "../common/app-event-bus/app-event-bus.injectable";
|
import appEventBusInjectable from "../common/app-event-bus/app-event-bus.injectable";
|
||||||
import loggerInjectable from "../common/logger.injectable";
|
import loggerInjectable from "../common/logger.injectable";
|
||||||
|
import hideAllWindowsInjectable from "./start-main-application/lens-window/hide-all-windows/hide-all-windows.injectable";
|
||||||
|
|
||||||
const stopServicesAndExitAppInjectable = getInjectable({
|
const stopServicesAndExitAppInjectable = getInjectable({
|
||||||
id: "stop-services-and-exit-app",
|
id: "stop-services-and-exit-app",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const exitApp = di.inject(exitAppInjectable);
|
const exitApp = di.inject(exitAppInjectable);
|
||||||
const windowManager = di.inject(windowManagerInjectable);
|
|
||||||
const clusterManager = di.inject(clusterManagerInjectable);
|
const clusterManager = di.inject(clusterManagerInjectable);
|
||||||
const appEventBus = di.inject(appEventBusInjectable);
|
const appEventBus = di.inject(appEventBusInjectable);
|
||||||
const logger = di.inject(loggerInjectable);
|
const logger = di.inject(loggerInjectable);
|
||||||
|
const hideAllWindows = di.inject(hideAllWindowsInjectable);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
appEventBus.emit({ name: "service", action: "close" });
|
appEventBus.emit({ name: "service", action: "close" });
|
||||||
windowManager.hide();
|
hideAllWindows();
|
||||||
clusterManager.stop();
|
clusterManager.stop();
|
||||||
logger.info("SERVICE:QUIT");
|
logger.info("SERVICE:QUIT");
|
||||||
setTimeout(exitApp, 1000);
|
setTimeout(exitApp, 1000);
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { afterApplicationIsReadyInjectionToken } from "../start-main-application/after-application-is-ready/after-application-is-ready-injection-token";
|
|
||||||
import trayInjectable from "./tray.injectable";
|
import trayInjectable from "./tray.injectable";
|
||||||
|
import { whenApplicationIsLoadingInjectionToken } from "../start-main-application/when-application-is-loading/when-application-is-loading-injection-token";
|
||||||
|
|
||||||
const startTrayInjectable = getInjectable({
|
const startTrayInjectable = getInjectable({
|
||||||
id: "start-tray",
|
id: "start-tray",
|
||||||
@ -19,7 +19,7 @@ const startTrayInjectable = getInjectable({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: afterApplicationIsReadyInjectionToken,
|
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default startTrayInjectable;
|
export default startTrayInjectable;
|
||||||
|
|||||||
@ -4,33 +4,36 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { initTray } from "./tray";
|
import { initTray } from "./tray";
|
||||||
import windowManagerInjectable from "../window-manager.injectable";
|
|
||||||
import trayMenuItemsInjectable from "./tray-menu-items.injectable";
|
import trayMenuItemsInjectable from "./tray-menu-items.injectable";
|
||||||
import navigateToPreferencesInjectable from "../../common/front-end-routing/routes/preferences/navigate-to-preferences.injectable";
|
import navigateToPreferencesInjectable from "../../common/front-end-routing/routes/preferences/navigate-to-preferences.injectable";
|
||||||
import stopServicesAndExitAppInjectable from "../stop-services-and-exit-app.injectable";
|
import stopServicesAndExitAppInjectable from "../stop-services-and-exit-app.injectable";
|
||||||
import { getStartableStoppable } from "../../common/utils/get-startable-stoppable";
|
import { getStartableStoppable } from "../../common/utils/get-startable-stoppable";
|
||||||
import isAutoUpdateEnabledInjectable from "../is-auto-update-enabled.injectable";
|
import isAutoUpdateEnabledInjectable from "../is-auto-update-enabled.injectable";
|
||||||
import trayIconPathInjectable from "./tray-icon-path.injectable";
|
import trayIconPathInjectable from "./tray-icon-path.injectable";
|
||||||
|
import applicationWindowInjectable from "../start-main-application/lens-window/application-window/application-window.injectable";
|
||||||
|
import showAboutInjectable from "../menu/show-about.injectable";
|
||||||
|
|
||||||
const trayInjectable = getInjectable({
|
const trayInjectable = getInjectable({
|
||||||
id: "tray",
|
id: "tray",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const windowManager = di.inject(windowManagerInjectable);
|
|
||||||
const trayMenuItems = di.inject(trayMenuItemsInjectable);
|
const trayMenuItems = di.inject(trayMenuItemsInjectable);
|
||||||
const navigateToPreferences = di.inject(navigateToPreferencesInjectable);
|
const navigateToPreferences = di.inject(navigateToPreferencesInjectable);
|
||||||
const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable);
|
const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable);
|
||||||
const isAutoUpdateEnabled = di.inject(isAutoUpdateEnabledInjectable);
|
const isAutoUpdateEnabled = di.inject(isAutoUpdateEnabledInjectable);
|
||||||
const trayIconPath = di.inject(trayIconPathInjectable);
|
const trayIconPath = di.inject(trayIconPathInjectable);
|
||||||
|
const applicationWindow = di.inject(applicationWindowInjectable);
|
||||||
|
const showAboutPopup = di.inject(showAboutInjectable);
|
||||||
|
|
||||||
return getStartableStoppable("build-of-tray", () =>
|
return getStartableStoppable("build-of-tray", () =>
|
||||||
initTray(
|
initTray(
|
||||||
windowManager,
|
|
||||||
trayMenuItems,
|
trayMenuItems,
|
||||||
navigateToPreferences,
|
navigateToPreferences,
|
||||||
stopServicesAndExitApp,
|
stopServicesAndExitApp,
|
||||||
isAutoUpdateEnabled,
|
isAutoUpdateEnabled,
|
||||||
trayIconPath,
|
trayIconPath,
|
||||||
|
applicationWindow,
|
||||||
|
showAboutPopup,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -7,15 +7,14 @@ import packageInfo from "../../../package.json";
|
|||||||
import { Menu, Tray } from "electron";
|
import { Menu, Tray } from "electron";
|
||||||
import type { IComputedValue } from "mobx";
|
import type { IComputedValue } from "mobx";
|
||||||
import { autorun } from "mobx";
|
import { autorun } from "mobx";
|
||||||
import { showAbout } from "../menu/menu";
|
|
||||||
import { checkForUpdates } from "../app-updater";
|
import { checkForUpdates } from "../app-updater";
|
||||||
import type { WindowManager } from "../window-manager";
|
|
||||||
import logger from "../logger";
|
import logger from "../logger";
|
||||||
import { isDevelopment, isWindows, productName, staticFilesDirectory } from "../../common/vars";
|
import { isDevelopment, isWindows, productName, staticFilesDirectory } from "../../common/vars";
|
||||||
import type { Disposer } from "../../common/utils";
|
import type { Disposer } from "../../common/utils";
|
||||||
import { disposer, toJS } from "../../common/utils";
|
import { disposer, toJS } from "../../common/utils";
|
||||||
import type { TrayMenuRegistration } from "./tray-menu-registration";
|
import type { TrayMenuRegistration } from "./tray-menu-registration";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import type { LensWindow } from "../start-main-application/lens-window/application-window/lens-window-injection-token";
|
||||||
|
|
||||||
const TRAY_LOG_PREFIX = "[TRAY]";
|
const TRAY_LOG_PREFIX = "[TRAY]";
|
||||||
|
|
||||||
@ -31,11 +30,12 @@ function getTrayIconPath(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function initTray(
|
export function initTray(
|
||||||
windowManager: WindowManager,
|
|
||||||
trayMenuItems: IComputedValue<TrayMenuRegistration[]>,
|
trayMenuItems: IComputedValue<TrayMenuRegistration[]>,
|
||||||
navigateToPreferences: () => void,
|
navigateToPreferences: () => void,
|
||||||
stopServicesAndExitApp: () => void,
|
stopServicesAndExitApp: () => void,
|
||||||
isAutoUpdateEnabled: () => boolean,
|
isAutoUpdateEnabled: () => boolean,
|
||||||
|
applicationWindow: LensWindow,
|
||||||
|
showAbout: () => void,
|
||||||
): Disposer {
|
): Disposer {
|
||||||
const icon = getTrayIconPath();
|
const icon = getTrayIconPath();
|
||||||
|
|
||||||
@ -45,8 +45,7 @@ export function initTray(
|
|||||||
|
|
||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
tray.on("click", () => {
|
tray.on("click", () => {
|
||||||
windowManager
|
applicationWindow.show()
|
||||||
.ensureMainWindow()
|
|
||||||
.catch(error => logger.error(`${TRAY_LOG_PREFIX}: Failed to open lens`, { error }));
|
.catch(error => logger.error(`${TRAY_LOG_PREFIX}: Failed to open lens`, { error }));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -54,7 +53,7 @@ export function initTray(
|
|||||||
return disposer(
|
return disposer(
|
||||||
autorun(() => {
|
autorun(() => {
|
||||||
try {
|
try {
|
||||||
const menu = createTrayMenu(windowManager, toJS(trayMenuItems.get()), navigateToPreferences, stopServicesAndExitApp, isAutoUpdateEnabled);
|
const menu = createTrayMenu(toJS(trayMenuItems.get()), navigateToPreferences, stopServicesAndExitApp, isAutoUpdateEnabled, applicationWindow, showAbout);
|
||||||
|
|
||||||
tray.setContextMenu(menu);
|
tray.setContextMenu(menu);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -79,19 +78,18 @@ function getMenuItemConstructorOptions(trayItem: TrayMenuRegistration): Electron
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createTrayMenu(
|
function createTrayMenu(
|
||||||
windowManager: WindowManager,
|
|
||||||
extensionTrayItems: TrayMenuRegistration[],
|
extensionTrayItems: TrayMenuRegistration[],
|
||||||
navigateToPreferences: () => void,
|
navigateToPreferences: () => void,
|
||||||
stopServicesAndExitApp: () => void,
|
stopServicesAndExitApp: () => void,
|
||||||
isAutoUpdateEnabled: () => boolean,
|
isAutoUpdateEnabled: () => boolean,
|
||||||
|
applicationWindow: LensWindow,
|
||||||
|
showAbout: () => void,
|
||||||
): Menu {
|
): Menu {
|
||||||
let template: Electron.MenuItemConstructorOptions[] = [
|
let template: Electron.MenuItemConstructorOptions[] = [
|
||||||
{
|
{
|
||||||
label: `Open ${productName}`,
|
label: `Open ${productName}`,
|
||||||
click() {
|
click() {
|
||||||
windowManager
|
applicationWindow.show().catch(error => logger.error(`${TRAY_LOG_PREFIX}: Failed to open lens`, { error }));
|
||||||
.ensureMainWindow()
|
|
||||||
.catch(error => logger.error(`${TRAY_LOG_PREFIX}: Failed to open lens`, { error }));
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -107,7 +105,7 @@ function createTrayMenu(
|
|||||||
label: "Check for updates",
|
label: "Check for updates",
|
||||||
click() {
|
click() {
|
||||||
checkForUpdates()
|
checkForUpdates()
|
||||||
.then(() => windowManager.ensureMainWindow());
|
.then(() => applicationWindow.show());
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -118,7 +116,7 @@ function createTrayMenu(
|
|||||||
{
|
{
|
||||||
label: `About ${productName}`,
|
label: `About ${productName}`,
|
||||||
click() {
|
click() {
|
||||||
windowManager.ensureMainWindow()
|
applicationWindow.show()
|
||||||
.then(showAbout)
|
.then(showAbout)
|
||||||
.catch(error => logger.error(`${TRAY_LOG_PREFIX}: Failed to show Lens About view`, { error }));
|
.catch(error => logger.error(`${TRAY_LOG_PREFIX}: Failed to show Lens About view`, { error }));
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,20 +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 { WindowManager } from "./window-manager";
|
|
||||||
import lensProxyPortNumberStateInjectable from "./lens-proxy-port-number-state.injectable";
|
|
||||||
|
|
||||||
const windowManagerInjectable = getInjectable({
|
|
||||||
id: "window-manager",
|
|
||||||
|
|
||||||
instantiate: (di) =>
|
|
||||||
new WindowManager({
|
|
||||||
lensProxyPortNumberState: di.inject(lensProxyPortNumberStateInjectable),
|
|
||||||
}),
|
|
||||||
|
|
||||||
causesSideEffects: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default windowManagerInjectable;
|
|
||||||
@ -1,289 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { ClusterId } from "../common/cluster-types";
|
|
||||||
import { makeObservable, observable } from "mobx";
|
|
||||||
import { app, BrowserWindow, dialog, ipcMain, webContents } from "electron";
|
|
||||||
import windowStateKeeper from "electron-window-state";
|
|
||||||
import { appEventBus } from "../common/app-event-bus/event-bus";
|
|
||||||
import { ipcMainOn } from "../common/ipc";
|
|
||||||
import { delay, iter, openBrowser } from "../common/utils";
|
|
||||||
import type { ClusterFrameInfo } from "../common/cluster-frames";
|
|
||||||
import { clusterFrameMap } from "../common/cluster-frames";
|
|
||||||
import { IpcRendererNavigationEvents } from "../renderer/navigation/events";
|
|
||||||
import logger from "./logger";
|
|
||||||
import { isMac, productName } from "../common/vars";
|
|
||||||
import { bundledExtensionsLoaded } from "../common/ipc/extension-handling";
|
|
||||||
|
|
||||||
function isHideable(window: BrowserWindow | null): boolean {
|
|
||||||
return Boolean(window && !window.isDestroyed());
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SendToViewArgs {
|
|
||||||
channel: string;
|
|
||||||
frameInfo?: ClusterFrameInfo;
|
|
||||||
data?: any[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Dependencies {
|
|
||||||
lensProxyPortNumberState: { get: () => number };
|
|
||||||
}
|
|
||||||
|
|
||||||
export class WindowManager {
|
|
||||||
protected mainWindow: BrowserWindow;
|
|
||||||
protected splashWindow: BrowserWindow;
|
|
||||||
protected windowState: windowStateKeeper.State;
|
|
||||||
protected disposers: Record<string, Function> = {};
|
|
||||||
|
|
||||||
@observable activeClusterId: ClusterId;
|
|
||||||
|
|
||||||
constructor(private dependencies: Dependencies) {
|
|
||||||
makeObservable(this);
|
|
||||||
this.bindEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
get mainContentUrl() {
|
|
||||||
return `http://localhost:${this.dependencies.lensProxyPortNumberState.get()}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async initMainWindow(showSplash: boolean) {
|
|
||||||
// Manage main window size and position with state persistence
|
|
||||||
if (!this.windowState) {
|
|
||||||
this.windowState = windowStateKeeper({
|
|
||||||
defaultHeight: 900,
|
|
||||||
defaultWidth: 1440,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.mainWindow) {
|
|
||||||
// show icon in dock (mac-os only)
|
|
||||||
app.dock?.show();
|
|
||||||
|
|
||||||
const { width, height, x, y } = this.windowState;
|
|
||||||
|
|
||||||
this.mainWindow = new BrowserWindow({
|
|
||||||
x, y, width, height,
|
|
||||||
title: productName,
|
|
||||||
show: false,
|
|
||||||
minWidth: 700, // accommodate 800 x 600 display minimum
|
|
||||||
minHeight: 500, // accommodate 800 x 600 display minimum
|
|
||||||
titleBarStyle: isMac ? "hiddenInset" : "hidden",
|
|
||||||
frame: isMac,
|
|
||||||
backgroundColor: "#1e2124",
|
|
||||||
webPreferences: {
|
|
||||||
nodeIntegration: true,
|
|
||||||
nodeIntegrationInSubFrames: true,
|
|
||||||
webviewTag: true,
|
|
||||||
contextIsolation: false,
|
|
||||||
nativeWindowOpen: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.windowState.manage(this.mainWindow);
|
|
||||||
|
|
||||||
// open external links in default browser (target=_blank, window.open)
|
|
||||||
this.mainWindow
|
|
||||||
.on("focus", () => {
|
|
||||||
appEventBus.emit({ name: "app", action: "focus" });
|
|
||||||
})
|
|
||||||
.on("blur", () => {
|
|
||||||
appEventBus.emit({ name: "app", action: "blur" });
|
|
||||||
})
|
|
||||||
.on("closed", () => {
|
|
||||||
// clean up
|
|
||||||
this.windowState.unmanage();
|
|
||||||
this.mainWindow = null;
|
|
||||||
this.splashWindow = null;
|
|
||||||
app.dock?.hide(); // hide icon in dock (mac-os)
|
|
||||||
})
|
|
||||||
.webContents
|
|
||||||
.on("dom-ready", () => {
|
|
||||||
appEventBus.emit({ name: "app", action: "dom-ready" });
|
|
||||||
})
|
|
||||||
.on("did-fail-load", (_event, code, desc) => {
|
|
||||||
logger.error(`[WINDOW-MANAGER]: Failed to load Main window`, { code, desc });
|
|
||||||
})
|
|
||||||
.on("did-finish-load", () => {
|
|
||||||
logger.info("[WINDOW-MANAGER]: Main window loaded");
|
|
||||||
})
|
|
||||||
.on("will-attach-webview", (event, webPreferences, params) => {
|
|
||||||
logger.debug("[WINDOW-MANAGER]: Attaching webview");
|
|
||||||
// Following is security recommendations because we allow webview tag (webviewTag: true)
|
|
||||||
// suggested by https://www.electronjs.org/docs/tutorial/security#11-verify-webview-options-before-creation
|
|
||||||
// and https://www.electronjs.org/docs/tutorial/security#10-do-not-use-allowpopups
|
|
||||||
|
|
||||||
if (webPreferences.preload) {
|
|
||||||
logger.warn("[WINDOW-MANAGER]: Strip away preload scripts of webview");
|
|
||||||
delete webPreferences.preload;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-expect-error some electron version uses webPreferences.preloadURL/webPreferences.preload
|
|
||||||
if (webPreferences.preloadURL) {
|
|
||||||
logger.warn("[WINDOW-MANAGER]: Strip away preload scripts of webview");
|
|
||||||
delete webPreferences.preload;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.allowpopups) {
|
|
||||||
logger.warn("[WINDOW-MANAGER]: We do not allow allowpopups props, stop webview from renderer");
|
|
||||||
|
|
||||||
// event.preventDefault() will destroy the guest page.
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always disable Node.js integration for all webviews
|
|
||||||
webPreferences.nodeIntegration = false;
|
|
||||||
})
|
|
||||||
.setWindowOpenHandler((details) => {
|
|
||||||
openBrowser(details.url).catch(error => {
|
|
||||||
logger.error("[WINDOW-MANAGER]: failed to open browser", { error });
|
|
||||||
});
|
|
||||||
|
|
||||||
return { action: "deny" };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (showSplash) await this.showSplash();
|
|
||||||
logger.info(`[WINDOW-MANAGER]: Loading Main window from url: ${this.mainContentUrl} ...`);
|
|
||||||
await this.mainWindow.loadURL(this.mainContentUrl);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("Loading main window failed", { error });
|
|
||||||
dialog.showErrorBox("ERROR!", error.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bindEvents() {
|
|
||||||
// track visible cluster from ui
|
|
||||||
ipcMainOn(IpcRendererNavigationEvents.CLUSTER_VIEW_CURRENT_ID, (event, clusterId: ClusterId) => {
|
|
||||||
this.activeClusterId = clusterId;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async ensureMainWindow(showSplash = true): Promise<BrowserWindow> {
|
|
||||||
// This needs to be ready to hear the IPC message before the window is loaded
|
|
||||||
let viewHasLoaded = Promise.resolve();
|
|
||||||
|
|
||||||
if (!this.mainWindow) {
|
|
||||||
viewHasLoaded = new Promise<void>(resolve => {
|
|
||||||
ipcMain.once(bundledExtensionsLoaded, () => resolve());
|
|
||||||
});
|
|
||||||
await this.initMainWindow(showSplash);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await viewHasLoaded;
|
|
||||||
await delay(50); // wait just a bit longer to let the first round of rendering happen
|
|
||||||
logger.info("[WINDOW-MANAGER]: Main window has reported that it has loaded");
|
|
||||||
|
|
||||||
this.mainWindow.show();
|
|
||||||
this.splashWindow?.close();
|
|
||||||
this.splashWindow = undefined;
|
|
||||||
setTimeout(() => {
|
|
||||||
appEventBus.emit({ name: "app", action: "start" });
|
|
||||||
}, 1000);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(`Showing main window failed: ${error.stack || error}`);
|
|
||||||
dialog.showErrorBox("ERROR!", error.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.mainWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendToView({ channel, frameInfo, data = [] }: SendToViewArgs) {
|
|
||||||
if (frameInfo) {
|
|
||||||
this.mainWindow.webContents.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...data);
|
|
||||||
} else {
|
|
||||||
this.mainWindow.webContents.send(channel, ...data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async navigateExtension(extId: string, pageId?: string, params?: Record<string, any>, frameId?: number) {
|
|
||||||
await this.ensureMainWindow();
|
|
||||||
|
|
||||||
const frameInfo = iter.find(clusterFrameMap.values(), frameInfo => frameInfo.frameId === frameId);
|
|
||||||
|
|
||||||
this.sendToView({
|
|
||||||
channel: "extension:navigate",
|
|
||||||
frameInfo,
|
|
||||||
data: [extId, pageId, params],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async navigate(url: string, frameId?: number) {
|
|
||||||
await this.ensureMainWindow();
|
|
||||||
|
|
||||||
this.navigateSync(url, frameId);
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateSync(url: string, frameId?: number) {
|
|
||||||
const frameInfo = iter.find(clusterFrameMap.values(), frameInfo => frameInfo.frameId === frameId);
|
|
||||||
const channel = frameInfo
|
|
||||||
? IpcRendererNavigationEvents.NAVIGATE_IN_CLUSTER
|
|
||||||
: IpcRendererNavigationEvents.NAVIGATE_IN_APP;
|
|
||||||
|
|
||||||
this.sendToView({
|
|
||||||
channel,
|
|
||||||
frameInfo,
|
|
||||||
data: [url],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
reload() {
|
|
||||||
const frameInfo = clusterFrameMap.get(this.activeClusterId);
|
|
||||||
|
|
||||||
if (frameInfo) {
|
|
||||||
this.sendToView({ channel: IpcRendererNavigationEvents.RELOAD_PAGE, frameInfo });
|
|
||||||
} else {
|
|
||||||
webContents.getAllWebContents().filter(wc => wc.getType() === "window").forEach(wc => {
|
|
||||||
wc.reload();
|
|
||||||
wc.clearHistory();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async showSplash() {
|
|
||||||
if (!this.splashWindow) {
|
|
||||||
this.splashWindow = new BrowserWindow({
|
|
||||||
width: 500,
|
|
||||||
height: 300,
|
|
||||||
backgroundColor: "#1e2124",
|
|
||||||
center: true,
|
|
||||||
frame: false,
|
|
||||||
resizable: false,
|
|
||||||
show: false,
|
|
||||||
webPreferences: {
|
|
||||||
nodeIntegration: true,
|
|
||||||
contextIsolation: false,
|
|
||||||
nodeIntegrationInSubFrames: true,
|
|
||||||
nativeWindowOpen: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await this.splashWindow.loadURL("static://splash.html");
|
|
||||||
}
|
|
||||||
this.splashWindow.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
hide() {
|
|
||||||
if (isHideable(this.mainWindow)) {
|
|
||||||
this.mainWindow.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isHideable(this.splashWindow)) {
|
|
||||||
this.splashWindow.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy() {
|
|
||||||
this.mainWindow.destroy();
|
|
||||||
this.splashWindow.destroy();
|
|
||||||
this.mainWindow = null;
|
|
||||||
this.splashWindow = null;
|
|
||||||
Object.entries(this.disposers).forEach(([name, dispose]) => {
|
|
||||||
dispose();
|
|
||||||
delete this.disposers[name];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -36,6 +36,7 @@ import hotbarStoreInjectable from "../common/hotbar-store.injectable";
|
|||||||
import themeStoreInjectable from "./theme-store.injectable";
|
import themeStoreInjectable from "./theme-store.injectable";
|
||||||
import apiManagerInjectable from "./components/kube-object-menu/dependencies/api-manager.injectable";
|
import apiManagerInjectable from "./components/kube-object-menu/dependencies/api-manager.injectable";
|
||||||
import { ApiManager } from "../common/k8s-api/api-manager";
|
import { ApiManager } from "../common/k8s-api/api-manager";
|
||||||
|
import lensResourcesDirInjectable from "../common/vars/lens-resources-dir.injectable";
|
||||||
|
|
||||||
export const getDiForUnitTesting = (
|
export const getDiForUnitTesting = (
|
||||||
{ doGeneralOverrides } = { doGeneralOverrides: false },
|
{ doGeneralOverrides } = { doGeneralOverrides: false },
|
||||||
@ -63,6 +64,8 @@ export const getDiForUnitTesting = (
|
|||||||
di.override(getAbsolutePathInjectable, () => getAbsolutePathFake);
|
di.override(getAbsolutePathInjectable, () => getAbsolutePathFake);
|
||||||
di.override(joinPathsInjectable, () => joinPathsFake);
|
di.override(joinPathsInjectable, () => joinPathsFake);
|
||||||
|
|
||||||
|
di.override(lensResourcesDirInjectable, () => "/irrelevant");
|
||||||
|
|
||||||
// eslint-disable-next-line unused-imports/no-unused-vars-ts
|
// eslint-disable-next-line unused-imports/no-unused-vars-ts
|
||||||
di.override(extensionsStoreInjectable, () => ({ isEnabled: ({ id, isBundled }) => false }) as ExtensionsStore);
|
di.override(extensionsStoreInjectable, () => ({ isEnabled: ({ id, isBundled }) => false }) as ExtensionsStore);
|
||||||
|
|
||||||
|
|||||||
@ -8,9 +8,9 @@ import getValueFromRegisteredChannelInjectable from "../renderer/app-paths/get-v
|
|||||||
import registerChannelInjectable from "../main/app-paths/register-channel/register-channel.injectable";
|
import registerChannelInjectable from "../main/app-paths/register-channel/register-channel.injectable";
|
||||||
import asyncFn from "@async-fn/jest";
|
import asyncFn from "@async-fn/jest";
|
||||||
import registerIpcChannelListenerInjectable from "../renderer/app-paths/get-value-from-registered-channel/register-ipc-channel-listener.injectable";
|
import registerIpcChannelListenerInjectable from "../renderer/app-paths/get-value-from-registered-channel/register-ipc-channel-listener.injectable";
|
||||||
import windowManagerInjectable from "../main/window-manager.injectable";
|
import type { SendToViewArgs } from "../main/start-main-application/lens-window/application-window/lens-window-injection-token";
|
||||||
import type { SendToViewArgs, WindowManager } from "../main/window-manager";
|
import sendToChannelInElectronBrowserWindowInjectable from "../main/start-main-application/lens-window/application-window/send-to-channel-in-electron-browser-window.injectable";
|
||||||
import { appNavigationIpcChannel } from "../common/front-end-routing/navigation-ipc-channel";
|
|
||||||
|
|
||||||
export const overrideIpcBridge = ({
|
export const overrideIpcBridge = ({
|
||||||
rendererDi,
|
rendererDi,
|
||||||
@ -68,7 +68,10 @@ export const overrideIpcBridge = ({
|
|||||||
mainIpcRegistrations.set(channel, callback);
|
mainIpcRegistrations.set(channel, callback);
|
||||||
});
|
});
|
||||||
|
|
||||||
const rendererIpcFakeHandles = new Map<string, ((...args: any[]) => void)[]>();
|
const rendererIpcFakeHandles = new Map<
|
||||||
|
string,
|
||||||
|
((...args: any[]) => void)[]
|
||||||
|
>();
|
||||||
|
|
||||||
rendererDi.override(
|
rendererDi.override(
|
||||||
registerIpcChannelListenerInjectable,
|
registerIpcChannelListenerInjectable,
|
||||||
@ -81,21 +84,14 @@ export const overrideIpcBridge = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
mainDi.override(
|
mainDi.override(
|
||||||
windowManagerInjectable,
|
sendToChannelInElectronBrowserWindowInjectable,
|
||||||
() =>
|
() =>
|
||||||
({
|
(browserWindow, { channel: channelName, data }: SendToViewArgs) => {
|
||||||
ensureMainWindow: () => Promise.resolve(),
|
|
||||||
|
|
||||||
sendToView: ({ channel: channelName, data }: SendToViewArgs) => {
|
|
||||||
const handles = rendererIpcFakeHandles.get(channelName);
|
const handles = rendererIpcFakeHandles.get(channelName);
|
||||||
|
|
||||||
handles.forEach(handle => handle(...data));
|
handles.forEach((handle) => handle(...data));
|
||||||
},
|
|
||||||
|
|
||||||
navigateSync(url: string) {
|
return Promise.resolve();
|
||||||
this.sendToView({ channel: appNavigationIpcChannel.name, data: [url] });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
} as unknown as WindowManager),
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user