/* * SPDX-License-Identifier: GPL-3.0 * Vesktop, a desktop app aiming to give you a snappier Discord Experience * Copyright (c) 2023 Vendicated and Vencord contributors */ import "./traySetting.css"; import { Margins, Modals, ModalSize, openModal } from "@vencord/types/utils"; import { findByCodeLazy, findByPropsLazy } from "@vencord/types/webpack"; import { Button, Forms, Select, Switch, Toasts } from "@vencord/types/webpack/common"; import { setCurrentTrayIcon } from "renderer/patches/tray"; import { useSettings } from "renderer/settings"; import { SettingsComponent } from "./Settings"; const ColorPicker = findByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); const { PencilIcon } = findByPropsLazy("PencilIcon"); const presets = [ "#3DB77F", // discord default ~ "#F6BFAC", // Vesktop inpired "#FC2F2F", // red "#2FFC33", // green "#FCF818", // yellow "#2FFCE6", // light-blue "#3870FA", // blue "#6F32FD", // purple "#FC18EC" // pink ]; VesktopNative.app.getAccentColor().then(color => { if (color) presets.unshift(color); }); const statusToSettingsKey = { icon: { key: "trayMainOverride", label: "Main Icon" }, idle: { key: "trayIdleOverride", label: "Idle Icon" }, speaking: { key: "traySpeakingOverride", label: "Speaking Icon" }, muted: { key: "trayMutedOverride", label: "Muted Icon" }, deafened: { key: "trayDeafenedOverride", label: "Deafened Icon" } }; async function changeIcon(iconName, settings) { const choice = await VesktopNative.fileManager.selectTrayIcon(iconName); 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; } const updateIcon = () => { const iconKey = statusToSettingsKey[iconName as keyof typeof statusToSettingsKey].key; settings[iconKey] = true; const iconDataURL = VesktopNative.tray.getIconSync(iconName); const img = document.getElementById(iconName) as HTMLImageElement; if (img) { img.src = iconDataURL; } setCurrentTrayIcon(); }; // sometimes new icon may not be generated in time and will be used old icon :c if (choice === "svg") setTimeout(updateIcon, 50); else updateIcon(); } function trayEditButton(iconName: string) { const Settings = useSettings(); return (
read if cute :3 { changeIcon(iconName, Settings); }} />
); } function TrayModalComponent({ modalProps, close }: { modalProps: any; close: () => void }) { const Settings = useSettings(); return ( Custom Tray Icons {Object.entries(statusToSettingsKey).map(([iconName, { key, label }]) => (
{trayEditButton(iconName)} {VesktopNative.settings.get()[key] && ( )}
{label}
))}
); } const openTrayModal = () => { openModal(props => props.onClose()} />); }; export const TraySwitch: SettingsComponent = ({ settings }) => { return ( { settings.tray = v; setCurrentTrayIcon(); }} note="Add a tray icon for Vesktop" > Tray Icon ); }; export const CustomizeTraySwitch: SettingsComponent = ({ settings }) => { if (!settings.tray) return null; return ( <>
Custom tray icons Use custom default and voice status tray icons.
); }; export const TrayIconPicker: SettingsComponent = ({ settings }) => { if (!settings.tray) return null; return (
Tray Icon Color Choose a color for your tray icon!
{ const hexColor = newColor.toString(16).padStart(6, "0"); settings.trayColor = hexColor; VesktopNative.tray.generateTrayIcons(); }} showEyeDropper={false} suggestedColors={presets} />
); }; export const TrayFillColorSwitch: SettingsComponent = ({ settings }) => { if (!settings.tray) return null; return (
Tray icon fill color Choose background fill of Tray Icons in Voice Chat
); };