Merge 60adb1f98d
into ec3d83f7ca
This commit is contained in:
commit
5c71632c34
10 changed files with 187 additions and 13 deletions
|
@ -18,6 +18,7 @@ export const PORTABLE =
|
||||||
const LEGACY_DATA_DIR = join(app.getPath("appData"), "VencordDesktop", "VencordDesktop");
|
const LEGACY_DATA_DIR = join(app.getPath("appData"), "VencordDesktop", "VencordDesktop");
|
||||||
export const DATA_DIR =
|
export const DATA_DIR =
|
||||||
process.env.VENCORD_USER_DATA_DIR || (PORTABLE ? join(vesktopDir, "Data") : join(app.getPath("userData")));
|
process.env.VENCORD_USER_DATA_DIR || (PORTABLE ? join(vesktopDir, "Data") : join(app.getPath("userData")));
|
||||||
|
export const TRAY_ICON_PATH = join(DATA_DIR, "settings", "tray_icon");
|
||||||
|
|
||||||
mkdirSync(DATA_DIR, { recursive: true });
|
mkdirSync(DATA_DIR, { recursive: true });
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,17 @@ if (process.platform === "linux") import("./venmic");
|
||||||
|
|
||||||
import { execFile } from "child_process";
|
import { execFile } from "child_process";
|
||||||
import { app, BrowserWindow, clipboard, dialog, nativeImage, RelaunchOptions, session, shell } from "electron";
|
import { app, BrowserWindow, clipboard, dialog, nativeImage, RelaunchOptions, session, shell } from "electron";
|
||||||
import { mkdirSync, readFileSync, watch } from "fs";
|
import { copyFileSync, 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";
|
||||||
import { setBadgeCount } from "./appBadge";
|
import { setBadgeCount } from "./appBadge";
|
||||||
import { autoStart } from "./autoStart";
|
import { autoStart } from "./autoStart";
|
||||||
import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants";
|
import { TRAY_ICON_PATH, VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants";
|
||||||
import { mainWin } from "./mainWindow";
|
import { mainWin } from "./mainWindow";
|
||||||
import { Settings } from "./settings";
|
import { Settings } from "./settings";
|
||||||
import { handle, handleSync } from "./utils/ipcWrappers";
|
import { handle, handleSync } from "./utils/ipcWrappers";
|
||||||
|
@ -41,6 +42,13 @@ handleSync(
|
||||||
() => process.platform === "win32" && Number(release().split(".").pop()) >= 22621
|
() => process.platform === "win32" && Number(release().split(".").pop()) >= 22621
|
||||||
);
|
);
|
||||||
|
|
||||||
|
handleSync(IpcEvents.GET_TRAY_ICON, () => {
|
||||||
|
if (!Settings.store.trayIconPath) return nativeImage.createFromPath(ICON_PATH).toDataURL();
|
||||||
|
const img = nativeImage.createFromPath(TRAY_ICON_PATH).resize({ width: 64, height: 64 });
|
||||||
|
if (img.isEmpty()) return nativeImage.createFromPath(ICON_PATH).toDataURL();
|
||||||
|
return img.toDataURL();
|
||||||
|
});
|
||||||
|
|
||||||
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);
|
||||||
|
@ -117,6 +125,20 @@ handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
|
||||||
return dir;
|
return dir;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
handle(IpcEvents.SELECT_TRAY_ICON, async () => {
|
||||||
|
const res = await dialog.showOpenDialog(mainWin!, {
|
||||||
|
properties: ["openFile"],
|
||||||
|
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";
|
||||||
|
copyFileSync(dir, TRAY_ICON_PATH);
|
||||||
|
return dir;
|
||||||
|
});
|
||||||
|
|
||||||
handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count));
|
handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count));
|
||||||
|
|
||||||
handle(IpcEvents.CLIPBOARD_COPY_IMAGE, async (_, buf: ArrayBuffer, src: string) => {
|
handle(IpcEvents.CLIPBOARD_COPY_IMAGE, async (_, buf: ArrayBuffer, src: string) => {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
dialog,
|
dialog,
|
||||||
Menu,
|
Menu,
|
||||||
MenuItemConstructorOptions,
|
MenuItemConstructorOptions,
|
||||||
|
nativeImage,
|
||||||
nativeTheme,
|
nativeTheme,
|
||||||
screen,
|
screen,
|
||||||
session,
|
session,
|
||||||
|
@ -34,6 +35,7 @@ import {
|
||||||
MessageBoxChoice,
|
MessageBoxChoice,
|
||||||
MIN_HEIGHT,
|
MIN_HEIGHT,
|
||||||
MIN_WIDTH,
|
MIN_WIDTH,
|
||||||
|
TRAY_ICON_PATH,
|
||||||
VENCORD_FILES_DIR
|
VENCORD_FILES_DIR
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
import { Settings, State, VencordSettings } from "./settings";
|
import { Settings, State, VencordSettings } from "./settings";
|
||||||
|
@ -122,8 +124,16 @@ function initTray(win: BrowserWindow) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
var trayImage = nativeImage.createFromPath(ICON_PATH);
|
||||||
|
if (Settings.store.trayIconPath) trayImage = nativeImage.createFromPath(TRAY_ICON_PATH);
|
||||||
|
if (trayImage.isEmpty()) trayImage = nativeImage.createFromPath(ICON_PATH);
|
||||||
|
|
||||||
|
if (process.platform === "darwin") {
|
||||||
|
tray = new Tray(trayImage.resize({ width: 16, height: 16 }));
|
||||||
|
} else {
|
||||||
|
tray = new Tray(trayImage.resize({ width: 32, height: 32 }));
|
||||||
|
}
|
||||||
|
|
||||||
tray = new Tray(ICON_PATH);
|
|
||||||
tray.setToolTip("Vesktop");
|
tray.setToolTip("Vesktop");
|
||||||
tray.setContextMenu(trayMenu);
|
tray.setContextMenu(trayMenu);
|
||||||
tray.on("click", onTrayClick);
|
tray.on("click", onTrayClick);
|
||||||
|
@ -333,6 +343,10 @@ function initSettingsListeners(win: BrowserWindow) {
|
||||||
if (enable) initTray(win);
|
if (enable) initTray(win);
|
||||||
else tray?.destroy();
|
else tray?.destroy();
|
||||||
});
|
});
|
||||||
|
addSettingsListener("trayIconPath", _ => {
|
||||||
|
tray?.destroy();
|
||||||
|
initTray(win);
|
||||||
|
});
|
||||||
addSettingsListener("disableMinSize", disable => {
|
addSettingsListener("disableMinSize", disable => {
|
||||||
if (disable) {
|
if (disable) {
|
||||||
// 0 no work
|
// 0 no work
|
||||||
|
@ -447,7 +461,7 @@ function createMainWindow() {
|
||||||
if (Settings.store.staticTitle) win.on("page-title-updated", e => e.preventDefault());
|
if (Settings.store.staticTitle) win.on("page-title-updated", e => e.preventDefault());
|
||||||
|
|
||||||
initWindowBoundsListeners(win);
|
initWindowBoundsListeners(win);
|
||||||
if (!isDeckGameMode && (Settings.store.tray ?? true) && process.platform !== "darwin") initTray(win);
|
if (!isDeckGameMode && (Settings.store.tray ?? true)) initTray(win);
|
||||||
initMenuBar(win);
|
initMenuBar(win);
|
||||||
makeLinksOpenExternally(win);
|
makeLinksOpenExternally(win);
|
||||||
initSettingsListeners(win);
|
initSettingsListeners(win);
|
||||||
|
|
|
@ -34,7 +34,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)
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
get: () => sendSync<Settings>(IpcEvents.GET_SETTINGS),
|
get: () => sendSync<Settings>(IpcEvents.GET_SETTINGS),
|
||||||
|
@ -57,6 +58,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,6 +14,7 @@ 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 { TrayIconImagePicker } from "./TrayIconImagePicker";
|
||||||
import { VencordLocationPicker } from "./VencordLocationPicker";
|
import { VencordLocationPicker } from "./VencordLocationPicker";
|
||||||
import { WindowsTransparencyControls } from "./WindowsTransparencyControls";
|
import { WindowsTransparencyControls } from "./WindowsTransparencyControls";
|
||||||
|
|
||||||
|
@ -68,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",
|
||||||
|
@ -126,6 +120,7 @@ const SettingsOptions: Record<string, Array<BooleanSetting | SettingsComponent>>
|
||||||
defaultValue: false
|
defaultValue: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"Tray Icon Image": [TrayIconImagePicker],
|
||||||
"Vencord Location": [VencordLocationPicker]
|
"Vencord Location": [VencordLocationPicker]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
74
src/renderer/components/settings/TrayIconImagePicker.tsx
Normal file
74
src/renderer/components/settings/TrayIconImagePicker.tsx
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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 { findByPropsLazy } from "@vencord/types/webpack";
|
||||||
|
import { Forms, Switch, Toasts } from "@vencord/types/webpack/common";
|
||||||
|
import { Settings } from "renderer/settings";
|
||||||
|
|
||||||
|
import { SettingsComponent } from "./Settings";
|
||||||
|
|
||||||
|
const { PencilIcon } = findByPropsLazy("PencilIcon");
|
||||||
|
|
||||||
|
export const TrayIconImagePicker: SettingsComponent = ({ settings }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div id="vcd-tray-setting">
|
||||||
|
<div className="vcd-tray-setting-switch">
|
||||||
|
<Switch
|
||||||
|
key="tray"
|
||||||
|
value={Settings.store.tray ?? false}
|
||||||
|
onChange={v => (Settings.store.tray = v)}
|
||||||
|
note={"Add a tray icon for Vesktop"}
|
||||||
|
>
|
||||||
|
Tray Icon
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
<div className="vcd-tray-setting-reset">
|
||||||
|
<Forms.FormText>
|
||||||
|
<a
|
||||||
|
href="about:blank"
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault();
|
||||||
|
settings.trayIconPath = void 0;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</a>
|
||||||
|
</Forms.FormText>
|
||||||
|
</div>
|
||||||
|
<div className="vcd-tray-icon-wrap">
|
||||||
|
<img
|
||||||
|
className="vcd-tray-icon-image"
|
||||||
|
src={VesktopNative.tray.getTrayIcon()}
|
||||||
|
alt="hello"
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
></img>
|
||||||
|
<PencilIcon
|
||||||
|
className="vcd-edit-button"
|
||||||
|
width="40"
|
||||||
|
height="40"
|
||||||
|
onClick={async () => {
|
||||||
|
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;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -12,3 +12,56 @@
|
||||||
.vcd-settings-title {
|
.vcd-settings-title {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#vcd-tray-setting {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
|
||||||
|
}
|
||||||
|
.vcd-tray-setting-switch {
|
||||||
|
flex-grow: 1;
|
||||||
|
align-self: flex-start;
|
||||||
|
margin-right: 20rem;
|
||||||
|
}
|
||||||
|
.vcd-tray-setting-reset {
|
||||||
|
align-self: right;
|
||||||
|
position: relative;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 1em;
|
||||||
|
bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-tray-icon-wrap {
|
||||||
|
position: relative;
|
||||||
|
align-self: right;
|
||||||
|
bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-tray-icon-image {
|
||||||
|
border-radius: 50%;
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-edit-button {
|
||||||
|
visibility: visible;
|
||||||
|
display: block;
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 3px;
|
||||||
|
left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-tray-icon-wrap:hover .vcd-tray-icon-image {
|
||||||
|
transition: 0.3s ease;
|
||||||
|
background-color: rgb(0, 0, 0) no-repeat;
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
.vcd-tray-icon-wrap:hover .vcd-edit-button {
|
||||||
|
transition: 0.3s ease;
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ export const enum IpcEvents {
|
||||||
|
|
||||||
SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR",
|
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_GET_DATA = "VCD_UPDATER_GET_DATA",
|
||||||
UPDATER_DOWNLOAD = "VCD_UPDATER_DOWNLOAD",
|
UPDATER_DOWNLOAD = "VCD_UPDATER_DOWNLOAD",
|
||||||
UPDATE_IGNORE = "VCD_UPDATE_IGNORE",
|
UPDATE_IGNORE = "VCD_UPDATE_IGNORE",
|
||||||
|
|
1
src/shared/settings.d.ts
vendored
1
src/shared/settings.d.ts
vendored
|
@ -22,6 +22,7 @@ export interface Settings {
|
||||||
disableMinSize?: boolean;
|
disableMinSize?: boolean;
|
||||||
clickTrayToShowHide?: boolean;
|
clickTrayToShowHide?: boolean;
|
||||||
customTitleBar?: boolean;
|
customTitleBar?: boolean;
|
||||||
|
trayIconPath?: string;
|
||||||
|
|
||||||
checkUpdates?: boolean;
|
checkUpdates?: boolean;
|
||||||
|
|
||||||
|
|
7
static/pencil-edit-icon.svg
Normal file
7
static/pencil-edit-icon.svg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||||
|
<svg fill="#ffffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="64px" viewBox="-105.78 -105.78 740.46 740.46" xml:space="preserve" style="--darkreader-inline-fill: #181a1b; --darkreader-inline-stroke: #e8e6e3;" data-darkreader-inline-fill="" stroke="#ffffff" data-darkreader-inline-stroke="">
|
||||||
|
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||||
|
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<g id="SVGRepo_iconCarrier"> <g> <path d="M328.883,89.125l107.59,107.589l-272.34,272.34L56.604,361.465L328.883,89.125z M518.113,63.177l-47.981-47.981 c-18.543-18.543-48.653-18.543-67.259,0l-45.961,45.961l107.59,107.59l53.611-53.611 C532.495,100.753,532.495,77.559,518.113,63.177z M0.3,512.69c-1.958,8.812,5.998,16.708,14.811,14.565l119.891-29.069 L27.473,390.597L0.3,512.69z"/> </g> </g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
Reference in a new issue