aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml2
-rwxr-xr-xscripts/build/build.mjs48
-rw-r--r--src/Vencord.ts12
-rw-r--r--src/components/VencordSettings/Updater.tsx3
-rw-r--r--src/components/VencordSettings/VencordTab.tsx4
-rw-r--r--src/globals.d.ts3
-rw-r--r--src/main/index.ts108
-rw-r--r--src/main/ipcMain.ts (renamed from src/ipcMain/index.ts)10
-rw-r--r--src/main/patchWin32Updater.ts (renamed from src/patchWin32Updater.ts)0
-rw-r--r--src/main/patcher.ts (renamed from src/patcher.ts)92
-rw-r--r--src/main/updater/common.ts (renamed from src/ipcMain/updater/common.ts)0
-rw-r--r--src/main/updater/git.ts (renamed from src/ipcMain/updater/git.ts)0
-rw-r--r--src/main/updater/http.ts (renamed from src/ipcMain/updater/http.ts)24
-rw-r--r--src/main/updater/index.ts (renamed from src/ipcMain/updater/index.ts)0
-rw-r--r--src/main/utils/constants.ts (renamed from src/ipcMain/constants.ts)2
-rw-r--r--src/main/utils/crxToZip.ts (renamed from src/ipcMain/crxToZip.ts)0
-rw-r--r--src/main/utils/extensions.ts (renamed from src/ipcMain/extensions.ts)0
-rw-r--r--src/main/utils/simpleGet.ts (renamed from src/ipcMain/simpleGet.ts)0
-rw-r--r--src/plugins/consoleShortcuts.ts3
-rw-r--r--src/plugins/settings.tsx1
-rw-r--r--src/preload.ts4
-rw-r--r--src/utils/native.ts24
-rw-r--r--src/utils/settingsSync.ts42
-rw-r--r--src/utils/updater.ts7
-rw-r--r--src/webpack/webpack.ts2
25 files changed, 264 insertions, 127 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b7a95cf..f278707 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -42,7 +42,7 @@ jobs:
- name: Clean up obsolete files
run: |
- rm -rf dist/extension* Vencord.user.css
+ rm -rf dist/extension* Vencord.user.css vencordDesktopRenderer.css vencordDesktopRenderer.css.map
- name: Get some values needed for the release
id: release_values
diff --git a/scripts/build/build.mjs b/scripts/build/build.mjs
index 70a05cf..a4b06f5 100755
--- a/scripts/build/build.mjs
+++ b/scripts/build/build.mjs
@@ -48,6 +48,7 @@ const sourceMapFooter = s => watch ? "" : `//# sourceMappingURL=vencord://${s}.j
const sourcemap = watch ? "inline" : "external";
await Promise.all([
+ // common preload
esbuild.build({
...nodeCommonOpts,
entryPoints: ["src/preload.ts"],
@@ -55,12 +56,19 @@ await Promise.all([
footer: { js: "//# sourceURL=VencordPreload\n" + sourceMapFooter("preload") },
sourcemap,
}),
+
+ // Discord Desktop main & renderer
esbuild.build({
...nodeCommonOpts,
- entryPoints: ["src/patcher.ts"],
+ entryPoints: ["src/main/index.ts"],
outfile: "dist/patcher.js",
footer: { js: "//# sourceURL=VencordPatcher\n" + sourceMapFooter("patcher") },
sourcemap,
+ define: {
+ ...defines,
+ IS_DISCORD_DESKTOP: true,
+ IS_VENCORD_DESKTOP: false
+ }
}),
esbuild.build({
...commonOpts,
@@ -77,7 +85,43 @@ await Promise.all([
],
define: {
...defines,
- IS_WEB: false
+ IS_WEB: false,
+ IS_DISCORD_DESKTOP: true,
+ IS_VENCORD_DESKTOP: false
+ }
+ }),
+
+ // Vencord Desktop main & renderer
+ esbuild.build({
+ ...nodeCommonOpts,
+ entryPoints: ["src/main/index.ts"],
+ outfile: "dist/vencordDesktopMain.js",
+ footer: { js: "//# sourceURL=VencordDesktopMain\n" + sourceMapFooter("vencordDesktopMain") },
+ sourcemap,
+ define: {
+ ...defines,
+ IS_DISCORD_DESKTOP: false,
+ IS_VENCORD_DESKTOP: true
+ }
+ }),
+ esbuild.build({
+ ...commonOpts,
+ entryPoints: ["src/Vencord.ts"],
+ outfile: "dist/vencordDesktopRenderer.js",
+ format: "iife",
+ target: ["esnext"],
+ footer: { js: "//# sourceURL=VencordDesktopRenderer\n" + sourceMapFooter("vencordDesktopRenderer") },
+ globalName: "Vencord",
+ sourcemap,
+ plugins: [
+ globPlugins,
+ ...commonOpts.plugins
+ ],
+ define: {
+ ...defines,
+ IS_WEB: false,
+ IS_DISCORD_DESKTOP: false,
+ IS_VENCORD_DESKTOP: true
}
}),
]).catch(err => {
diff --git a/src/Vencord.ts b/src/Vencord.ts
index 00f8a58..73b53e8 100644
--- a/src/Vencord.ts
+++ b/src/Vencord.ts
@@ -30,7 +30,7 @@ import "./webpack/patchWebpack";
import { showNotification } from "./api/Notifications";
import { PlainSettings, Settings } from "./api/settings";
import { patches, PMLogger, startAllPlugins } from "./plugins";
-import { checkForUpdates, rebuild, update, UpdateLogger } from "./utils/updater";
+import { checkForUpdates, rebuild, update,UpdateLogger } from "./utils/updater";
import { onceReady } from "./webpack";
import { SettingsRouter } from "./webpack/common";
@@ -56,8 +56,12 @@ async function init() {
permanent: true,
noPersist: true,
onClick() {
- if (needsFullRestart)
- window.DiscordNative.app.relaunch();
+ if (needsFullRestart) {
+ if (IS_DISCORD_DESKTOP)
+ window.DiscordNative.app.relaunch();
+ else
+ window.VencordDesktop.app.relaunch();
+ }
else
location.reload();
}
@@ -96,7 +100,7 @@ async function init() {
init();
-if (!IS_WEB && Settings.winNativeTitleBar && navigator.platform.toLowerCase().startsWith("win")) {
+if (IS_DISCORD_DESKTOP && Settings.winNativeTitleBar && navigator.platform.toLowerCase().startsWith("win")) {
document.addEventListener("DOMContentLoaded", () => {
document.head.append(Object.assign(document.createElement("style"), {
id: "vencord-native-titlebar-style",
diff --git a/src/components/VencordSettings/Updater.tsx b/src/components/VencordSettings/Updater.tsx
index 3c3eb91..15a8c87 100644
--- a/src/components/VencordSettings/Updater.tsx
+++ b/src/components/VencordSettings/Updater.tsx
@@ -24,6 +24,7 @@ import { handleComponentFailed } from "@components/handleComponentFailed";
import { Link } from "@components/Link";
import { Margins } from "@utils/margins";
import { classes, useAwaiter } from "@utils/misc";
+import { relaunch } from "@utils/native";
import { changes, checkForUpdates, getRepo, isNewer, rebuild, update, updateError, UpdateLogger } from "@utils/updater";
import { Alerts, Button, Card, Forms, Parser, React, Switch, Toasts } from "@webpack/common";
@@ -133,7 +134,7 @@ function Updatable(props: CommonProps) {
cancelText: "Not now!",
onConfirm() {
if (needFullRestart)
- window.DiscordNative.app.relaunch();
+ relaunch();
else
location.reload();
r();
diff --git a/src/components/VencordSettings/VencordTab.tsx b/src/components/VencordSettings/VencordTab.tsx
index 7113421..8b86968 100644
--- a/src/components/VencordSettings/VencordTab.tsx
+++ b/src/components/VencordSettings/VencordTab.tsx
@@ -26,6 +26,7 @@ import { ErrorCard } from "@components/ErrorCard";
import IpcEvents from "@utils/IpcEvents";
import { Margins } from "@utils/margins";
import { identity, useAwaiter } from "@utils/misc";
+import { relaunch } from "@utils/native";
import { Button, Card, Forms, React, Select, Slider, Switch } from "@webpack/common";
const cl = classNameFactory("vc-settings-");
@@ -100,7 +101,7 @@ function VencordSettings() {
) : (
<React.Fragment>
<Button
- onClick={() => window.DiscordNative.app.relaunch()}
+ onClick={relaunch}
size={Button.Sizes.SMALL}>
Restart Client
</Button>
@@ -111,6 +112,7 @@ function VencordSettings() {
Open QuickCSS File
</Button>
<Button
+ // FIXME: Vencord Desktop support
onClick={() => window.DiscordNative.fileManager.showItemInFolder(settingsDir)}
size={Button.Sizes.SMALL}
disabled={settingsDirPending}>
diff --git a/src/globals.d.ts b/src/globals.d.ts
index 7c494e2..98eccde 100644
--- a/src/globals.d.ts
+++ b/src/globals.d.ts
@@ -35,6 +35,8 @@ declare global {
export var IS_WEB: boolean;
export var IS_DEV: boolean;
export var IS_STANDALONE: boolean;
+ export var IS_DISCORD_DESKTOP: boolean;
+ export var IS_VENCORD_DESKTOP: boolean;
export var VencordNative: typeof import("./VencordNative").default;
export var Vencord: typeof import("./Vencord");
@@ -54,6 +56,7 @@ declare global {
* If you really must use it, mark your plugin as Desktop App only by naming it Foo.desktop.ts(x)
*/
export var DiscordNative: any;
+ export var VencordDesktop: any;
interface Window {
webpackChunkdiscord_app: {
diff --git a/src/main/index.ts b/src/main/index.ts
new file mode 100644
index 0000000..c35635e
--- /dev/null
+++ b/src/main/index.ts
@@ -0,0 +1,108 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2023 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import { app, protocol, session } from "electron";
+import { join } from "path";
+
+import { getSettings } from "./ipcMain";
+import { IS_VANILLA } from "./utils/constants";
+import { installExt } from "./utils/extensions";
+
+if (IS_VENCORD_DESKTOP || !IS_VANILLA) {
+ app.whenReady().then(() => {
+ // Source Maps! Maybe there's a better way but since the renderer is executed
+ // from a string I don't think any other form of sourcemaps would work
+ protocol.registerFileProtocol("vencord", ({ url: unsafeUrl }, cb) => {
+ let url = unsafeUrl.slice("vencord://".length);
+ if (url.endsWith("/")) url = url.slice(0, -1);
+ switch (url) {
+ case "renderer.js.map":
+ case "preload.js.map":
+ case "patcher.js.map": // doubt
+ cb(join(__dirname, url));
+ break;
+ default:
+ cb({ statusCode: 403 });
+ }
+ });
+
+ try {
+ if (getSettings().enableReactDevtools)
+ installExt("fmkadmapgofadopljbjfkapdkoienihi")
+ .then(() => console.info("[Vencord] Installed React Developer Tools"))
+ .catch(err => console.error("[Vencord] Failed to install React Developer Tools", err));
+ } catch { }
+
+
+ // Remove CSP
+ type PolicyResult = Record<string, string[]>;
+
+ const parsePolicy = (policy: string): PolicyResult => {
+ const result: PolicyResult = {};
+ policy.split(";").forEach(directive => {
+ const [directiveKey, ...directiveValue] = directive.trim().split(/\s+/g);
+ if (directiveKey && !Object.prototype.hasOwnProperty.call(result, directiveKey)) {
+ result[directiveKey] = directiveValue;
+ }
+ });
+ return result;
+ };
+ const stringifyPolicy = (policy: PolicyResult): string =>
+ Object.entries(policy)
+ .filter(([, values]) => values?.length)
+ .map(directive => directive.flat().join(" "))
+ .join("; ");
+
+ function patchCsp(headers: Record<string, string[]>, header: string) {
+ if (header in headers) {
+ const csp = parsePolicy(headers[header][0]);
+
+ for (const directive of ["style-src", "connect-src", "img-src", "font-src", "media-src", "worker-src"]) {
+ csp[directive] = ["*", "blob:", "data:", "'unsafe-inline'"];
+ }
+ // TODO: Restrict this to only imported packages with fixed version.
+ // Perhaps auto generate with esbuild
+ csp["script-src"] ??= [];
+ csp["script-src"].push("'unsafe-eval'", "https://unpkg.com", "https://cdnjs.cloudflare.com");
+ headers[header] = [stringifyPolicy(csp)];
+ }
+ }
+
+ session.defaultSession.webRequest.onHeadersReceived(({ responseHeaders, resourceType }, cb) => {
+ if (responseHeaders) {
+ if (resourceType === "mainFrame")
+ patchCsp(responseHeaders, "content-security-policy");
+
+ // Fix hosts that don't properly set the css content type, such as
+ // raw.githubusercontent.com
+ if (resourceType === "stylesheet")
+ responseHeaders["content-type"] = ["text/css"];
+ }
+ cb({ cancel: false, responseHeaders });
+ });
+
+ // assign a noop to onHeadersReceived to prevent other mods from adding their own incompatible ones.
+ // For instance, OpenAsar adds their own that doesn't fix content-type for stylesheets which makes it
+ // impossible to load css from github raw despite our fix above
+ session.defaultSession.webRequest.onHeadersReceived = () => { };
+ });
+}
+
+if (IS_DISCORD_DESKTOP) {
+ require("./patcher");
+}
diff --git a/src/ipcMain/index.ts b/src/main/ipcMain.ts
index 6fb31d1..b0f8fc3 100644
--- a/src/ipcMain/index.ts
+++ b/src/main/ipcMain.ts
@@ -28,7 +28,7 @@ import { join } from "path";
import monacoHtml from "~fileContent/../components/monacoWin.html;base64";
-import { ALLOWED_PROTOCOLS, QUICKCSS_PATH, SETTINGS_DIR, SETTINGS_FILE } from "./constants";
+import { ALLOWED_PROTOCOLS, QUICKCSS_PATH, SETTINGS_DIR, SETTINGS_FILE } from "./utils/constants";
mkdirSync(SETTINGS_DIR, { recursive: true });
@@ -44,6 +44,14 @@ export function readSettings() {
}
}
+export function getSettings(): typeof import("@api/settings").Settings {
+ try {
+ return JSON.parse(readSettings());
+ } catch {
+ return {} as any;
+ }
+}
+
ipcMain.handle(IpcEvents.OPEN_QUICKCSS, () => shell.openPath(QUICKCSS_PATH));
ipcMain.handle(IpcEvents.OPEN_EXTERNAL, (_, url) => {
diff --git a/src/patchWin32Updater.ts b/src/main/patchWin32Updater.ts
index e08e37d..e08e37d 100644
--- a/src/patchWin32Updater.ts
+++ b/src/main/patchWin32Updater.ts
diff --git a/src/patcher.ts b/src/main/patcher.ts
index b1f47b0..c45a299 100644
--- a/src/patcher.ts
+++ b/src/main/patcher.ts
@@ -17,12 +17,11 @@
*/
import { onceDefined } from "@utils/onceDefined";
-import electron, { app, BrowserWindowConstructorOptions, Menu, protocol, session } from "electron";
+import electron, { app, BrowserWindowConstructorOptions, Menu } from "electron";
import { dirname, join } from "path";
-import { initIpc } from "./ipcMain";
-import { installExt } from "./ipcMain/extensions";
-import { readSettings } from "./ipcMain/index";
+import { getSettings, initIpc } from "./ipcMain";
+import { IS_VANILLA } from "./utils/constants";
console.log("[Vencord] Starting up...");
@@ -41,11 +40,8 @@ require.main!.filename = join(asarPath, discordPkg.main);
// @ts-ignore Untyped method? Dies from cringe
app.setAppPath(asarPath);
-if (!process.argv.includes("--vanilla")) {
- let settings: typeof import("@api/settings").Settings = {} as any;
- try {
- settings = JSON.parse(readSettings());
- } catch { }
+if (!IS_VANILLA) {
+ const settings = getSettings();
// Repatch after host updates on Windows
if (process.platform === "win32") {
@@ -116,84 +112,6 @@ if (!process.argv.includes("--vanilla")) {
);
process.env.DATA_DIR = join(app.getPath("userData"), "..", "Vencord");
-
- app.whenReady().then(() => {
- // Source Maps! Maybe there's a better way but since the renderer is executed
- // from a string I don't think any other form of sourcemaps would work
- protocol.registerFileProtocol("vencord", ({ url: unsafeUrl }, cb) => {
- let url = unsafeUrl.slice("vencord://".length);
- if (url.endsWith("/")) url = url.slice(0, -1);
- switch (url) {
- case "renderer.js.map":
- case "preload.js.map":
- case "patcher.js.map": // doubt
- cb(join(__dirname, url));
- break;
- default:
- cb({ statusCode: 403 });
- }
- });
-
- try {
- if (settings?.enableReactDevtools)
- installExt("fmkadmapgofadopljbjfkapdkoienihi")
- .then(() => console.info("[Vencord] Installed React Developer Tools"))
- .catch(err => console.error("[Vencord] Failed to install React Developer Tools", err));
- } catch { }
-
-
- // Remove CSP
- type PolicyResult = Record<string, string[]>;
-
- const parsePolicy = (policy: string): PolicyResult => {
- const result: PolicyResult = {};
- policy.split(";").forEach(directive => {
- const [directiveKey, ...directiveValue] = directive.trim().split(/\s+/g);
- if (directiveKey && !Object.prototype.hasOwnProperty.call(result, directiveKey)) {
- result[directiveKey] = directiveValue;
- }
- });
- return result;
- };
- const stringifyPolicy = (policy: PolicyResult): string =>
- Object.entries(policy)
- .filter(([, values]) => values?.length)
- .map(directive => directive.flat().join(" "))
- .join("; ");
-
- function patchCsp(headers: Record<string, string[]>, header: string) {
- if (header in headers) {
- const csp = parsePolicy(headers[header][0]);
-
- for (const directive of ["style-src", "connect-src", "img-src", "font-src", "media-src", "worker-src"]) {
- csp[directive] = ["*", "blob:", "data:", "'unsafe-inline'"];
- }
- // TODO: Restrict this to only imported packages with fixed version.
- // Perhaps auto generate with esbuild
- csp["script-src"] ??= [];
- csp["script-src"].push("'unsafe-eval'", "https://unpkg.com", "https://cdnjs.cloudflare.com");
- headers[header] = [stringifyPolicy(csp)];
- }
- }
-
- session.defaultSession.webRequest.onHeadersReceived(({ responseHeaders, resourceType }, cb) => {
- if (responseHeaders) {
- if (resourceType === "mainFrame")
- patchCsp(responseHeaders, "content-security-policy");
-
- // Fix hosts that don't properly set the css content type, such as
- // raw.githubusercontent.com
- if (resourceType === "stylesheet")
- responseHeaders["content-type"] = ["text/css"];
- }
- cb({ cancel: false, responseHeaders });
- });
-
- // assign a noop to onHeadersReceived to prevent other mods from adding their own incompatible ones.
- // For instance, OpenAsar adds their own that doesn't fix content-type for stylesheets which makes it
- // impossible to load css from github raw despite our fix above
- session.defaultSession.webRequest.onHeadersReceived = () => { };
- });
} else {
console.log("[Vencord] Running in vanilla mode. Not loading Vencord");
}
diff --git a/src/ipcMain/updater/common.ts b/src/main/updater/common.ts
index 3729c6d..3729c6d 100644
--- a/src/ipcMain/updater/common.ts
+++ b/src/main/updater/common.ts
diff --git a/src/ipcMain/updater/git.ts b/src/main/updater/git.ts
index 89c2d3c..89c2d3c 100644
--- a/src/ipcMain/updater/git.ts
+++ b/src/main/updater/git.ts
diff --git a/src/ipcMain/updater/http.ts b/src/main/updater/http.ts
index cc10631..a2e2aad 100644
--- a/src/ipcMain/updater/http.ts
+++ b/src/main/updater/http.ts
@@ -25,7 +25,7 @@ import { join } from "path";
import gitHash from "~git-hash";
import gitRemote from "~git-remote";
-import { get } from "../simpleGet";
+import { get } from "../utils/simpleGet";
import { calculateHashes, serializeErrors } from "./common";
const API_BASE = `https://api.github.com/repos/${gitRemote}`;
@@ -57,6 +57,13 @@ async function calculateGitChanges() {
}));
}
+const FILES_TO_DOWNLOAD = [
+ IS_DISCORD_DESKTOP ? "patcher.js" : "vencordDesktopMain.js",
+ "preload.js",
+ IS_DISCORD_DESKTOP ? "renderer.js" : "vencordDesktopRenderer.js",
+ "renderer.css"
+];
+
async function fetchUpdates() {
const release = await githubGet("/releases/latest");
@@ -66,7 +73,7 @@ async function fetchUpdates() {
return false;
data.assets.forEach(({ name, browser_download_url }) => {
- if (["patcher.js", "preload.js", "renderer.js", "renderer.css"].some(s => name.startsWith(s))) {
+ if (FILES_TO_DOWNLOAD.some(s => name.startsWith(s))) {
PendingUpdates.push([name, browser_download_url]);
}
});
@@ -75,8 +82,17 @@ async function fetchUpdates() {
async function applyUpdates() {
await Promise.all(PendingUpdates.map(
- async ([name, data]) => writeFile(join(__dirname, name), await get(data)))
- );
+ async ([name, data]) => writeFile(
+ join(
+ __dirname,
+ IS_VENCORD_DESKTOP
+ // vencordDesktopRenderer.js -> renderer.js
+ ? name.replace(/vencordDesktop(\w)/, (_, c) => c.toLowerCase())
+ : name
+ ),
+ await get(data)
+ )
+ ));
PendingUpdates = [];
return true;
}
diff --git a/src/ipcMain/updater/index.ts b/src/main/updater/index.ts
index 7036112..7036112 100644
--- a/src/ipcMain/updater/index.ts
+++ b/src/main/updater/index.ts
diff --git a/src/ipcMain/constants.ts b/src/main/utils/constants.ts
index 7133757..cc9f459 100644
--- a/src/ipcMain/constants.ts
+++ b/src/main/utils/constants.ts
@@ -33,3 +33,5 @@ export const ALLOWED_PROTOCOLS = [
"steam:",
"spotify:"
];
+
+export const IS_VANILLA = /* @__PURE__ */ process.argv.includes("--vanilla");
diff --git a/src/ipcMain/crxToZip.ts b/src/main/utils/crxToZip.ts
index ca43890..ca43890 100644
--- a/src/ipcMain/crxToZip.ts
+++ b/src/main/utils/crxToZip.ts
diff --git a/src/ipcMain/extensions.ts b/src/main/utils/extensions.ts
index d8f8437..d8f8437 100644
--- a/src/ipcMain/extensions.ts
+++ b/src/main/utils/extensions.ts
diff --git a/src/ipcMain/simpleGet.ts b/src/main/utils/simpleGet.ts
index 1a8302c..1a8302c 100644
--- a/src/ipcMain/simpleGet.ts
+++ b/src/main/utils/simpleGet.ts
diff --git a/src/plugins/consoleShortcuts.ts b/src/plugins/consoleShortcuts.ts
index 70a9875..056d246 100644
--- a/src/plugins/consoleShortcuts.ts
+++ b/src/plugins/consoleShortcuts.ts
@@ -17,6 +17,7 @@
*/
import { Devs } from "@utils/constants";
+import { relaunch } from "@utils/native";
import definePlugin from "@utils/types";
import * as Webpack from "@webpack";
import { extract, filters, findAll, search } from "@webpack";
@@ -77,7 +78,7 @@ export default definePlugin({
Settings: Vencord.Settings,
Api: Vencord.Api,
reload: () => location.reload(),
- restart: IS_WEB ? WEB_ONLY("restart") : window.DiscordNative.app.relaunch
+ restart: IS_WEB ? WEB_ONLY("restart") : relaunch
};
},
diff --git a/src/plugins/settings.tsx b/src/plugins/settings.tsx
index 67d1f8d..8db0a4e 100644
--- a/src/plugins/settings.tsx
+++ b/src/plugins/settings.tsx
@@ -168,6 +168,7 @@ export default definePlugin({
get additionalInfo() {
if (IS_DEV) return " (Dev)";
if (IS_WEB) return " (Web)";
+ if (IS_VENCORD_DESKTOP) return " (Vencord Desktop)";
if (IS_STANDALONE) return " (Standalone)";
return "";
},
diff --git a/src/preload.ts b/src/preload.ts
index 820b655..b75574a 100644
--- a/src/preload.ts
+++ b/src/preload.ts
@@ -54,7 +54,9 @@ if (location.protocol !== "data:") {
document.getElementById("vencord-css-core")!.textContent = readFileSync(rendererCss, "utf-8");
});
}
- require(process.env.DISCORD_PRELOAD!);
+
+ if (process.env.DISCORD_PRELOAD)
+ require(process.env.DISCORD_PRELOAD);
} else {
// Monaco Popout
contextBridge.exposeInMainWorld("setCss", debounce(s => VencordNative.ipc.invoke(IpcEvents.SET_QUICK_CSS, s)));
diff --git a/src/utils/native.ts b/src/utils/native.ts
new file mode 100644
index 0000000..70e4c0e
--- /dev/null
+++ b/src/utils/native.ts
@@ -0,0 +1,24 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2023 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+export function relaunch() {
+ if (IS_DISCORD_DESKTOP)
+ window.DiscordNative.app.relaunch();
+ else
+ window.VencordDesktop.app.relaunch();
+}
diff --git a/src/utils/settingsSync.ts b/src/utils/settingsSync.ts
index 18e1854..781899f 100644
--- a/src/utils/settingsSync.ts
+++ b/src/utils/settingsSync.ts
@@ -47,7 +47,9 @@ export async function downloadSettingsBackup() {
const backup = await exportSettings();
const data = new TextEncoder().encode(backup);
- if (IS_WEB) {
+ if (IS_DISCORD_DESKTOP) {
+ DiscordNative.fileManager.saveWithDialog(data, filename);
+ } else {
const file = new File([data], filename, { type: "application/json" });
const a = document.createElement("a");
a.href = URL.createObjectURL(file);
@@ -59,8 +61,6 @@ export async function downloadSettingsBackup() {
URL.revokeObjectURL(a.href);
document.body.removeChild(a);
});
- } else {
- DiscordNative.fileManager.saveWithDialog(data, filename);
}
}
@@ -77,7 +77,24 @@ const toastFailure = (err: any) => Toasts.show({
});
export async function uploadSettingsBackup(showToast = true): Promise<void> {
- if (IS_WEB) {
+ if (IS_DISCORD_DESKTOP) {
+ const [file] = await DiscordNative.fileManager.openFiles({
+ filters: [
+ { name: "Vencord Settings Backup", extensions: ["json"] },
+ { name: "all", extensions: ["*"] }
+ ]
+ });
+
+ if (file) {
+ try {
+ await importSettings(new TextDecoder().decode(file.data));
+ if (showToast) toastSuccess();
+ } catch (err) {
+ new Logger("SettingsSync").error(err);
+ if (showToast) toastFailure(err);
+ }
+ }
+ } else {
const input = document.createElement("input");
input.type = "file";
input.style.display = "none";
@@ -102,22 +119,5 @@ export async function uploadSettingsBackup(showToast = true): Promise<void> {
document.body.appendChild(input);
input.click();
setImmediate(() => document.body.removeChild(input));
- } else {
- const [file] = await DiscordNative.fileManager.openFiles({
- filters: [
- { name: "Vencord Settings Backup", extensions: ["json"] },
- { name: "all", extensions: ["*"] }
- ]
- });
-
- if (file) {
- try {
- await importSettings(new TextDecoder().decode(file.data));
- if (showToast) toastSuccess();
- } catch (err) {
- new Logger("SettingsSync").error(err);
- if (showToast) toastFailure(err);
- }
- }
}
}
diff --git a/src/utils/updater.ts b/src/utils/updater.ts
index e13f5cf..d0b1fdc 100644
--- a/src/utils/updater.ts
+++ b/src/utils/updater.ts
@@ -20,6 +20,7 @@ import gitHash from "~git-hash";
import IpcEvents from "./IpcEvents";
import Logger from "./Logger";
+import { relaunch } from "./native";
import { IpcRes } from "./types";
export const UpdateLogger = /* #__PURE__*/ new Logger("Updater", "white");
@@ -90,8 +91,10 @@ export async function maybePromptToUpdate(confirmMessage: string, checkForDev =
if (wantsUpdate) {
await update();
const needFullRestart = await rebuild();
- if (needFullRestart) DiscordNative.app.relaunch();
- else location.reload();
+ if (needFullRestart)
+ relaunch();
+ else
+ location.reload();
}
}
} catch (err) {
diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts
index 0d95587..a37fe6d 100644
--- a/src/webpack/webpack.ts
+++ b/src/webpack/webpack.ts
@@ -67,7 +67,7 @@ export function _initWebpack(instance: typeof window.webpackChunkdiscord_app) {
instance.pop();
}
-if (IS_DEV && !IS_WEB) {
+if (IS_DEV && IS_DISCORD_DESKTOP) {
var devToolsOpen = false;
// At this point in time, DiscordNative has not been exposed yet, so setImmediate is needed
setTimeout(() => {