From 44f6f71c3efd2e4e0f9dbd97ab4680ec76536052 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sat, 22 Oct 2022 04:41:33 +0200 Subject: [PATCH] Monaco for Discord Desktop --- scripts/build/build.mjs | 9 +++-- scripts/build/buildWeb.mjs | 5 ++- scripts/build/common.mjs | 51 ++++++++++++++++++------ src/components/Monaco.ts | 74 +++++------------------------------ src/components/Settings.tsx | 2 +- src/components/monacoWin.html | 52 ++++++++++++++++++++++++ src/ipcMain/index.ts | 20 +++++++++- src/modules.d.ts | 5 +++ src/preload.ts | 15 +++++-- src/utils/IpcEvents.ts | 3 +- src/utils/Queue.ts | 27 +++++++++++++ 11 files changed, 173 insertions(+), 90 deletions(-) create mode 100644 src/components/monacoWin.html create mode 100644 src/utils/Queue.ts diff --git a/scripts/build/build.mjs b/scripts/build/build.mjs index f6304b113..19863693f 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 8abac2cc4..286aad3bd 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 6143fb245..c3afc7ff3 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 495f512a1..6b0189165 100644 --- a/src/components/Monaco.ts +++ b/src/components/Monaco.ts @@ -16,80 +16,26 @@ * along with this program. If not, see . */ - 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()) - ); - }; + win.getTheme = () => find(m => m.ProtoClass?.typeName.endsWith("PreloadedUserSettings")) + .getCurrentValue().appearance.theme === 1 + ? "vs-dark" + : "vs-light"; - let { theme } = find(m => m.ProtoClass?.typeName.endsWith("PreloadedUserSettings")) - .getCurrentValue().appearance; - theme = theme === 1 ? "vs-dark" : "vs-light"; - - // problem? - win.document.write(` - - - - - - QuickCss Editor - - - - -
- - - - - - -`); + win.document.write(monacoHtml); } diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index 6a5ea9de6..8ffe1113d 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -77,7 +77,7 @@ export default ErrorBoundary.wrap(function Settings() { Launch Directory