aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/build/build.mjs9
-rwxr-xr-xscripts/build/buildWeb.mjs5
-rw-r--r--scripts/build/common.mjs51
-rw-r--r--src/components/Monaco.ts74
-rw-r--r--src/components/Settings.tsx2
-rw-r--r--src/components/monacoWin.html52
-rw-r--r--src/ipcMain/index.ts20
-rw-r--r--src/modules.d.ts5
-rw-r--r--src/preload.ts15
-rw-r--r--src/utils/IpcEvents.ts3
-rw-r--r--src/utils/Queue.ts27
11 files changed, 173 insertions, 90 deletions
diff --git a/scripts/build/build.mjs b/scripts/build/build.mjs
index f6304b1..1986369 100755
--- a/scripts/build/build.mjs
+++ b/scripts/build/build.mjs
@@ -18,7 +18,7 @@
*/
import esbuild from "esbuild";
-import { commonOpts, gitHashPlugin, globPlugins, makeAllPackagesExternalPlugin } from "./common.mjs";
+import { commonOpts, fileIncludePlugin, gitHashPlugin, globPlugins, makeAllPackagesExternalPlugin } from "./common.mjs";
/**
* @type {esbuild.BuildOptions}
@@ -30,7 +30,7 @@ const nodeCommonOpts = {
target: ["esnext"],
minify: true,
sourcemap: "linked",
- plugins: [makeAllPackagesExternalPlugin],
+ plugins: [...commonOpts.plugins, makeAllPackagesExternalPlugin],
};
await Promise.all([
@@ -55,7 +55,8 @@ await Promise.all([
external: ["plugins", "git-hash"],
plugins: [
globPlugins,
- gitHashPlugin
+ gitHashPlugin,
+ fileIncludePlugin
],
define: {
IS_WEB: "false"
@@ -65,6 +66,6 @@ await Promise.all([
console.error("Build failed");
console.error(err.message);
// make ci fail
- if (!watch)
+ if (!commonOpts.watch)
process.exitCode = 1;
});
diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs
index 8abac2c..286aad3 100755
--- a/scripts/build/buildWeb.mjs
+++ b/scripts/build/buildWeb.mjs
@@ -23,7 +23,7 @@ import yazl from "yazl";
import esbuild from "esbuild";
// wtf is this assert syntax
import PackageJSON from "../../package.json" assert { type: "json" };
-import { commonOpts, gitHashPlugin, globPlugins } from "./common.mjs";
+import { commonOpts, fileIncludePlugin, gitHashPlugin, globPlugins } from "./common.mjs";
/**
* @type {esbuild.BuildOptions}
@@ -36,7 +36,8 @@ const commonOptions = {
external: ["plugins", "git-hash"],
plugins: [
globPlugins,
- gitHashPlugin
+ gitHashPlugin,
+ fileIncludePlugin
],
target: ["esnext"],
define: {
diff --git a/scripts/build/common.mjs b/scripts/build/common.mjs
index 6143fb2..c3afc7f 100644
--- a/scripts/build/common.mjs
+++ b/scripts/build/common.mjs
@@ -19,22 +19,11 @@
import { execSync } from "child_process";
import esbuild from "esbuild";
import { existsSync } from "fs";
-import { readdir } from "fs/promises";
+import { readdir, readFile } from "fs/promises";
+import { join } from "path";
const watch = process.argv.includes("--watch");
-/**
- * @type {esbuild.BuildOptions}
- */
-export const commonOpts = {
- logLevel: "info",
- bundle: true,
- watch,
- minify: !watch,
- sourcemap: watch ? "inline" : "",
- legalComments: "linked"
-};
-
// https://github.com/evanw/esbuild/issues/619#issuecomment-751995294
/**
* @type {esbuild.Plugin}
@@ -103,3 +92,39 @@ export const gitHashPlugin = {
}));
}
};
+
+/**
+ * @type {esbuild.Plugin}
+ */
+export const fileIncludePlugin = {
+ name: "file-include-plugin",
+ setup: build => {
+ const filter = /^@fileContent\/.+$/;
+ build.onResolve({ filter }, args => ({
+ namespace: "include-file",
+ path: args.path,
+ pluginData: {
+ path: join(args.resolveDir, args.path.slice("include-file/".length))
+ }
+ }));
+ build.onLoad({ filter, namespace: "include-file" }, async ({ pluginData: { path } }) => {
+ const [name, format] = path.split(";");
+ return {
+ contents: `export default ${JSON.stringify(await readFile(name, format ?? "utf-8"))}`
+ };
+ });
+ }
+};
+
+/**
+ * @type {esbuild.BuildOptions}
+ */
+export const commonOpts = {
+ logLevel: "info",
+ bundle: true,
+ watch,
+ minify: !watch,
+ sourcemap: watch ? "inline" : "",
+ legalComments: "linked",
+ plugins: [fileIncludePlugin]
+};
diff --git a/src/components/Monaco.ts b/src/components/Monaco.ts
index 495f512..6b01891 100644
--- a/src/components/Monaco.ts
+++ b/src/components/Monaco.ts
@@ -16,80 +16,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-
import { IpcEvents } from "../utils";
import { debounce } from "../utils/debounce";
import { find } from "../webpack/webpack";
+import monacoHtml from "@fileContent/monacoWin.html";
+import { Queue } from "../utils/Queue";
+const queue = new Queue();
const setCss = debounce((css: string) => {
- VencordNative.ipc.invoke(IpcEvents.SET_QUICK_CSS, css);
+ queue.add(() => VencordNative.ipc.invoke(IpcEvents.SET_QUICK_CSS, css));
});
-// FIXME: Discord Desktop support.
-// open() fails to create the popup and returns null. Probably have to
-// do some logic in main
-
-// adapted from https://stackoverflow.com/a/63179814
export async function launchMonacoEditor() {
const win = open("about:blank", void 0, "popup,width=1000,height=1000")!;
+ win.setCss = setCss;
win.getCurrentCss = () => VencordNative.ipc.invoke(IpcEvents.GET_QUICK_CSS);
- win.callback = (editor: any) => {
- editor.onDidChangeModelContent(() =>
- setCss(editor.getValue())
- );
- };
-
- let { theme } = find(m => m.ProtoClass?.typeName.endsWith("PreloadedUserSettings"))
- .getCurrentValue().appearance;
- theme = theme === 1 ? "vs-dark" : "vs-light";
-
- // problem?
- win.document.write(`
-
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>QuickCss Editor</title>
- <link rel="stylesheet" data-name="vs/editor/editor.main" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/editor/editor.main.min.css">
- <style>
- html, body, #container {
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- overflow: hidden;
- }
- </style>
- </head>
- <body>
- <div id="container"></div>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/loader.min.js"></script>
-
- <script>
- var editor;
- require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs' }});
- require(["vs/editor/editor.main"], () => {
- getCurrentCss().then(css => {
- callback(editor = monaco.editor.create(document.getElementById('container'), {
- value: css,
- language: 'css',
- theme: '${theme}',
- }));
- });
- });
-
- window.addEventListener("resize", () => {
- // make monaco re-layout
- editor.layout();
- });
- </script>
- </body>
- </html>
+ win.getTheme = () => find(m => m.ProtoClass?.typeName.endsWith("PreloadedUserSettings"))
+ .getCurrentValue().appearance.theme === 1
+ ? "vs-dark"
+ : "vs-light";
-`);
+ win.document.write(monacoHtml);
}
diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx
index 6a5ea9d..8ffe111 100644
--- a/src/components/Settings.tsx
+++ b/src/components/Settings.tsx
@@ -77,7 +77,7 @@ export default ErrorBoundary.wrap(function Settings() {
Launch Directory
</Button>
<Button
- onClick={() => VencordNative.ipc.invoke(IpcEvents.OPEN_QUICKCSS)}
+ onClick={() => VencordNative.ipc.invoke(IpcEvents.OPEN_MONACO_EDITOR)}
size={Button.Sizes.SMALL}
disabled={settingsDir === "Loading..."}
>
diff --git a/src/components/monacoWin.html b/src/components/monacoWin.html
new file mode 100644
index 0000000..edf273d
--- /dev/null
+++ b/src/components/monacoWin.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html lang="en">
+
+<head>
+ <meta charset="utf-8">
+ <title>QuickCss Editor</title>
+ <link rel="stylesheet" data-name="vs/editor/editor.main"
+ href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/editor/editor.main.min.css">
+ <style>
+ html,
+ body,
+ #container {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ }
+ </style>
+</head>
+
+<body>
+ <div id="container"></div>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/loader.min.js"></script>
+
+ <script>
+ require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs' } });
+ require(["vs/editor/editor.main"], () => {
+ getCurrentCss().then(css => {
+ var editor = monaco.editor.create(document.getElementById('container'), {
+ value: css,
+ language: 'css',
+ theme: getTheme(),
+ });
+ editor.onDidChangeModelContent(() =>
+ setCss(editor.getValue())
+ );
+ window.addEventListener("resize", () => {
+ // make monaco re-layout
+ editor.layout();
+ });
+ });
+ });
+
+
+ </script>
+</body>
+
+</html>
diff --git a/src/ipcMain/index.ts b/src/ipcMain/index.ts
index caa4e34..dc05079 100644
--- a/src/ipcMain/index.ts
+++ b/src/ipcMain/index.ts
@@ -22,8 +22,10 @@ import { open, readFile, writeFile } from "fs/promises";
import { join } from "path";
import { debounce } from "../utils/debounce";
import IpcEvents from "../utils/IpcEvents";
+import monacoHtml from "@fileContent/../components/monacoWin.html;base64";
import "./updater";
+import { Queue } from "../utils/Queue";
const DATA_DIR = process.env.VENCORD_USER_DATA_DIR ?? (
process.env.DISCORD_USER_DATA_DIR
@@ -71,15 +73,19 @@ ipcMain.handle(IpcEvents.OPEN_EXTERNAL, (_, url) => {
shell.openExternal(url);
});
+const cssWriteQueue = new Queue();
+const settingsWriteQueue = new Queue();
ipcMain.handle(IpcEvents.GET_QUICK_CSS, () => readCss());
+ipcMain.handle(IpcEvents.SET_QUICK_CSS, (_, css) =>
+ cssWriteQueue.add(() => writeFile(QUICKCSS_PATH, css))
+);
ipcMain.handle(IpcEvents.GET_SETTINGS_DIR, () => SETTINGS_DIR);
ipcMain.on(IpcEvents.GET_SETTINGS, e => e.returnValue = readSettings());
-let settingsWriteQueue = Promise.resolve();
ipcMain.handle(IpcEvents.SET_SETTINGS, (_, s) => {
- settingsWriteQueue = settingsWriteQueue.then(() => writeFile(SETTINGS_FILE, s));
+ settingsWriteQueue.add(() => writeFile(SETTINGS_FILE, s));
});
@@ -91,3 +97,13 @@ export function initIpc(mainWindow: BrowserWindow) {
}, 50));
});
}
+
+ipcMain.handle(IpcEvents.OPEN_MONACO_EDITOR, async () => {
+ const win = new BrowserWindow({
+ title: "QuickCss Editor",
+ webPreferences: {
+ preload: join(__dirname, "preload.js"),
+ }
+ });
+ await win.loadURL(`data:text/html;base64,${monacoHtml}`);
+});
diff --git a/src/modules.d.ts b/src/modules.d.ts
index 11576d2..70bad2f 100644
--- a/src/modules.d.ts
+++ b/src/modules.d.ts
@@ -28,3 +28,8 @@ declare module "git-hash" {
const hash: string;
export default hash;
}
+
+declare module "@fileContent/*" {
+ const content: string;
+ export default content;
+}
diff --git a/src/preload.ts b/src/preload.ts
index 7244a1d..5de4298 100644
--- a/src/preload.ts
+++ b/src/preload.ts
@@ -21,6 +21,7 @@ import { readFileSync } from "fs";
import { join } from "path";
import VencordNative from "./VencordNative";
import IpcEvents from "./utils/IpcEvents";
+import { debounce } from "./utils/debounce";
if (electron.desktopCapturer === void 0) {
// Fix for desktopCapturer being main only in Electron 17+
@@ -39,6 +40,14 @@ if (electron.desktopCapturer === void 0) {
contextBridge.exposeInMainWorld("VencordNative", VencordNative);
-webFrame.executeJavaScript(readFileSync(join(__dirname, "renderer.js"), "utf-8"));
-
-require(process.env.DISCORD_PRELOAD!);
+if (location.protocol !== "data:") {
+ // Discord
+ webFrame.executeJavaScript(readFileSync(join(__dirname, "renderer.js"), "utf-8"));
+ require(process.env.DISCORD_PRELOAD!);
+} else {
+ // Monaco Popout
+ contextBridge.exposeInMainWorld("setCss", debounce(s => VencordNative.ipc.invoke(IpcEvents.SET_QUICK_CSS, s)));
+ contextBridge.exposeInMainWorld("getCurrentCss", () => VencordNative.ipc.invoke(IpcEvents.GET_QUICK_CSS));
+ // shrug
+ contextBridge.exposeInMainWorld("getTheme", () => "vs-dark");
+}
diff --git a/src/utils/IpcEvents.ts b/src/utils/IpcEvents.ts
index b773f64..c6696f8 100644
--- a/src/utils/IpcEvents.ts
+++ b/src/utils/IpcEvents.ts
@@ -43,5 +43,6 @@ export default strEnum({
GET_HASHES: "VencordGetHashes",
UPDATE: "VencordUpdate",
BUILD: "VencordBuild",
- GET_DESKTOP_CAPTURE_SOURCES: "VencordGetDesktopCaptureSources"
+ GET_DESKTOP_CAPTURE_SOURCES: "VencordGetDesktopCaptureSources",
+ OPEN_MONACO_EDITOR: "VencordOpenMonacoEditor"
} as const);
diff --git a/src/utils/Queue.ts b/src/utils/Queue.ts
new file mode 100644
index 0000000..269fd36
--- /dev/null
+++ b/src/utils/Queue.ts
@@ -0,0 +1,27 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 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 { Promisable } from "type-fest";
+
+export class Queue {
+ private promise = Promise.resolve();
+
+ add(func: () => Promisable<void>) {
+ this.promise = this.promise.then(func);
+ }
+}