feat: ability to set custom icons

This commit is contained in:
Oleh Polisan 2024-06-20 16:01:03 +03:00
parent 95536603dd
commit 490b8c8b2f
5 changed files with 26 additions and 6 deletions

View file

@ -23,7 +23,7 @@ import { isTruthy } from "shared/utils/guards";
import { once } from "shared/utils/once"; import { once } from "shared/utils/once";
import type { SettingsStore } from "shared/utils/SettingsStore"; import type { SettingsStore } from "shared/utils/SettingsStore";
import { ICON_PATH, STATIC_DIR } from "../shared/paths"; import { ICON_PATH } from "../shared/paths";
import { createAboutWindow } from "./about"; import { createAboutWindow } from "./about";
import { initArRPC } from "./arrpc"; import { initArRPC } from "./arrpc";
import { import {
@ -125,6 +125,12 @@ function initTray(win: BrowserWindow) {
]); ]);
tray = new Tray(ICON_PATH); tray = new Tray(ICON_PATH);
try {
if (Settings.store.trayCustom) tray.setImage(join(DATA_DIR, "TrayIcons", "icon.png"));
} catch (error) {
console.log("Error while loading custom tray image. Recreating new ones.");
generateTrayIcons(true);
}
tray.setToolTip("Vesktop"); tray.setToolTip("Vesktop");
tray.setContextMenu(trayMenu); tray.setContextMenu(trayMenu);
tray.on("click", onTrayClick); tray.on("click", onTrayClick);
@ -505,7 +511,8 @@ export async function createWindows() {
export async function setTrayIcon(iconName: string) { export async function setTrayIcon(iconName: string) {
if (!tray || tray.isDestroyed()) return; if (!tray || tray.isDestroyed()) return;
if (iconName !== "icon") { const Icons = new Set(["speaking", "muted", "deafened", "idle", "icon"]);
if (Icons.has(iconName)) {
try { try {
tray.setImage(join(DATA_DIR, "TrayIcons", iconName + ".png")); tray.setImage(join(DATA_DIR, "TrayIcons", iconName + ".png"));
} catch (error) { } catch (error) {
@ -514,5 +521,4 @@ export async function setTrayIcon(iconName: string) {
} }
return; return;
} }
tray.setImage(join(STATIC_DIR, "icon.png"));
} }

View file

@ -53,11 +53,15 @@ export async function generateTrayIcons(force = false) {
for (const icon of Icons) { for (const icon of Icons) {
mainWin.webContents.send(IpcEvents.CREATE_TRAY_ICON_REQUEST, icon); mainWin.webContents.send(IpcEvents.CREATE_TRAY_ICON_REQUEST, icon);
} }
} copyFileSync(join(STATIC_DIR, "icon.png"), join(DATA_DIR, "TrayIcons", "icon.png"));
mainWin.webContents.send(IpcEvents.SET_CURRENT_VOICE_TRAY_ICON); mainWin.webContents.send(IpcEvents.SET_CURRENT_VOICE_TRAY_ICON);
}
} }
export async function pickTrayIcon(iconName: string) { export async function pickTrayIcon(iconName: string) {
const Icons = new Set(["speaking", "muted", "deafened", "idle", "icon"]);
if (!Icons.has(iconName)) return;
const res = await dialog.showOpenDialog(mainWin!, { const res = await dialog.showOpenDialog(mainWin!, {
properties: ["openFile"], properties: ["openFile"],
filters: [{ name: "Image", extensions: ["png", "jpg"] }] filters: [{ name: "Image", extensions: ["png", "jpg"] }]

View file

@ -36,7 +36,8 @@ export const VesktopNative = {
fileManager: { fileManager: {
showItemInFolder: (path: string) => invoke<void>(IpcEvents.SHOW_ITEM_IN_FOLDER, path), showItemInFolder: (path: string) => invoke<void>(IpcEvents.SHOW_ITEM_IN_FOLDER, path),
selectVencordDir: () => invoke<LiteralUnion<"cancelled" | "invalid", string>>(IpcEvents.SELECT_VENCORD_DIR), selectVencordDir: () => invoke<LiteralUnion<"cancelled" | "invalid", string>>(IpcEvents.SELECT_VENCORD_DIR),
selectTrayIcon: () => invoke<LiteralUnion<"cancelled" | "invalid", string>>(IpcEvents.SELECT_TRAY_ICON) selectTrayIcon: (iconName: string) =>
invoke<LiteralUnion<"cancelled" | "invalid", string>>(IpcEvents.SELECT_TRAY_ICON, iconName)
}, },
settings: { settings: {
get: () => sendSync<Settings>(IpcEvents.GET_SETTINGS), get: () => sendSync<Settings>(IpcEvents.GET_SETTINGS),

View file

@ -44,13 +44,14 @@ function trayEditButton(iconName: string) {
alt="read if cute :3" alt="read if cute :3"
width="48" width="48"
height="48" height="48"
id={iconName}
></img> ></img>
<PencilIcon <PencilIcon
className="vcd-edit-button" className="vcd-edit-button"
width="40" width="40"
height="40" height="40"
onClick={async () => { onClick={async () => {
const choice = await VesktopNative.fileManager.selectTrayIcon(); const choice = await VesktopNative.fileManager.selectTrayIcon(iconName);
switch (choice) { switch (choice) {
case "cancelled": case "cancelled":
return; return;
@ -65,6 +66,12 @@ function trayEditButton(iconName: string) {
console.log("choice:", choice); console.log("choice:", choice);
// copy image and reload // copy image and reload
// settings.trayIconPath = choice; // settings.trayIconPath = choice;
const iconDataURL = VesktopNative.tray.getIconSync(iconName);
const img = document.getElementById(iconName) as HTMLImageElement;
if (img) {
img.src = iconDataURL;
}
VesktopNative.tray.createIconResponse(iconName, iconDataURL);
}} }}
/> />
</div> </div>

View file

@ -22,6 +22,8 @@ export function setCurrentTrayIcon() {
} else { } else {
VesktopNative.tray.setIcon("idle"); VesktopNative.tray.setIcon("idle");
} }
} else {
VesktopNative.tray.setIcon("icon");
} }
} }