diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 46afde5..5ab45d9 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -12,6 +12,7 @@ import { mkdirSync, readFileSync, watch } from "fs"; import { open, readFile } from "fs/promises"; import { release } from "os"; import { join } from "path"; +import { ICON_PATH } from "shared/paths"; import { debounce } from "shared/utils/debounce"; import { IpcEvents } from "../shared/IpcEvents"; @@ -41,6 +42,19 @@ handleSync( () => process.platform === "win32" && Number(release().split(".").pop()) >= 22621 ); +handleSync(IpcEvents.GET_TRAY_ICON, () => { + try { + if (!Settings.store.trayIconPath) return nativeImage.createFromPath(ICON_PATH).toDataURL(); + + const img = nativeImage.createFromPath(Settings.store.trayIconPath).resize({ width: 64, height: 64 }); + if (img.isEmpty()) return nativeImage.createFromPath(ICON_PATH).toDataURL(); + + return img.toDataURL(); + } catch (error) { + return "no"; + } +}); + handleSync(IpcEvents.AUTOSTART_ENABLED, () => autoStart.isEnabled()); handle(IpcEvents.ENABLE_AUTOSTART, autoStart.enable); handle(IpcEvents.DISABLE_AUTOSTART, autoStart.disable); @@ -124,13 +138,13 @@ handle(IpcEvents.SELECT_VENCORD_DIR, async () => { handle(IpcEvents.SELECT_TRAY_ICON, async () => { const res = await dialog.showOpenDialog(mainWin!, { properties: ["openFile"], - filters: [{name: "Image", extensions: ["png", "jpg"]}] + filters: [{ name: "Image", extensions: ["png", "jpg"] }] }); if (!res.filePaths.length) return "cancelled"; - + const dir = res.filePaths[0]; const image = nativeImage.createFromPath(dir); - if(image.isEmpty()) return "invalid"; + if (image.isEmpty()) return "invalid"; return dir; }); diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 58b580a..a3e667a 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -11,8 +11,8 @@ import { dialog, Menu, MenuItemConstructorOptions, - nativeTheme, nativeImage, + nativeTheme, Tray } from "electron"; import { rm } from "fs/promises"; @@ -21,6 +21,7 @@ import { IpcEvents } from "shared/IpcEvents"; import { isTruthy } from "shared/utils/guards"; import { once } from "shared/utils/once"; import type { SettingsStore } from "shared/utils/SettingsStore"; + import { ICON_PATH } from "../shared/paths"; import { createAboutWindow } from "./about"; import { initArRPC } from "./arrpc"; @@ -123,9 +124,9 @@ function initTray(win: BrowserWindow) { tray = new Tray(ICON_PATH); if (Settings.store.trayIconPath) { const trayImage = nativeImage.createFromPath(Settings.store.trayIconPath); - if (!trayImage.isEmpty()) tray.setImage(trayImage.resize({width: 32, height: 32})); + if (!trayImage.isEmpty()) tray.setImage(trayImage.resize({ width: 32, height: 32 })); } - + tray.setToolTip("Vesktop"); tray.setContextMenu(trayMenu); tray.on("click", onTrayClick); @@ -277,7 +278,7 @@ function getWindowBoundsOptions(): BrowserWindowConstructorOptions { options.x = x; options.y = y; } - + if (!Settings.store.disableMinSize) { options.minWidth = MIN_WIDTH; options.minHeight = MIN_HEIGHT; diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index 467bfb6..4f5146b 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -57,6 +57,9 @@ export const VesktopNative = { minimize: () => invoke(IpcEvents.MINIMIZE), maximize: () => invoke(IpcEvents.MAXIMIZE) }, + tray: { + getTrayIcon: () => sendSync(IpcEvents.GET_TRAY_ICON) + }, capturer: { getLargeThumbnail: (id: string) => invoke(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, id) }, diff --git a/src/renderer/components/settings/Settings.tsx b/src/renderer/components/settings/Settings.tsx index 3127308..5f7479c 100644 --- a/src/renderer/components/settings/Settings.tsx +++ b/src/renderer/components/settings/Settings.tsx @@ -14,8 +14,8 @@ import { isMac, isWindows } from "renderer/utils"; import { AutoStartToggle } from "./AutoStartToggle"; import { DiscordBranchPicker } from "./DiscordBranchPicker"; import { NotificationBadgeToggle } from "./NotificationBadgeToggle"; -import { VencordLocationPicker } from "./VencordLocationPicker"; import { TrayIconImagePicker } from "./TrayIconImagePicker"; +import { VencordLocationPicker } from "./VencordLocationPicker"; import { WindowsTransparencyControls } from "./WindowsTransparencyControls"; interface BooleanSetting { @@ -69,13 +69,6 @@ const SettingsOptions: Record> WindowsTransparencyControls ], Behaviour: [ - { - key: "tray", - title: "Tray Icon", - description: "Add a tray icon for Vesktop", - defaultValue: true, - invisible: () => isMac - }, { key: "minimizeToTray", title: "Minimize to tray", @@ -128,7 +121,7 @@ const SettingsOptions: Record> } ], "Tray Icon Image": [TrayIconImagePicker], - "Vencord Location": [VencordLocationPicker], + "Vencord Location": [VencordLocationPicker] }; function SettingsSections() { diff --git a/src/renderer/components/settings/TrayIconImagePicker.tsx b/src/renderer/components/settings/TrayIconImagePicker.tsx index 352e51e..cf8487a 100644 --- a/src/renderer/components/settings/TrayIconImagePicker.tsx +++ b/src/renderer/components/settings/TrayIconImagePicker.tsx @@ -4,58 +4,69 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ -import { Button, Forms, Toasts } from "@vencord/types/webpack/common"; +import { Forms, Switch, Toasts } from "@vencord/types/webpack/common"; +import { Settings } from "renderer/settings"; import { SettingsComponent } from "./Settings"; export const TrayIconImagePicker: SettingsComponent = ({ settings }) => { return ( <> - - Tray icon is currently {" "} - {settings.trayIconPath ? ( - { - e.preventDefault(); - VesktopNative.fileManager.showItemInFolder(settings.trayIconPath!); - }} +
+
+ (Settings.store.tray = v)} + note={"Add a tray icon for Vesktop"} > - {settings.trayIconPath} - - ) : ( - "the default location" - )} - -
- - + {"Tray Icon"} + +
+ +
+
+ hello + { + const choice = await VesktopNative.fileManager.selectTrayIcon(); + switch (choice) { + case "cancelled": + return; + case "invalid": + Toasts.show({ + message: "Please select a valid .png or .jpg image!", + id: Toasts.genId(), + type: Toasts.Type.FAILURE + }); + return; + } + settings.trayIconPath = choice; + }} + /> +
+
); diff --git a/src/renderer/components/settings/settings.css b/src/renderer/components/settings/settings.css index d55ff50..fa66db5 100644 --- a/src/renderer/components/settings/settings.css +++ b/src/renderer/components/settings/settings.css @@ -11,4 +11,62 @@ .vcd-settings-title { margin-bottom: 0.5rem; -} \ No newline at end of file +} + +.tray-icon-wrap { + position: relative; + top: 0; + right: 0; +} + +.tray-icon-image { + border-radius: 50%; + position: relative; + top: 0; + right: 0; +} + +.edit-button { + visibility: visible; + display: block; + opacity: 0; + position: absolute; + top: 4px; + left: 4px; +} + +.tray-icon-wrap:hover .tray-icon-image { + transition: 0.3s ease; + background-color: rgb(0, 0, 0) no-repeat; + opacity: 0.25; +} +.tray-icon-wrap:hover .edit-button { + transition: 0.3s ease; + visibility: visible; + opacity: 1; +} + +#tray-setting { + height: 48px; + position: relative; +} +#colLeft { + height: 48px; + display: inline-block; + width: 40%; +} +#colMiddle { + height: 48px; + float: center; + display: inline; + position: relative; + left: 45%; +} +#colRight { + height: 48px; + display: inline; + float: right; + position: absolute; + top: -12px; + right: 0; +} diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index 407403b..eb1910a 100644 --- a/src/shared/IpcEvents.ts +++ b/src/shared/IpcEvents.ts @@ -24,7 +24,9 @@ export const enum IpcEvents { SET_SETTINGS = "VCD_SET_SETTINGS", SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR", + SELECT_TRAY_ICON = "VCD_SELECT_TRAY_ICON", + GET_TRAY_ICON = "VCD_GET_TRAY_ICON", UPDATER_GET_DATA = "VCD_UPDATER_GET_DATA", UPDATER_DOWNLOAD = "VCD_UPDATER_DOWNLOAD",