mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Make tray items comply with Open Closed Principle
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
6d5e5a930e
commit
bc979b72e6
14
src/main/check-for-updates.injectable.ts
Normal file
14
src/main/check-for-updates.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 { checkForUpdates } from "./app-updater";
|
||||||
|
|
||||||
|
const checkForUpdatesInjectable = getInjectable({
|
||||||
|
id: "check-for-updates",
|
||||||
|
instantiate: () => checkForUpdates,
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default checkForUpdatesInjectable;
|
||||||
@ -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 productNameInjectable from "../../../app-paths/app-name/product-name.injectable";
|
||||||
|
import showApplicationWindowInjectable from "../../../start-main-application/lens-window/show-application-window.injectable";
|
||||||
|
import showAboutInjectable from "../../../menu/show-about.injectable";
|
||||||
|
import { trayMenuItemInjectionToken } from "../tray-menu-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: "about-app",
|
||||||
|
parentId: null,
|
||||||
|
orderNumber: 140,
|
||||||
|
label: `About ${productName}`,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
visible: computed(() => true),
|
||||||
|
|
||||||
|
click: async () => {
|
||||||
|
await showApplicationWindow();
|
||||||
|
|
||||||
|
await showAbout();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: trayMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default aboutAppTrayItemInjectable;
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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 showApplicationWindowInjectable from "../../../start-main-application/lens-window/show-application-window.injectable";
|
||||||
|
import checkForUpdatesInjectable from "../../../check-for-updates.injectable";
|
||||||
|
import isAutoUpdateEnabledInjectable from "../../../is-auto-update-enabled.injectable";
|
||||||
|
|
||||||
|
const checkForUpdatesTrayItemInjectable = getInjectable({
|
||||||
|
id: "check-for-updates-tray-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const showApplicationWindow = di.inject(showApplicationWindowInjectable);
|
||||||
|
const checkForUpdates = di.inject(checkForUpdatesInjectable);
|
||||||
|
const isAutoUpdateEnabled = di.inject(isAutoUpdateEnabledInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: "check-for-updates",
|
||||||
|
parentId: null,
|
||||||
|
orderNumber: 30,
|
||||||
|
label: "Check for updates",
|
||||||
|
enabled: computed(() => true),
|
||||||
|
visible: computed(() => isAutoUpdateEnabled()),
|
||||||
|
|
||||||
|
click: async () => {
|
||||||
|
await checkForUpdates();
|
||||||
|
|
||||||
|
await showApplicationWindow();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default checkForUpdatesTrayItemInjectable;
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* 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 productNameInjectable from "../../../app-paths/app-name/product-name.injectable";
|
||||||
|
import showApplicationWindowInjectable from "../../../start-main-application/lens-window/show-application-window.injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
const openAppTrayItemInjectable = getInjectable({
|
||||||
|
id: "open-app-tray-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const productName = di.inject(productNameInjectable);
|
||||||
|
const showApplicationWindow = di.inject(showApplicationWindowInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: "open-app",
|
||||||
|
parentId: null,
|
||||||
|
label: `Open ${productName}`,
|
||||||
|
orderNumber: 10,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
visible: computed(() => true),
|
||||||
|
|
||||||
|
click: async () => {
|
||||||
|
await showApplicationWindow();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: trayMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default openAppTrayItemInjectable;
|
||||||
@ -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 } from "@ogre-tools/injectable";
|
||||||
|
import { trayMenuItemInjectionToken } from "../tray-menu-item-injection-token";
|
||||||
|
import navigateToPreferencesInjectable from "../../../../common/front-end-routing/routes/preferences/navigate-to-preferences.injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
const openPreferencesTrayItemInjectable = getInjectable({
|
||||||
|
id: "open-preferences-tray-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const navigateToPreferences = di.inject(navigateToPreferencesInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: "open-preferences",
|
||||||
|
parentId: null,
|
||||||
|
label: "Preferences",
|
||||||
|
orderNumber: 20,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
visible: computed(() => true),
|
||||||
|
|
||||||
|
click: () => {
|
||||||
|
navigateToPreferences();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: trayMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default openPreferencesTrayItemInjectable;
|
||||||
@ -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-sepator",
|
||||||
|
parentId: null,
|
||||||
|
orderNumber: 149,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
visible: computed(() => true),
|
||||||
|
separator: true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: trayMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default quitAppSeparatorTrayItemInjectable;
|
||||||
@ -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 { trayMenuItemInjectionToken } from "../tray-menu-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import stopServicesAndExitAppInjectable from "../../../stop-services-and-exit-app.injectable";
|
||||||
|
|
||||||
|
const quitAppTrayItemInjectable = getInjectable({
|
||||||
|
id: "quit-app-tray-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: "quit-app",
|
||||||
|
parentId: null,
|
||||||
|
orderNumber: 150,
|
||||||
|
label: "Quit App",
|
||||||
|
enabled: computed(() => true),
|
||||||
|
visible: computed(() => true),
|
||||||
|
separated: true,
|
||||||
|
|
||||||
|
click: () => {
|
||||||
|
stopServicesAndExitApp();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: trayMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default quitAppTrayItemInjectable;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* 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";
|
||||||
|
import type { LensMainExtension } from "../../../extensions/lens-main-extension";
|
||||||
|
|
||||||
|
export interface TrayMenuItem {
|
||||||
|
id: string;
|
||||||
|
parentId: string;
|
||||||
|
orderNumber: number;
|
||||||
|
enabled: IComputedValue<boolean>;
|
||||||
|
visible: IComputedValue<boolean>;
|
||||||
|
|
||||||
|
label?: string;
|
||||||
|
click?: () => Promise<void> | void;
|
||||||
|
tooltip?: string;
|
||||||
|
separator?: boolean;
|
||||||
|
extension?: LensMainExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const trayMenuItemInjectionToken = getInjectionToken<TrayMenuItem>({
|
||||||
|
id: "tray-menu-item",
|
||||||
|
});
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* 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 { flatMap, kebabCase } from "lodash/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";
|
||||||
|
|
||||||
|
const trayMenuItemRegistratorInjectable = getInjectable({
|
||||||
|
id: "tray-menu-item-registrator",
|
||||||
|
|
||||||
|
instantiate: (di) => (extension: LensMainExtension, installationCounter) => {
|
||||||
|
pipeline(
|
||||||
|
extension.trayMenus,
|
||||||
|
|
||||||
|
flatMap(toItemInjectablesFor(extension, installationCounter)),
|
||||||
|
|
||||||
|
(injectables) => di.register(...injectables),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: extensionRegistratorInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default trayMenuItemRegistratorInjectable;
|
||||||
|
|
||||||
|
|
||||||
|
const toItemInjectablesFor = (extension: LensMainExtension, installationCounter: number) => {
|
||||||
|
const _toItemInjectables = (parentId: string | null) => (registration: TrayMenuRegistration): Injectable<TrayMenuItem, TrayMenuItem, void>[] => {
|
||||||
|
const trayItemId = registration.id || kebabCase(registration.label);
|
||||||
|
const id = `${trayItemId}-tray-menu-item-for-extension-${extension.sanitizedExtensionId}-instance-${installationCounter}`;
|
||||||
|
|
||||||
|
const parentInjectable = getInjectable({
|
||||||
|
id,
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
id,
|
||||||
|
parentId,
|
||||||
|
orderNumber: 100,
|
||||||
|
|
||||||
|
separator: registration.type === "separator",
|
||||||
|
|
||||||
|
label: registration.label,
|
||||||
|
tooltip: registration.toolTip,
|
||||||
|
|
||||||
|
click: () => {
|
||||||
|
registration.click?.(registration);
|
||||||
|
},
|
||||||
|
|
||||||
|
enabled: computed(() => registration.enabled),
|
||||||
|
visible: computed(() => true),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: trayMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const childMenuItems = registration.submenu || [];
|
||||||
|
|
||||||
|
const childInjectables = childMenuItems.flatMap(_toItemInjectables(id));
|
||||||
|
|
||||||
|
return [
|
||||||
|
parentInjectable,
|
||||||
|
...childInjectables,
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
return _toItemInjectables(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
49
src/main/tray/tray-menu-item/tray-menu-items.injectable.ts
Normal file
49
src/main/tray/tray-menu-item/tray-menu-items.injectable.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* 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 mainExtensionsInjectable from "../../../extensions/main-extensions.injectable";
|
||||||
|
import type { TrayMenuItem } from "./tray-menu-item-injection-token";
|
||||||
|
import { trayMenuItemInjectionToken } from "./tray-menu-item-injection-token";
|
||||||
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
|
import { filter, overSome, sortBy } from "lodash/fp";
|
||||||
|
import type { LensMainExtension } from "../../../extensions/lens-main-extension";
|
||||||
|
|
||||||
|
const trayMenuItemsInjectable = getInjectable({
|
||||||
|
id: "tray-menu-items",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const extensions = di.inject(mainExtensionsInjectable);
|
||||||
|
|
||||||
|
return computed(() => {
|
||||||
|
const enabledExtensions = extensions.get();
|
||||||
|
|
||||||
|
return pipeline(
|
||||||
|
di.injectMany(trayMenuItemInjectionToken),
|
||||||
|
|
||||||
|
filter((item) =>
|
||||||
|
overSome([
|
||||||
|
isNonExtensionItem,
|
||||||
|
isEnabledExtensionItemFor(enabledExtensions),
|
||||||
|
])(item),
|
||||||
|
),
|
||||||
|
|
||||||
|
filter(item => item.visible.get()),
|
||||||
|
items => sortBy("orderNumber", items),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const isNonExtensionItem = (item: TrayMenuItem) => !item.extension;
|
||||||
|
|
||||||
|
const isEnabledExtensionItemFor =
|
||||||
|
(enabledExtensions: LensMainExtension[]) => (item: TrayMenuItem) =>
|
||||||
|
!!enabledExtensions.find((extension) => extension === item.extension);
|
||||||
|
|
||||||
|
|
||||||
|
export default trayMenuItemsInjectable;
|
||||||
@ -4,13 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { initTray } from "./tray";
|
import { initTray } from "./tray";
|
||||||
import trayMenuItemsInjectable from "./tray-menu-items.injectable";
|
|
||||||
import navigateToPreferencesInjectable from "../../common/front-end-routing/routes/preferences/navigate-to-preferences.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 showAboutInjectable from "../menu/show-about.injectable";
|
|
||||||
import showApplicationWindowInjectable from "../start-main-application/lens-window/show-application-window.injectable";
|
import showApplicationWindowInjectable from "../start-main-application/lens-window/show-application-window.injectable";
|
||||||
|
import trayMenuItemsInjectable from "./tray-menu-item/tray-menu-items.injectable";
|
||||||
import trayIconPathInjectable from "./tray-icon-path.injectable";
|
import trayIconPathInjectable from "./tray-icon-path.injectable";
|
||||||
|
|
||||||
const trayInjectable = getInjectable({
|
const trayInjectable = getInjectable({
|
||||||
@ -18,21 +14,13 @@ const trayInjectable = getInjectable({
|
|||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const trayMenuItems = di.inject(trayMenuItemsInjectable);
|
const trayMenuItems = di.inject(trayMenuItemsInjectable);
|
||||||
const navigateToPreferences = di.inject(navigateToPreferencesInjectable);
|
|
||||||
const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable);
|
|
||||||
const isAutoUpdateEnabled = di.inject(isAutoUpdateEnabledInjectable);
|
|
||||||
const showApplicationWindow = di.inject(showApplicationWindowInjectable);
|
const showApplicationWindow = di.inject(showApplicationWindowInjectable);
|
||||||
const showAboutPopup = di.inject(showAboutInjectable);
|
|
||||||
const trayIconPath = di.inject(trayIconPathInjectable);
|
const trayIconPath = di.inject(trayIconPathInjectable);
|
||||||
|
|
||||||
return getStartableStoppable("build-of-tray", () =>
|
return getStartableStoppable("build-of-tray", () =>
|
||||||
initTray(
|
initTray(
|
||||||
trayMenuItems,
|
trayMenuItems,
|
||||||
navigateToPreferences,
|
|
||||||
stopServicesAndExitApp,
|
|
||||||
isAutoUpdateEnabled,
|
|
||||||
showApplicationWindow,
|
showApplicationWindow,
|
||||||
showAboutPopup,
|
|
||||||
trayIconPath,
|
trayIconPath,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -7,25 +7,22 @@ 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 { checkForUpdates } from "../app-updater";
|
|
||||||
import logger from "../logger";
|
import logger from "../logger";
|
||||||
import { isWindows, productName } from "../../common/vars";
|
import { isWindows } from "../../common/vars";
|
||||||
import type { Disposer } from "../../common/utils";
|
import type { Disposer } from "../../common/utils";
|
||||||
import { disposer, toJS } from "../../common/utils";
|
import { disposer } from "../../common/utils";
|
||||||
import type { TrayMenuRegistration } from "./tray-menu-registration";
|
import type { TrayMenuItem } from "./tray-menu-item/tray-menu-item-injection-token";
|
||||||
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
|
import { filter, isEmpty, map } from "lodash/fp";
|
||||||
|
|
||||||
const TRAY_LOG_PREFIX = "[TRAY]";
|
export const TRAY_LOG_PREFIX = "[TRAY]";
|
||||||
|
|
||||||
// note: instance of Tray should be saved somewhere, otherwise it disappears
|
// note: instance of Tray should be saved somewhere, otherwise it disappears
|
||||||
export let tray: Tray | null = null;
|
export let tray: Tray | null = null;
|
||||||
|
|
||||||
export function initTray(
|
export function initTray(
|
||||||
trayMenuItems: IComputedValue<TrayMenuRegistration[]>,
|
trayMenuItems: IComputedValue<TrayMenuItem[]>,
|
||||||
navigateToPreferences: () => void,
|
|
||||||
stopServicesAndExitApp: () => void,
|
|
||||||
isAutoUpdateEnabled: () => boolean,
|
|
||||||
showApplicationWindow: () => Promise<void>,
|
showApplicationWindow: () => Promise<void>,
|
||||||
showAbout: () => void,
|
|
||||||
trayIconPath: string,
|
trayIconPath: string,
|
||||||
): Disposer {
|
): Disposer {
|
||||||
tray = new Tray(trayIconPath);
|
tray = new Tray(trayIconPath);
|
||||||
@ -42,7 +39,9 @@ export function initTray(
|
|||||||
return disposer(
|
return disposer(
|
||||||
autorun(() => {
|
autorun(() => {
|
||||||
try {
|
try {
|
||||||
const menu = createTrayMenu(toJS(trayMenuItems.get()), navigateToPreferences, stopServicesAndExitApp, isAutoUpdateEnabled, showApplicationWindow, showAbout);
|
const options = toTrayMenuOptions(trayMenuItems.get());
|
||||||
|
|
||||||
|
const menu = Menu.buildFromTemplate(options);
|
||||||
|
|
||||||
tray?.setContextMenu(menu);
|
tray?.setContextMenu(menu);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -56,66 +55,52 @@ export function initTray(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMenuItemConstructorOptions(trayItem: TrayMenuRegistration): Electron.MenuItemConstructorOptions {
|
const toTrayMenuOptions = (trayMenuItems: TrayMenuItem[]) => {
|
||||||
return {
|
const _toTrayMenuOptions = (parentId: string | null) =>
|
||||||
...trayItem,
|
pipeline(
|
||||||
submenu: trayItem.submenu ? trayItem.submenu.map(getMenuItemConstructorOptions) : undefined,
|
trayMenuItems,
|
||||||
click: trayItem.click ? () => {
|
|
||||||
trayItem.click?.(trayItem);
|
|
||||||
} : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function createTrayMenu(
|
filter((item) => item.parentId === parentId),
|
||||||
extensionTrayItems: TrayMenuRegistration[],
|
|
||||||
navigateToPreferences: () => void,
|
|
||||||
stopServicesAndExitApp: () => void,
|
|
||||||
isAutoUpdateEnabled: () => boolean,
|
|
||||||
showApplicationWindow: () => Promise<void>,
|
|
||||||
showAbout: () => void,
|
|
||||||
): Menu {
|
|
||||||
let template: Electron.MenuItemConstructorOptions[] = [
|
|
||||||
{
|
|
||||||
label: `Open ${productName}`,
|
|
||||||
click() {
|
|
||||||
showApplicationWindow().catch(error => logger.error(`${TRAY_LOG_PREFIX}: Failed to open lens`, { error }));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Preferences",
|
|
||||||
click() {
|
|
||||||
navigateToPreferences();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isAutoUpdateEnabled()) {
|
map(
|
||||||
template.push({
|
(trayMenuItem: TrayMenuItem): Electron.MenuItemConstructorOptions => {
|
||||||
label: "Check for updates",
|
if (trayMenuItem.separator) {
|
||||||
click() {
|
return { id: trayMenuItem.id, type: "separator" };
|
||||||
checkForUpdates()
|
}
|
||||||
.then(() => showApplicationWindow());
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template = template.concat(extensionTrayItems.map(getMenuItemConstructorOptions));
|
const childItems = _toTrayMenuOptions(trayMenuItem.id);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: trayMenuItem.id,
|
||||||
|
label: trayMenuItem.label,
|
||||||
|
enabled: trayMenuItem.enabled.get(),
|
||||||
|
toolTip: trayMenuItem.tooltip,
|
||||||
|
|
||||||
|
...(isEmpty(childItems)
|
||||||
|
? {
|
||||||
|
type: "normal",
|
||||||
|
submenu: _toTrayMenuOptions(trayMenuItem.id),
|
||||||
|
|
||||||
|
click: () => {
|
||||||
|
try {
|
||||||
|
trayMenuItem.click?.();
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(
|
||||||
|
`${TRAY_LOG_PREFIX}: clicking item "${trayMenuItem.id} failed."`,
|
||||||
|
{ error },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
type: "submenu",
|
||||||
|
submenu: _toTrayMenuOptions(trayMenuItem.id),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return _toTrayMenuOptions(null);
|
||||||
|
};
|
||||||
|
|
||||||
return Menu.buildFromTemplate(template.concat([
|
|
||||||
{
|
|
||||||
label: `About ${productName}`,
|
|
||||||
click() {
|
|
||||||
showApplicationWindow()
|
|
||||||
.then(showAbout)
|
|
||||||
.catch(error => logger.error(`${TRAY_LOG_PREFIX}: Failed to show Lens About view`, { error }));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ type: "separator" },
|
|
||||||
{
|
|
||||||
label: "Quit App",
|
|
||||||
click() {
|
|
||||||
stopServicesAndExitApp();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user