90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
/*
|
|
* Vencord, a Discord client mod
|
|
* Copyright (c) 2026 Vendicated and contributors
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
import { IpcEvents } from "@shared/IpcEvents";
|
|
import { BrowserWindow, ipcMain, Menu, MenuItemConstructorOptions, shell } from "electron";
|
|
|
|
import { SETTINGS_DIR } from "./utils/constants";
|
|
|
|
let cachedUpdateAvailable = false;
|
|
|
|
ipcMain.on(IpcEvents.SET_TRAY_UPDATE_STATE, (_, available: boolean) => {
|
|
cachedUpdateAvailable = available;
|
|
});
|
|
|
|
function getMainWindow(): BrowserWindow | undefined {
|
|
return BrowserWindow.getFocusedWindow() ?? BrowserWindow.getAllWindows()[0];
|
|
}
|
|
|
|
function sendToRenderer(event: IpcEvents): void {
|
|
getMainWindow()?.webContents.send(event);
|
|
}
|
|
|
|
function findInsertIndex(template: MenuItemConstructorOptions[]): number {
|
|
const openIndex = template.findIndex(item => {
|
|
const label = item.label?.toLowerCase() ?? "";
|
|
return label.includes("open") || label.includes("show");
|
|
});
|
|
return openIndex !== -1 ? openIndex + 1 : 0;
|
|
}
|
|
|
|
function isTrayMenu(template: MenuItemConstructorOptions[]): boolean {
|
|
if (!template.length) return false;
|
|
|
|
const hasOpenOrShow = template.some(item => {
|
|
const label = item.label?.toLowerCase() ?? "";
|
|
return label.includes("open") || label.includes("show");
|
|
});
|
|
|
|
const hasQuit = template.some(item =>
|
|
item.label?.toLowerCase().includes("quit") || item.role === "quit"
|
|
);
|
|
|
|
const isNotAppMenu = !template.some(item =>
|
|
item.label === "&File" || item.label === "File" ||
|
|
item.label === "&Edit" || item.label === "Edit"
|
|
);
|
|
|
|
return hasOpenOrShow && hasQuit && isNotAppMenu;
|
|
}
|
|
|
|
function createEquicordMenuItems(): MenuItemConstructorOptions[] {
|
|
return [
|
|
{
|
|
label: "Equicord",
|
|
submenu: [
|
|
{
|
|
label: cachedUpdateAvailable ? "Update Equicord" : "Check for Updates",
|
|
click: () => sendToRenderer(IpcEvents.TRAY_CHECK_UPDATES)
|
|
},
|
|
{
|
|
label: "Repair Equicord",
|
|
click: () => sendToRenderer(IpcEvents.TRAY_REPAIR)
|
|
},
|
|
{ type: "separator" },
|
|
{
|
|
label: "Open Settings Folder",
|
|
click: () => shell.openPath(SETTINGS_DIR)
|
|
}
|
|
]
|
|
},
|
|
{ type: "separator" }
|
|
];
|
|
}
|
|
|
|
export function patchTrayMenu(): void {
|
|
const originalBuildFromTemplate = Menu.buildFromTemplate;
|
|
|
|
Menu.buildFromTemplate = function (template: MenuItemConstructorOptions[]) {
|
|
if (isTrayMenu(template)) {
|
|
const insertIndex = findInsertIndex(template);
|
|
const equicordItems = createEquicordMenuItems();
|
|
template.splice(insertIndex, 0, ...equicordItems);
|
|
}
|
|
|
|
return originalBuildFromTemplate.call(this, template);
|
|
};
|
|
}
|