mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Restructure to monorepo (#6907)
* wip: restructure to monorepo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor create-release-pr to a package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * github workflow fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix typo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * add webpack-env types to core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix github workflows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor/fix integration tests Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * lint fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * yarn run dev Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * eslint settings for vscode Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * move templates to right package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * open-lens build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * integration test fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix nx task dependencies Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * use bash shell for unit tests in test workflow Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix test:unit for windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix build:app on windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove ELECTRON_BUILDER_EXTRA_ARGS Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * sync src/ from master Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove Makefile from core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
1 parent
0066ca4ea2
commit
2657df2293
3321 files changed
+28699
-11447
No files matched your search
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 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 { Menu, Tray } from "electron";
|
||||
import showApplicationWindowInjectable from "../../start-main-application/lens-window/show-application-window.injectable";
|
||||
import isWindowsInjectable from "../../../common/vars/is-windows.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import { convertToElectronMenuTemplate } from "../reactive-tray-menu-items/converters";
|
||||
import trayIconInjectable from "../menu-icon/tray-icon.injectable";
|
||||
import applicationDescriptionInjectable from "../../../common/vars/application-description.injectable";
|
||||
|
||||
const TRAY_LOG_PREFIX = "[TRAY]";
|
||||
|
||||
export interface MinimalTrayMenuItem {
|
||||
id: string;
|
||||
parentId: string | null;
|
||||
enabled: boolean;
|
||||
label?: string;
|
||||
click?: () => Promise<void> | void;
|
||||
tooltip?: string;
|
||||
separator?: boolean;
|
||||
}
|
||||
|
||||
export interface ElectronTray {
|
||||
start(): void;
|
||||
stop(): void;
|
||||
setMenuItems(menuItems: MinimalTrayMenuItem[]): void;
|
||||
setIconPath(iconPath: string): void;
|
||||
}
|
||||
|
||||
const electronTrayInjectable = getInjectable({
|
||||
id: "electron-tray",
|
||||
|
||||
instantiate: (di): ElectronTray => {
|
||||
const applicationDescription = di.inject(applicationDescriptionInjectable);
|
||||
const showApplicationWindow = di.inject(showApplicationWindowInjectable);
|
||||
const isWindows = di.inject(isWindowsInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
const trayIcon = di.inject(trayIconInjectable);
|
||||
|
||||
let tray: Tray;
|
||||
|
||||
return {
|
||||
start: () => {
|
||||
tray = new Tray(trayIcon.get().iconPath);
|
||||
|
||||
tray.setToolTip(applicationDescription);
|
||||
tray.setIgnoreDoubleClickEvents(true);
|
||||
|
||||
if (isWindows) {
|
||||
tray.on("click", () => {
|
||||
showApplicationWindow()
|
||||
.catch(error => logger.error(`${TRAY_LOG_PREFIX}: Failed to open lens`, { error }));
|
||||
});
|
||||
}
|
||||
},
|
||||
stop: () => {
|
||||
tray.destroy();
|
||||
},
|
||||
setMenuItems: (menuItems) => {
|
||||
const template = convertToElectronMenuTemplate(menuItems);
|
||||
const menu = Menu.buildFromTemplate(template);
|
||||
|
||||
tray.setContextMenu(menu);
|
||||
},
|
||||
setIconPath: (iconPath) => {
|
||||
tray.setImage(iconPath);
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default electronTrayInjectable;
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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 { onLoadOfApplicationInjectionToken } from "../../start-main-application/runnable-tokens/on-load-of-application-injection-token";
|
||||
import electronTrayInjectable from "./electron-tray.injectable";
|
||||
|
||||
const startTrayInjectable = getInjectable({
|
||||
id: "start-tray",
|
||||
|
||||
instantiate: (di) => {
|
||||
const electronTray = di.inject(electronTrayInjectable);
|
||||
|
||||
return {
|
||||
id: "start-tray",
|
||||
run: () => {
|
||||
electronTray.start();
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: onLoadOfApplicationInjectionToken,
|
||||
});
|
||||
|
||||
export default startTrayInjectable;
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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 electronTrayInjectable from "./electron-tray.injectable";
|
||||
import { beforeQuitOfBackEndInjectionToken } from "../../start-main-application/runnable-tokens/before-quit-of-back-end-injection-token";
|
||||
import stopReactiveTrayMenuItemsInjectable from "../reactive-tray-menu-items/stop-reactive-tray-menu-items.injectable";
|
||||
|
||||
const stopTrayInjectable = getInjectable({
|
||||
id: "stop-tray",
|
||||
|
||||
instantiate: (di) => {
|
||||
const electronTray = di.inject(electronTrayInjectable);
|
||||
|
||||
return {
|
||||
id: "stop-tray",
|
||||
run: () => void electronTray.stop(),
|
||||
runAfter: di.inject(stopReactiveTrayMenuItemsInjectable),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: beforeQuitOfBackEndInjectionToken,
|
||||
});
|
||||
|
||||
export default stopTrayInjectable;
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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 staticFilesDirectoryInjectable from "../../../common/vars/static-files-directory.injectable";
|
||||
import isMacInjectable from "../../../common/vars/is-mac.injectable";
|
||||
import { camelCase, flow, upperFirst } from "lodash/fp";
|
||||
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
||||
const upperCamelCase = flow(camelCase, upperFirst);
|
||||
|
||||
const getTrayIconPathInjectable = getInjectable({
|
||||
id: "get-tray-icon-path",
|
||||
|
||||
instantiate: (di) => {
|
||||
const joinPaths = di.inject(joinPathsInjectable);
|
||||
const staticFilesDirectory = di.inject(staticFilesDirectoryInjectable);
|
||||
const isMac = di.inject(isMacInjectable);
|
||||
|
||||
const baseIconDirectory = joinPaths(
|
||||
staticFilesDirectory,
|
||||
"build/tray",
|
||||
);
|
||||
|
||||
const fileSuffix = isMac ? "Template.png" : ".png";
|
||||
|
||||
return (name: string) => joinPaths(
|
||||
baseIconDirectory,
|
||||
`trayIcon${upperCamelCase(name)}${fileSuffix}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default getTrayIconPathInjectable;
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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 { trayIconInjectionToken } from "./tray-icon-injection-token";
|
||||
import getTrayIconPathInjectable from "./get-tray-icon-path.injectable";
|
||||
|
||||
const normalTrayIconInjectable = getInjectable({
|
||||
id: "normal-icon",
|
||||
|
||||
instantiate: (di) => {
|
||||
const getTrayIconPath = di.inject(getTrayIconPathInjectable);
|
||||
|
||||
return {
|
||||
iconPath: getTrayIconPath(""),
|
||||
priority: 999,
|
||||
shouldBeShown: computed(() => true),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: trayIconInjectionToken,
|
||||
});
|
||||
|
||||
export default normalTrayIconInjectable;
|
||||
@@ -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 { reaction } from "mobx";
|
||||
import { getStartableStoppable } from "../../../common/utils/get-startable-stoppable";
|
||||
import electronTrayInjectable from "../electron-tray/electron-tray.injectable";
|
||||
import trayIconInjectable from "./tray-icon.injectable";
|
||||
|
||||
const reactiveTrayMenuIconInjectable = getInjectable({
|
||||
id: "reactive-tray-menu-icon",
|
||||
|
||||
instantiate: (di) => {
|
||||
const trayMenuIcon = di.inject(trayIconInjectable);
|
||||
const electronTray = di.inject(electronTrayInjectable);
|
||||
|
||||
return getStartableStoppable("reactive-tray-menu-icon", () => (
|
||||
reaction(
|
||||
() => trayMenuIcon.get(),
|
||||
icon => {
|
||||
electronTray.setIconPath(icon.iconPath);
|
||||
},
|
||||
{
|
||||
fireImmediately: true,
|
||||
},
|
||||
)
|
||||
));
|
||||
},
|
||||
});
|
||||
|
||||
export default reactiveTrayMenuIconInjectable;
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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 { onLoadOfApplicationInjectionToken } from "../../start-main-application/runnable-tokens/on-load-of-application-injection-token";
|
||||
import startTrayInjectable from "../electron-tray/start-tray.injectable";
|
||||
import reactiveTrayMenuIconInjectable from "./reactive.injectable";
|
||||
|
||||
const startReactiveTrayMenuIconInjectable = getInjectable({
|
||||
id: "start-reactive-tray-menu-icon",
|
||||
|
||||
instantiate: (di) => {
|
||||
const reactiveTrayMenuIcon = di.inject(reactiveTrayMenuIconInjectable);
|
||||
|
||||
return {
|
||||
id: "start-reactive-tray-menu-icon",
|
||||
run: () => {
|
||||
reactiveTrayMenuIcon.start();
|
||||
},
|
||||
|
||||
runAfter: di.inject(startTrayInjectable),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: onLoadOfApplicationInjectionToken,
|
||||
});
|
||||
|
||||
export default startReactiveTrayMenuIconInjectable;
|
||||
@@ -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 { beforeQuitOfBackEndInjectionToken } from "../../start-main-application/runnable-tokens/before-quit-of-back-end-injection-token";
|
||||
import reactiveTrayMenuIconInjectable from "./reactive.injectable";
|
||||
|
||||
const stopReactiveTrayMenuIconInjectable = getInjectable({
|
||||
id: "stop-reactive-tray-menu-icon",
|
||||
|
||||
instantiate: (di) => {
|
||||
const reactiveTrayMenuIcon = di.inject(reactiveTrayMenuIconInjectable);
|
||||
|
||||
return {
|
||||
id: "stop-reactive-tray-menu-icon",
|
||||
run: () => void reactiveTrayMenuIcon.stop(),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: beforeQuitOfBackEndInjectionToken,
|
||||
});
|
||||
|
||||
export default stopReactiveTrayMenuIconInjectable;
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* 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 { IComputedValue } from "mobx";
|
||||
|
||||
export interface TrayIcon {
|
||||
iconPath: string;
|
||||
priority: number;
|
||||
shouldBeShown: IComputedValue<boolean>;
|
||||
}
|
||||
|
||||
export const trayIconInjectionToken = getInjectionToken<TrayIcon>({
|
||||
id: "tray-icon-token",
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import { find, sortBy } from "lodash/fp";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import { trayIconInjectionToken } from "./tray-icon-injection-token";
|
||||
|
||||
const trayIconInjectable = getInjectable({
|
||||
id: "tray-icon",
|
||||
|
||||
instantiate: (di) => {
|
||||
const availableIcons = di.injectMany(trayIconInjectionToken);
|
||||
|
||||
return computed(() => {
|
||||
const mostPrioritizedIcon = pipeline(
|
||||
availableIcons,
|
||||
sortBy((icon) => icon.priority),
|
||||
find((icon) => icon.shouldBeShown.get()),
|
||||
);
|
||||
|
||||
if (!mostPrioritizedIcon) {
|
||||
throw new Error("There should always be tray icon which is shown.");
|
||||
}
|
||||
|
||||
return mostPrioritizedIcon;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default trayIconInjectable;
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { MinimalTrayMenuItem } from "../electron-tray/electron-tray.injectable";
|
||||
|
||||
export function convertToElectronMenuTemplate(trayMenuItems: MinimalTrayMenuItem[]): Electron.MenuItemConstructorOptions[] {
|
||||
const toTrayMenuOptions = (parentId: string | null) => (
|
||||
trayMenuItems
|
||||
.filter((item) => item.parentId === parentId)
|
||||
.map((trayMenuItem): Electron.MenuItemConstructorOptions => {
|
||||
if (trayMenuItem.separator) {
|
||||
return { id: trayMenuItem.id, type: "separator" };
|
||||
}
|
||||
|
||||
const childItems = toTrayMenuOptions(trayMenuItem.id);
|
||||
|
||||
return {
|
||||
id: trayMenuItem.id,
|
||||
label: trayMenuItem.label,
|
||||
enabled: trayMenuItem.enabled,
|
||||
toolTip: trayMenuItem.tooltip,
|
||||
|
||||
...(childItems.length === 0
|
||||
? {
|
||||
type: "normal",
|
||||
submenu: toTrayMenuOptions(trayMenuItem.id),
|
||||
click: trayMenuItem.click,
|
||||
}
|
||||
: {
|
||||
type: "submenu",
|
||||
submenu: toTrayMenuOptions(trayMenuItem.id),
|
||||
}),
|
||||
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
return toTrayMenuOptions(null);
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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 { getStartableStoppable } from "../../../common/utils/get-startable-stoppable";
|
||||
import { reaction } from "mobx";
|
||||
import type { MinimalTrayMenuItem } from "../electron-tray/electron-tray.injectable";
|
||||
import electronTrayInjectable from "../electron-tray/electron-tray.injectable";
|
||||
import trayMenuItemsInjectable from "../tray-menu-item/tray-menu-items.injectable";
|
||||
import type { TrayMenuItem } from "../tray-menu-item/tray-menu-item-injection-token";
|
||||
|
||||
const reactiveTrayMenuItemsInjectable = getInjectable({
|
||||
id: "reactive-tray-menu-items",
|
||||
|
||||
instantiate: (di) => {
|
||||
const electronTray = di.inject(electronTrayInjectable);
|
||||
const reactiveItems = di.inject(trayMenuItemsInjectable);
|
||||
|
||||
return getStartableStoppable("reactive-tray-menu-items", () =>
|
||||
reaction(
|
||||
() => reactiveItems.get().map(toNonReactiveItem),
|
||||
(nonReactiveItems) => electronTray.setMenuItems(nonReactiveItems),
|
||||
{
|
||||
fireImmediately: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default reactiveTrayMenuItemsInjectable;
|
||||
|
||||
const toNonReactiveItem = (item: TrayMenuItem): MinimalTrayMenuItem => ({
|
||||
id: item.id,
|
||||
parentId: item.parentId,
|
||||
click: item.click,
|
||||
tooltip: item.tooltip,
|
||||
separator: item.separator,
|
||||
enabled: item.enabled.get(),
|
||||
label: item.label?.get(),
|
||||
});
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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 reactiveTrayMenuItemsInjectable from "./reactive-tray-menu-items.injectable";
|
||||
import { onLoadOfApplicationInjectionToken } from "../../start-main-application/runnable-tokens/on-load-of-application-injection-token";
|
||||
import startTrayInjectable from "../electron-tray/start-tray.injectable";
|
||||
|
||||
const startReactiveTrayMenuItemsInjectable = getInjectable({
|
||||
id: "start-reactive-tray-menu-items",
|
||||
|
||||
instantiate: (di) => {
|
||||
const reactiveTrayMenuItems = di.inject(reactiveTrayMenuItemsInjectable);
|
||||
|
||||
return {
|
||||
id: "start-reactive-tray-menu-items",
|
||||
run: () => {
|
||||
reactiveTrayMenuItems.start();
|
||||
},
|
||||
|
||||
runAfter: di.inject(startTrayInjectable),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: onLoadOfApplicationInjectionToken,
|
||||
});
|
||||
|
||||
export default startReactiveTrayMenuItemsInjectable;
|
||||
+24
@@ -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 reactiveTrayMenuItemsInjectable from "./reactive-tray-menu-items.injectable";
|
||||
import { beforeQuitOfBackEndInjectionToken } from "../../start-main-application/runnable-tokens/before-quit-of-back-end-injection-token";
|
||||
|
||||
const stopReactiveTrayMenuItemsInjectable = getInjectable({
|
||||
id: "stop-reactive-tray-menu-items",
|
||||
|
||||
instantiate: (di) => {
|
||||
const reactiveTrayMenuItems = di.inject(reactiveTrayMenuItemsInjectable);
|
||||
|
||||
return {
|
||||
id: "stop-reactive-tray-menu-items",
|
||||
run: () => void reactiveTrayMenuItems.stop(),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: beforeQuitOfBackEndInjectionToken,
|
||||
});
|
||||
|
||||
export default stopReactiveTrayMenuItemsInjectable;
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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 showApplicationWindowInjectable from "../../../start-main-application/lens-window/show-application-window.injectable";
|
||||
import showAboutInjectable from "../../../../features/application-menu/main/menu-items/special-menu-for-mac-application/show-about-application/show-about.injectable";
|
||||
import { trayMenuItemInjectionToken } from "../tray-menu-item-injection-token";
|
||||
import { computed } from "mobx";
|
||||
import withErrorLoggingInjectable from "../../../../common/utils/with-error-logging/with-error-logging.injectable";
|
||||
import { withErrorSuppression } from "../../../../common/utils/with-error-suppression/with-error-suppression";
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import productNameInjectable from "../../../../common/vars/product-name.injectable";
|
||||
|
||||
const aboutAppTrayItemInjectable = getInjectable({
|
||||
id: "about-app-tray-item",
|
||||
|
||||
instantiate: (di) => {
|
||||
const productName = di.inject(productNameInjectable);
|
||||
const showApplicationWindow = di.inject(showApplicationWindowInjectable);
|
||||
const showAbout = di.inject(showAboutInjectable);
|
||||
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
|
||||
|
||||
return {
|
||||
id: "about-app",
|
||||
parentId: null,
|
||||
orderNumber: 140,
|
||||
label: computed(() => `About ${productName}`),
|
||||
enabled: computed(() => true),
|
||||
visible: computed(() => true),
|
||||
|
||||
click: pipeline(
|
||||
async () => {
|
||||
await showApplicationWindow();
|
||||
showAbout();
|
||||
},
|
||||
withErrorLoggingFor(() => "[TRAY]: Opening of show about failed."),
|
||||
withErrorSuppression,
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: trayMenuItemInjectionToken,
|
||||
});
|
||||
|
||||
export default aboutAppTrayItemInjectable;
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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 { trayMenuItemInjectionToken } from "../tray-menu-item-injection-token";
|
||||
import showApplicationWindowInjectable from "../../../start-main-application/lens-window/show-application-window.injectable";
|
||||
import { computed } from "mobx";
|
||||
import withErrorLoggingInjectable from "../../../../common/utils/with-error-logging/with-error-logging.injectable";
|
||||
import { withErrorSuppression } from "../../../../common/utils/with-error-suppression/with-error-suppression";
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import productNameInjectable from "../../../../common/vars/product-name.injectable";
|
||||
|
||||
const openAppTrayItemInjectable = getInjectable({
|
||||
id: "open-app-tray-item",
|
||||
|
||||
instantiate: (di) => {
|
||||
const productName = di.inject(productNameInjectable);
|
||||
const showApplicationWindow = di.inject(showApplicationWindowInjectable);
|
||||
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
|
||||
|
||||
return {
|
||||
id: "open-app",
|
||||
parentId: null,
|
||||
label: computed(() => `Open ${productName}`),
|
||||
orderNumber: 10,
|
||||
enabled: computed(() => true),
|
||||
visible: computed(() => true),
|
||||
|
||||
click: pipeline(
|
||||
showApplicationWindow,
|
||||
withErrorLoggingFor(() => "[TRAY]: Opening of application window failed."),
|
||||
withErrorSuppression,
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: trayMenuItemInjectionToken,
|
||||
});
|
||||
|
||||
export default openAppTrayItemInjectable;
|
||||
+24
@@ -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 { trayMenuItemInjectionToken } from "../tray-menu-item-injection-token";
|
||||
import { computed } from "mobx";
|
||||
|
||||
const quitAppSeparatorTrayItemInjectable = getInjectable({
|
||||
id: "quit-app-separator-tray-item",
|
||||
|
||||
instantiate: () => ({
|
||||
id: "quit-app-separator",
|
||||
parentId: null,
|
||||
orderNumber: 149,
|
||||
enabled: computed(() => true),
|
||||
visible: computed(() => true),
|
||||
separator: true,
|
||||
}),
|
||||
|
||||
injectionToken: trayMenuItemInjectionToken,
|
||||
});
|
||||
|
||||
export default quitAppSeparatorTrayItemInjectable;
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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 { trayMenuItemInjectionToken } from "../tray-menu-item-injection-token";
|
||||
import { computed } from "mobx";
|
||||
import stopServicesAndExitAppInjectable from "../../../stop-services-and-exit-app.injectable";
|
||||
import { withErrorSuppression } from "../../../../common/utils/with-error-suppression/with-error-suppression";
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import withErrorLoggingInjectable from "../../../../common/utils/with-error-logging/with-error-logging.injectable";
|
||||
|
||||
const quitAppTrayItemInjectable = getInjectable({
|
||||
id: "quit-app-tray-item",
|
||||
|
||||
instantiate: (di) => {
|
||||
const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable);
|
||||
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
|
||||
|
||||
return {
|
||||
id: "quit-app",
|
||||
parentId: null,
|
||||
orderNumber: 150,
|
||||
label: computed(() => "Quit App"),
|
||||
enabled: computed(() => true),
|
||||
visible: computed(() => true),
|
||||
|
||||
click: pipeline(
|
||||
stopServicesAndExitApp,
|
||||
|
||||
withErrorLoggingFor(() => "[TRAY]: Quitting application failed."),
|
||||
|
||||
// TODO: Find out how to improve typing so that instead of
|
||||
// x => withErrorSuppression(x) there could only be withErrorSuppression
|
||||
(x) => withErrorSuppression(x),
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: trayMenuItemInjectionToken,
|
||||
});
|
||||
|
||||
export default quitAppTrayItemInjectable;
|
||||
@@ -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 { IComputedValue } from "mobx";
|
||||
|
||||
export interface TrayMenuItem {
|
||||
id: string;
|
||||
parentId: string | null;
|
||||
orderNumber: number;
|
||||
enabled: IComputedValue<boolean>;
|
||||
visible: IComputedValue<boolean>;
|
||||
|
||||
label?: IComputedValue<string>;
|
||||
click?: () => Promise<void> | void;
|
||||
tooltip?: string;
|
||||
separator?: boolean;
|
||||
}
|
||||
|
||||
export const trayMenuItemInjectionToken = getInjectionToken<TrayMenuItem>({
|
||||
id: "tray-menu-item",
|
||||
});
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import type { Injectable } from "@ogre-tools/injectable";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token";
|
||||
import type { LensMainExtension } from "../../../extensions/lens-main-extension";
|
||||
import type { TrayMenuItem } from "./tray-menu-item-injection-token";
|
||||
import { trayMenuItemInjectionToken } from "./tray-menu-item-injection-token";
|
||||
import type { TrayMenuRegistration } from "../tray-menu-registration";
|
||||
import { withErrorSuppression } from "../../../common/utils/with-error-suppression/with-error-suppression";
|
||||
import type { WithErrorLoggingFor } from "../../../common/utils/with-error-logging/with-error-logging.injectable";
|
||||
import withErrorLoggingInjectable from "../../../common/utils/with-error-logging/with-error-logging.injectable";
|
||||
import getRandomIdInjectable from "../../../common/utils/get-random-id.injectable";
|
||||
import { isBoolean, isString } from "../../../common/utils";
|
||||
|
||||
const trayMenuItemRegistratorInjectable = getInjectable({
|
||||
id: "tray-menu-item-registrator",
|
||||
|
||||
instantiate: (di) => (extension) => {
|
||||
const mainExtension = extension as LensMainExtension;
|
||||
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
|
||||
const getRandomId = di.inject(getRandomIdInjectable);
|
||||
|
||||
return computed(() => {
|
||||
const trayMenus = Array.isArray(mainExtension.trayMenus) ? mainExtension.trayMenus : mainExtension.trayMenus.get();
|
||||
|
||||
return trayMenus.flatMap(
|
||||
toItemInjectablesFor(mainExtension, withErrorLoggingFor, getRandomId),
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
injectionToken: extensionRegistratorInjectionToken,
|
||||
});
|
||||
|
||||
export default trayMenuItemRegistratorInjectable;
|
||||
|
||||
const toItemInjectablesFor = (extension: LensMainExtension, withErrorLoggingFor: WithErrorLoggingFor, getRandomId: () => string) => {
|
||||
const _toItemInjectables = (parentId: string | null) => (registration: TrayMenuRegistration): Injectable<TrayMenuItem, TrayMenuItem, void>[] => {
|
||||
const trayItemId = registration.id || getRandomId();
|
||||
const id = `${trayItemId}-tray-menu-item-for-extension-${extension.sanitizedExtensionId}`;
|
||||
|
||||
const parentInjectable = getInjectable({
|
||||
id,
|
||||
|
||||
instantiate: () => ({
|
||||
id,
|
||||
parentId,
|
||||
orderNumber: 100,
|
||||
|
||||
separator: registration.type === "separator",
|
||||
|
||||
label: computed(() => {
|
||||
if (!registration.label) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (isString(registration.label)) {
|
||||
return registration.label;
|
||||
}
|
||||
|
||||
return registration.label.get();
|
||||
}),
|
||||
|
||||
tooltip: registration.toolTip,
|
||||
|
||||
click: () => {
|
||||
const decorated = pipeline(
|
||||
registration.click || (() => {}),
|
||||
|
||||
withErrorLoggingFor(
|
||||
() =>
|
||||
`[TRAY]: Clicking of tray item "${trayItemId}" from extension "${extension.sanitizedExtensionId}" failed.`,
|
||||
),
|
||||
|
||||
// TODO: Find out how to improve typing so that instead of
|
||||
// x => withErrorSuppression(x) there could only be withErrorSuppression
|
||||
(x) => withErrorSuppression(x),
|
||||
);
|
||||
|
||||
return decorated(registration);
|
||||
},
|
||||
|
||||
enabled: computed(() => {
|
||||
if (registration.enabled === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isBoolean(registration.enabled)) {
|
||||
return registration.enabled;
|
||||
}
|
||||
|
||||
return registration.enabled.get();
|
||||
}),
|
||||
|
||||
visible: computed(() => {
|
||||
if (!registration.visible) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return registration.visible.get();
|
||||
}),
|
||||
}),
|
||||
|
||||
injectionToken: trayMenuItemInjectionToken,
|
||||
});
|
||||
|
||||
const childMenuItems = registration.submenu || [];
|
||||
|
||||
const childInjectables = childMenuItems.flatMap(_toItemInjectables(id));
|
||||
|
||||
return [
|
||||
parentInjectable,
|
||||
...childInjectables,
|
||||
];
|
||||
};
|
||||
|
||||
return _toItemInjectables(null);
|
||||
};
|
||||
@@ -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 { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||
import { computed } from "mobx";
|
||||
import { trayMenuItemInjectionToken } from "./tray-menu-item-injection-token";
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import { filter, sortBy } from "lodash/fp";
|
||||
|
||||
const trayMenuItemsInjectable = getInjectable({
|
||||
id: "tray-menu-items",
|
||||
|
||||
instantiate: (di) => {
|
||||
const computedInjectMany = di.inject(
|
||||
computedInjectManyInjectable,
|
||||
);
|
||||
|
||||
const reactiveMenuItems = computedInjectMany(trayMenuItemInjectionToken);
|
||||
|
||||
return computed(() =>
|
||||
pipeline(
|
||||
reactiveMenuItems.get(),
|
||||
filter((item) => item.visible.get()),
|
||||
(items) => sortBy("orderNumber", items),
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default trayMenuItemsInjectable;
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { IComputedValue } from "mobx";
|
||||
|
||||
export interface TrayMenuRegistration {
|
||||
label?: string | IComputedValue<string>;
|
||||
click?: (menuItem: TrayMenuRegistration) => void;
|
||||
id?: string;
|
||||
type?: "normal" | "separator" | "submenu";
|
||||
toolTip?: string;
|
||||
enabled?: boolean | IComputedValue<boolean>;
|
||||
submenu?: TrayMenuRegistration[];
|
||||
visible?: IComputedValue<boolean>;
|
||||
}
|
||||
Reference in new issue
Block a user