diff --git a/eslint.config.js b/eslint.config.js index 3b9670e..ef95d14 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -17,6 +17,7 @@ export default tseslint.config( }, rules: { "no-constant-binary-expression": 0, + "@typescript-eslint/no-non-null-assertion": 0, "@typescript-eslint/no-unused-vars": [ 2, { diff --git a/resources/placeholderTrayIcon.png b/resources/placeholderTrayIcon.png new file mode 100644 index 0000000..f64b855 Binary files /dev/null and b/resources/placeholderTrayIcon.png differ diff --git a/src/@types/config.d.ts b/src/@types/config.d.ts index 6a41e4b..31ed10e 100644 --- a/src/@types/config.d.ts +++ b/src/@types/config.d.ts @@ -4,4 +4,5 @@ export interface Config { multiInstance: boolean; mods: "vencord"[]; autoHideMenuBar: boolean; + tray: boolean; } diff --git a/src/main/discord/discordWindow.ts b/src/main/discord/discordWindow.ts index 3b765fe..8bcce8d 100644 --- a/src/main/discord/discordWindow.ts +++ b/src/main/discord/discordWindow.ts @@ -1,6 +1,6 @@ import {BrowserWindow} from "electron"; import {getConfig} from "../../shared/config.js"; -import { join } from "path"; +import {join} from "path"; export async function createDiscordWindow() { const window = new BrowserWindow({ @@ -19,7 +19,7 @@ export async function createDiscordWindow() { await window.loadURL(`https://${getConfig("channel")}.discord.com/app`); } - //!SECTION Block Analytics + //SECTION - Block Analytics window.webContents.session.webRequest.onBeforeRequest( { urls: [ @@ -33,4 +33,5 @@ export async function createDiscordWindow() { callback({cancel: true}); } ); + return window; } diff --git a/src/main/main.ts b/src/main/main.ts index 0dde74a..432cc61 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -3,9 +3,14 @@ import {createDiscordWindow} from "./discord/discordWindow.js"; import "./startup.js"; import "./ipc.js"; import {fetchMods} from "./functions/fetchMods.js"; +import {startTray} from "./tray.js"; +import {getConfig} from "../shared/config.js"; await fetchMods(); void app.whenReady().then(async () => { - await createDiscordWindow(); + const Acorn = await createDiscordWindow(); + if (getConfig("tray")) { + startTray(Acorn.webContents); + } }); diff --git a/src/main/tray.ts b/src/main/tray.ts new file mode 100644 index 0000000..b6c035e --- /dev/null +++ b/src/main/tray.ts @@ -0,0 +1,24 @@ +import {app, Menu, nativeImage, Tray, type WebContents} from "electron"; +import icon from "../../resources/placeholderTrayIcon.png?asset"; + +export function startTray(pageData: WebContents) { + const tray = new Tray(icon as string); + tray.setToolTip("Acorn"); + tray.setContextMenu( + Menu.buildFromTemplate([ + { + label: "Quit", + click() { + app.quit(); + } + } + ]) + ); + pageData.on("page-favicon-updated", (_, favicons) => { + try { + tray.setImage(nativeImage.createFromDataURL(favicons[0]!)); + } catch { + return; // NOTE - Discord will send a URL before fully loaded + } + }); +} diff --git a/src/shared/config.ts b/src/shared/config.ts index a2d1705..51f9a58 100644 --- a/src/shared/config.ts +++ b/src/shared/config.ts @@ -10,7 +10,8 @@ function makeConfig() { channel: "stable", multiInstance: false, mods: ["vencord"], - autoHideMenuBar: true + autoHideMenuBar: true, + tray: true } as Config; writeFileSync(configLocation, JSON.stringify(config, null, 2), {encoding: "utf8", flag: "w"}); } diff --git a/tsconfig.json b/tsconfig.json index 568f79c..b3e4f71 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,9 @@ "ESNext", "DOM" ], + "types": [ + "electron-vite/node" + ], "target": "ESNext", }, "include": [