mirror of
https://github.com/MasterAcnolo/Freedom-Loader.git
synced 2026-09-27 20:11:15 +02:00
115 lines
3.4 KiB
JavaScript
115 lines
3.4 KiB
JavaScript
const {app, Menu, Tray, nativeImage} = require("electron");
|
|
const path = require("path");
|
|
const {logger} = require("../server/logger"); // Ajuste le chemin si besoin
|
|
const fs = require("fs");
|
|
const {getMainWindow} = require("./windowManager");
|
|
|
|
/**
|
|
* Global reference to the Tray instance to prevent garbage collection.
|
|
* @type {Tray | null}
|
|
*/
|
|
let tray = null;
|
|
|
|
/**
|
|
* Creates and configures the cross-platform System Tray.
|
|
*
|
|
* Responsibilities:
|
|
* - Loads the appropriate icon format based on the operating system.
|
|
* - Builds the right-click context menu.
|
|
* - Handles left-click behavior to toggle main window visibility.
|
|
*
|
|
* @param {boolean} devMode - Indicates whether the application is running in development mode.
|
|
* @returns {Tray} The created Tray instance.
|
|
*/
|
|
function createSystemTray(devMode) {
|
|
// Prevent creating multiple tray instances
|
|
if (tray) return tray;
|
|
|
|
const isWin = process.platform === "win32";
|
|
const iconName = isWin ? "app-icon.ico" : "app-icon-64x64.png";
|
|
|
|
// Attempt to load the icon from the local build directory first
|
|
let iconPath = path.join(__dirname, "..", "build", iconName);
|
|
|
|
// Fallback to the extracted resources path if running in production
|
|
if (!devMode && !fs.existsSync(iconPath)) {
|
|
iconPath = path.join(process.resourcesPath, iconName);
|
|
}
|
|
|
|
if (!fs.existsSync(iconPath)) {
|
|
logger.error(`System Tray icon not found at resolved path: ${iconPath}`);
|
|
} else {
|
|
logger.info("System Tray icon resolved successfully.");
|
|
}
|
|
|
|
const icon = nativeImage.createFromPath(iconPath);
|
|
|
|
if (icon.isEmpty()) {
|
|
logger.error("System Tray icon file was found but could not be decoded by Electron (image is empty).");
|
|
}
|
|
|
|
tray = new Tray(icon);
|
|
tray.setToolTip("Freedom Loader");
|
|
|
|
/**
|
|
* System Tray Context Menu (Right-click action).
|
|
*/
|
|
const contextMenu = Menu.buildFromTemplate([
|
|
{
|
|
label: "Show Freedom Loader",
|
|
click: () => {
|
|
const window = getMainWindow();
|
|
if (window && !window.isDestroyed()) {
|
|
window.show();
|
|
window.focus();
|
|
}
|
|
},
|
|
},
|
|
{ type: "separator" },
|
|
{
|
|
label: "Quit",
|
|
click: () => {
|
|
/**
|
|
* Flags the application for a deliberate exit,
|
|
* bypassing the default "minimize to tray" behavior.
|
|
*/
|
|
app.isQuitting = true;
|
|
app.quit();
|
|
},
|
|
},
|
|
]);
|
|
|
|
tray.setContextMenu(contextMenu);
|
|
|
|
/**
|
|
* Left-click behavior: Toggles main window visibility.
|
|
* but it remains standard practice for Windows and Linux environments.
|
|
*/
|
|
tray.on("click", () => {
|
|
const window = getMainWindow();
|
|
if (!window || window.isDestroyed()) return;
|
|
|
|
if (window.isVisible()) {
|
|
window.hide();
|
|
} else {
|
|
window.show();
|
|
window.focus();
|
|
}
|
|
});
|
|
|
|
return tray;
|
|
}
|
|
|
|
/**
|
|
* Safely destroys the tray icon to prevent OS-level crashes (especially on Linux/Wayland).
|
|
* Should be called right before the application quits.
|
|
*/
|
|
function destroyTray() {
|
|
if (tray && !tray.isDestroyed()) {
|
|
tray.destroy();
|
|
tray = null;
|
|
logger.info("System Tray destroyed cleanly.");
|
|
}
|
|
}
|
|
|
|
module.exports = {createSystemTray, destroyTray}; |