diff --git a/package.json b/package.json index a15009b..57b807a 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "postinstall": "electron-builder install-app-deps", "build:unpack": "npm run build && electron-builder --dir", "build:win": "npm run build && electron-builder --win", - "build:mac": "electron-vite build && electron-builder --mac --publish always", + "build:mac": "electron-vite build && electron-builder --mac", "build:linux": "electron-vite build && electron-builder --linux" }, "dependencies": { diff --git a/resources/diamond.png b/resources/diamond.png new file mode 100644 index 0000000..dd32a22 Binary files /dev/null and b/resources/diamond.png differ diff --git a/src/main/index.ts b/src/main/index.ts index 260b249..c4bfd2c 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,5 +1,5 @@ import { electronApp, is, optimizer } from "@electron-toolkit/utils"; -import { app, BrowserWindow, Menu, shell } from "electron"; +import { app, BrowserWindow, Menu, shell, nativeImage, Tray } from "electron"; import log from "electron-log/main"; import { autoUpdater } from "electron-updater"; import path, { join } from "path"; @@ -8,10 +8,11 @@ import ErrorTypeCheck from "../util/errorTypeCheck"; import ipcTypes from "../util/ipcTypes.json"; import client from "./graphql/graphql-client"; import store from "./store/store"; -import { createPublicKey } from "crypto"; +import appIcon from "../../resources/diamond.png?asset"; log.initialize(); const isMac = process.platform === "darwin"; +var isAppQuitting = false; //Needed on Mac as an override to allow us to fully quit the app. function createWindow(): void { // Create the browser window. const { width, height, x, y } = store.get("app.windowBounds") as { @@ -128,68 +129,62 @@ function createWindow(): void { ], }, - ...(import.meta.env.DEV - ? [ - { - label: "Development", - submenu: [ - { - label: "Check for updates", - click: (): void => { - autoUpdater.checkForUpdates(); - }, - }, - { - label: "Open Log Folder", - click: (): void => { - /* action for item 1 */ - shell.openPath(log.transports.file.getFile().path); - }, - }, - { - label: "Clear Log", - click: (): void => { - log.transports.file.getFile().clear(); - }, - }, - { - label: "Open Config", - click: (): void => { - shell.openPath(path.dirname(store.path)); - }, - }, - { - label: "Log the Store", - click: (): void => { - log.debug( - "Store Contents" + JSON.stringify(store.store, null, 4), - ); - }, - }, - { - type: "separator", - }, - { - label: "Temp Test Action - Get Token from Renderer", - click: (): void => { - client - .request( - ` + { + label: "Development", + submenu: [ + { + label: "Check for updates", + click: (): void => { + autoUpdater.checkForUpdates(); + }, + }, + { + label: "Open Log Folder", + click: (): void => { + /* action for item 1 */ + shell.openPath(log.transports.file.getFile().path); + }, + }, + { + label: "Clear Log", + click: (): void => { + log.transports.file.getFile().clear(); + }, + }, + { + label: "Open Config", + click: (): void => { + shell.openPath(path.dirname(store.path)); + }, + }, + { + label: "Log the Store", + click: (): void => { + log.debug("Store Contents" + JSON.stringify(store.store, null, 4)); + }, + }, + { + type: "separator", + }, + { + label: "Temp Test Action - Get Token from Renderer", + click: (): void => { + client + .request( + ` query jobs{ jobs { id}} `, - ) - .then((data) => { - log.info("Data from graffle", data); - }); - }, - }, - ], + ) + .then((data) => { + log.info("Data from graffle", data); + }); }, - ] - : []), + }, + ], + }, ]; const menu: Electron.Menu = Menu.buildFromTemplate(template); @@ -210,6 +205,13 @@ function createWindow(): void { mainWindow.show(); }); + mainWindow.on("close", (event: Electron.Event) => { + if (!isAppQuitting) { + event.preventDefault(); // Prevent the window from closing + mainWindow.hide(); + } + }); + mainWindow.webContents.setWindowOpenHandler((details) => { shell.openExternal(details.url); return { action: "deny" }; @@ -255,6 +257,26 @@ app.whenReady().then(async () => { ...ErrorTypeCheck(error), }); } + //Create Tray + + const trayicon = nativeImage.createFromPath(appIcon); + const tray = new Tray(trayicon.resize({ width: 16 })); + const contextMenu = Menu.buildFromTemplate([ + { + label: "Show App", + click: (): void => { + openMainWindow(); + }, + }, + { + label: "Quit", + click: (): void => { + app.quit(); // actually quit the app. + }, + }, + ]); + + tray.setContextMenu(contextMenu); //Check for app updates. @@ -300,9 +322,7 @@ app.whenReady().then(async () => { createWindow(); app.on("activate", function () { - // On macOS it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (BrowserWindow.getAllWindows().length === 0) createWindow(); + openMainWindow(); }); }); @@ -311,9 +331,19 @@ app.whenReady().then(async () => { // explicitly with Cmd + Q. app.on("window-all-closed", () => { if (process.platform !== "darwin") { - app.quit(); + app.quit(); //Disable the quit. } }); -// In this file you can include the rest of your app's specific main process -// code. You can also put them in separate files and require them here. +app.on("before-quit", () => { + isAppQuitting = true; +}); + +function openMainWindow(): void { + const mainWindow = BrowserWindow.getAllWindows()[0]; + if (mainWindow) { + mainWindow.show(); + } else { + createWindow(); + } +} diff --git a/src/renderer/src/components/NavigationHeader/Navigationheader.tsx b/src/renderer/src/components/NavigationHeader/Navigationheader.tsx index 3acfa5d..633320c 100644 --- a/src/renderer/src/components/NavigationHeader/Navigationheader.tsx +++ b/src/renderer/src/components/NavigationHeader/Navigationheader.tsx @@ -10,10 +10,10 @@ const NavigationHeader: React.FC = () => { const isWatcherStarted = useAppSelector(selectWatcherStatus); const menuItems: MenuItemType[] = [ { label: {t("navigation.home")}, key: "home" }, - { - label: {t("navigation.settings")}, - key: "settings", - }, + // { + // label: {t("navigation.settings")}, + // key: "settings", + // }, ]; return (