mirror of
https://github.com/Vencord/Vesktop.git
synced 2025-02-24 14:15:09 +00:00
improved tray icon setting UI
This commit is contained in:
parent
3e5783e18a
commit
7713a46394
7 changed files with 144 additions and 62 deletions
|
@ -12,6 +12,7 @@ import { mkdirSync, readFileSync, watch } from "fs";
|
||||||
import { open, readFile } from "fs/promises";
|
import { open, readFile } from "fs/promises";
|
||||||
import { release } from "os";
|
import { release } from "os";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
import { ICON_PATH } from "shared/paths";
|
||||||
import { debounce } from "shared/utils/debounce";
|
import { debounce } from "shared/utils/debounce";
|
||||||
|
|
||||||
import { IpcEvents } from "../shared/IpcEvents";
|
import { IpcEvents } from "../shared/IpcEvents";
|
||||||
|
@ -41,6 +42,19 @@ handleSync(
|
||||||
() => process.platform === "win32" && Number(release().split(".").pop()) >= 22621
|
() => 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());
|
handleSync(IpcEvents.AUTOSTART_ENABLED, () => autoStart.isEnabled());
|
||||||
handle(IpcEvents.ENABLE_AUTOSTART, autoStart.enable);
|
handle(IpcEvents.ENABLE_AUTOSTART, autoStart.enable);
|
||||||
handle(IpcEvents.DISABLE_AUTOSTART, autoStart.disable);
|
handle(IpcEvents.DISABLE_AUTOSTART, autoStart.disable);
|
||||||
|
@ -124,13 +138,13 @@ handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
|
||||||
handle(IpcEvents.SELECT_TRAY_ICON, async () => {
|
handle(IpcEvents.SELECT_TRAY_ICON, async () => {
|
||||||
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"] }]
|
||||||
});
|
});
|
||||||
if (!res.filePaths.length) return "cancelled";
|
if (!res.filePaths.length) return "cancelled";
|
||||||
|
|
||||||
const dir = res.filePaths[0];
|
const dir = res.filePaths[0];
|
||||||
const image = nativeImage.createFromPath(dir);
|
const image = nativeImage.createFromPath(dir);
|
||||||
if(image.isEmpty()) return "invalid";
|
if (image.isEmpty()) return "invalid";
|
||||||
|
|
||||||
return dir;
|
return dir;
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,8 +11,8 @@ import {
|
||||||
dialog,
|
dialog,
|
||||||
Menu,
|
Menu,
|
||||||
MenuItemConstructorOptions,
|
MenuItemConstructorOptions,
|
||||||
nativeTheme,
|
|
||||||
nativeImage,
|
nativeImage,
|
||||||
|
nativeTheme,
|
||||||
Tray
|
Tray
|
||||||
} from "electron";
|
} from "electron";
|
||||||
import { rm } from "fs/promises";
|
import { rm } from "fs/promises";
|
||||||
|
@ -21,6 +21,7 @@ import { IpcEvents } from "shared/IpcEvents";
|
||||||
import { isTruthy } from "shared/utils/guards";
|
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 } 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";
|
||||||
|
@ -123,9 +124,9 @@ function initTray(win: BrowserWindow) {
|
||||||
tray = new Tray(ICON_PATH);
|
tray = new Tray(ICON_PATH);
|
||||||
if (Settings.store.trayIconPath) {
|
if (Settings.store.trayIconPath) {
|
||||||
const trayImage = nativeImage.createFromPath(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.setToolTip("Vesktop");
|
||||||
tray.setContextMenu(trayMenu);
|
tray.setContextMenu(trayMenu);
|
||||||
tray.on("click", onTrayClick);
|
tray.on("click", onTrayClick);
|
||||||
|
@ -277,7 +278,7 @@ function getWindowBoundsOptions(): BrowserWindowConstructorOptions {
|
||||||
options.x = x;
|
options.x = x;
|
||||||
options.y = y;
|
options.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Settings.store.disableMinSize) {
|
if (!Settings.store.disableMinSize) {
|
||||||
options.minWidth = MIN_WIDTH;
|
options.minWidth = MIN_WIDTH;
|
||||||
options.minHeight = MIN_HEIGHT;
|
options.minHeight = MIN_HEIGHT;
|
||||||
|
|
|
@ -57,6 +57,9 @@ export const VesktopNative = {
|
||||||
minimize: () => invoke<void>(IpcEvents.MINIMIZE),
|
minimize: () => invoke<void>(IpcEvents.MINIMIZE),
|
||||||
maximize: () => invoke<void>(IpcEvents.MAXIMIZE)
|
maximize: () => invoke<void>(IpcEvents.MAXIMIZE)
|
||||||
},
|
},
|
||||||
|
tray: {
|
||||||
|
getTrayIcon: () => sendSync<string>(IpcEvents.GET_TRAY_ICON)
|
||||||
|
},
|
||||||
capturer: {
|
capturer: {
|
||||||
getLargeThumbnail: (id: string) => invoke<string>(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, id)
|
getLargeThumbnail: (id: string) => invoke<string>(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, id)
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,8 +14,8 @@ import { isMac, isWindows } from "renderer/utils";
|
||||||
import { AutoStartToggle } from "./AutoStartToggle";
|
import { AutoStartToggle } from "./AutoStartToggle";
|
||||||
import { DiscordBranchPicker } from "./DiscordBranchPicker";
|
import { DiscordBranchPicker } from "./DiscordBranchPicker";
|
||||||
import { NotificationBadgeToggle } from "./NotificationBadgeToggle";
|
import { NotificationBadgeToggle } from "./NotificationBadgeToggle";
|
||||||
import { VencordLocationPicker } from "./VencordLocationPicker";
|
|
||||||
import { TrayIconImagePicker } from "./TrayIconImagePicker";
|
import { TrayIconImagePicker } from "./TrayIconImagePicker";
|
||||||
|
import { VencordLocationPicker } from "./VencordLocationPicker";
|
||||||
import { WindowsTransparencyControls } from "./WindowsTransparencyControls";
|
import { WindowsTransparencyControls } from "./WindowsTransparencyControls";
|
||||||
|
|
||||||
interface BooleanSetting {
|
interface BooleanSetting {
|
||||||
|
@ -69,13 +69,6 @@ const SettingsOptions: Record<string, Array<BooleanSetting | SettingsComponent>>
|
||||||
WindowsTransparencyControls
|
WindowsTransparencyControls
|
||||||
],
|
],
|
||||||
Behaviour: [
|
Behaviour: [
|
||||||
{
|
|
||||||
key: "tray",
|
|
||||||
title: "Tray Icon",
|
|
||||||
description: "Add a tray icon for Vesktop",
|
|
||||||
defaultValue: true,
|
|
||||||
invisible: () => isMac
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: "minimizeToTray",
|
key: "minimizeToTray",
|
||||||
title: "Minimize to tray",
|
title: "Minimize to tray",
|
||||||
|
@ -128,7 +121,7 @@ const SettingsOptions: Record<string, Array<BooleanSetting | SettingsComponent>>
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Tray Icon Image": [TrayIconImagePicker],
|
"Tray Icon Image": [TrayIconImagePicker],
|
||||||
"Vencord Location": [VencordLocationPicker],
|
"Vencord Location": [VencordLocationPicker]
|
||||||
};
|
};
|
||||||
|
|
||||||
function SettingsSections() {
|
function SettingsSections() {
|
||||||
|
|
|
@ -4,58 +4,69 @@
|
||||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
* 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";
|
import { SettingsComponent } from "./Settings";
|
||||||
|
|
||||||
export const TrayIconImagePicker: SettingsComponent = ({ settings }) => {
|
export const TrayIconImagePicker: SettingsComponent = ({ settings }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Forms.FormText>
|
<div id="tray-setting">
|
||||||
Tray icon is currently {" "}
|
<div id="colLeft">
|
||||||
{settings.trayIconPath ? (
|
<Switch
|
||||||
<a
|
key="tray"
|
||||||
href="about:blank"
|
value={Settings.store.tray ?? false}
|
||||||
onClick={e => {
|
onChange={v => (Settings.store.tray = v)}
|
||||||
e.preventDefault();
|
note={"Add a tray icon for Vesktop"}
|
||||||
VesktopNative.fileManager.showItemInFolder(settings.trayIconPath!);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{settings.trayIconPath}
|
{"Tray Icon"}
|
||||||
</a>
|
</Switch>
|
||||||
) : (
|
</div>
|
||||||
"the default location"
|
<div id="colMiddle">
|
||||||
)}
|
<Forms.FormText>
|
||||||
</Forms.FormText>
|
<a
|
||||||
<div className="vcd-location-btns">
|
href="about:blank"
|
||||||
<Button
|
onClick={e => {
|
||||||
size={Button.Sizes.SMALL}
|
e.preventDefault();
|
||||||
onClick={async () => {
|
settings.trayIconPath = void 0;
|
||||||
const choice = await VesktopNative.fileManager.selectTrayIcon();
|
}}
|
||||||
switch (choice) {
|
>
|
||||||
case "cancelled":
|
Reset
|
||||||
return;
|
</a>
|
||||||
case "invalid":
|
</Forms.FormText>
|
||||||
Toasts.show({
|
</div>
|
||||||
message:
|
<div id="colRight">
|
||||||
"Please select a valid .png or .jpg image!",
|
<div className="tray-icon-wrap">
|
||||||
id: Toasts.genId(),
|
<img
|
||||||
type: Toasts.Type.FAILURE
|
className="tray-icon-image"
|
||||||
});
|
src={VesktopNative.tray.getTrayIcon()}
|
||||||
return;
|
alt="hello"
|
||||||
}
|
width="48"
|
||||||
settings.trayIconPath = choice;
|
height="48"
|
||||||
}}
|
></img>
|
||||||
>
|
<input
|
||||||
Change
|
className="edit-button"
|
||||||
</Button>
|
type="image"
|
||||||
<Button
|
src="https://cdn.discordapp.com/attachments/895550066453012480/1236925384482619433/I1oxwE7.png?ex=6639c808&is=66387688&hm=5c5f47a0c06b2e0580fd5494386bfbeebc001c20e3fd64f26783f360b12162ed&"
|
||||||
size={Button.Sizes.SMALL}
|
onClick={async () => {
|
||||||
color={Button.Colors.RED}
|
const choice = await VesktopNative.fileManager.selectTrayIcon();
|
||||||
onClick={() => (settings.trayIconPath = void 0)}
|
switch (choice) {
|
||||||
>
|
case "cancelled":
|
||||||
Reset
|
return;
|
||||||
</Button>
|
case "invalid":
|
||||||
|
Toasts.show({
|
||||||
|
message: "Please select a valid .png or .jpg image!",
|
||||||
|
id: Toasts.genId(),
|
||||||
|
type: Toasts.Type.FAILURE
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
settings.trayIconPath = choice;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,4 +11,62 @@
|
||||||
|
|
||||||
.vcd-settings-title {
|
.vcd-settings-title {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@ export const enum IpcEvents {
|
||||||
SET_SETTINGS = "VCD_SET_SETTINGS",
|
SET_SETTINGS = "VCD_SET_SETTINGS",
|
||||||
|
|
||||||
SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR",
|
SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR",
|
||||||
|
|
||||||
SELECT_TRAY_ICON = "VCD_SELECT_TRAY_ICON",
|
SELECT_TRAY_ICON = "VCD_SELECT_TRAY_ICON",
|
||||||
|
GET_TRAY_ICON = "VCD_GET_TRAY_ICON",
|
||||||
|
|
||||||
UPDATER_GET_DATA = "VCD_UPDATER_GET_DATA",
|
UPDATER_GET_DATA = "VCD_UPDATER_GET_DATA",
|
||||||
UPDATER_DOWNLOAD = "VCD_UPDATER_DOWNLOAD",
|
UPDATER_DOWNLOAD = "VCD_UPDATER_DOWNLOAD",
|
||||||
|
|
Loading…
Add table
Reference in a new issue