diff --git a/browser/VencordNativeStub.ts b/browser/VencordNativeStub.ts
index 79f0f2cd..9080f644 100644
--- a/browser/VencordNativeStub.ts
+++ b/browser/VencordNativeStub.ts
@@ -20,16 +20,13 @@
///
import monacoHtmlLocal from "file://monacoWin.html?minify";
-import monacoHtmlCdn from "file://../src/main/monacoWin.html?minify";
import * as DataStore from "../src/api/DataStore";
-import { debounce } from "../src/utils";
+import { debounce, localStorage } from "../src/utils";
import { EXTENSION_BASE_URL } from "../src/utils/web-metadata";
import { getTheme, Theme } from "../src/utils/discord";
import { getThemeInfo } from "../src/main/themes";
import { Settings } from "../src/Vencord";
-
-// Discord deletes this so need to store in variable
-const { localStorage } = window;
+import { getStylusWebStoreUrl } from "@utils/web";
// listeners for ipc.on
const cssListeners = new Set<(css: string) => void>();
@@ -77,6 +74,14 @@ window.VencordNative = {
addThemeChangeListener: NOOP,
openFile: NOOP_ASYNC,
async openEditor() {
+ if (IS_USERSCRIPT) {
+ const shouldOpenWebStore = confirm("QuickCSS is not supported on the Userscript. You can instead use the Stylus extension.\n\nDo you want to open the Stylus web store page?");
+ if (shouldOpenWebStore) {
+ window.open(getStylusWebStoreUrl(), "_blank");
+ }
+ return;
+ }
+
const features = `popup,width=${Math.min(window.innerWidth, 1000)},height=${Math.min(window.innerHeight, 1000)}`;
const win = open("about:blank", "VencordQuickCss", features);
if (!win) {
@@ -92,7 +97,7 @@ window.VencordNative = {
? "vs-light"
: "vs-dark";
- win.document.write(IS_EXTENSION ? monacoHtmlLocal : monacoHtmlCdn);
+ win.document.write(monacoHtmlLocal);
},
},
diff --git a/scripts/build/build.mjs b/scripts/build/build.mjs
index 7d21cd24..0ee24a31 100755
--- a/scripts/build/build.mjs
+++ b/scripts/build/build.mjs
@@ -31,6 +31,7 @@ const defines = stringifyValues({
IS_UPDATER_DISABLED,
IS_WEB: false,
IS_EXTENSION: false,
+ IS_USERSCRIPT: false,
VERSION,
BUILD_TIMESTAMP
});
diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs
index 824194cf..b22df8ab 100644
--- a/scripts/build/buildWeb.mjs
+++ b/scripts/build/buildWeb.mjs
@@ -43,6 +43,7 @@ const commonOptions = {
define: stringifyValues({
IS_WEB: true,
IS_EXTENSION: false,
+ IS_USERSCRIPT: false,
IS_STANDALONE: true,
IS_DEV,
IS_REPORTER,
@@ -98,6 +99,7 @@ const buildConfigs = [
inject: ["browser/GMPolyfill.js", ...(commonOptions?.inject || [])],
define: {
...commonOptions.define,
+ IS_USERSCRIPT: "true",
window: "unsafeWindow",
},
outfile: "dist/Vencord.user.js",
diff --git a/src/components/VencordSettings/ThemesTab.tsx b/src/components/VencordSettings/ThemesTab.tsx
index c507ef88..0c66ec5d 100644
--- a/src/components/VencordSettings/ThemesTab.tsx
+++ b/src/components/VencordSettings/ThemesTab.tsx
@@ -30,6 +30,7 @@ import { Margins } from "@utils/margins";
import { classes } from "@utils/misc";
import { showItemInFolder } from "@utils/native";
import { useAwaiter } from "@utils/react";
+import { getStylusWebStoreUrl } from "@utils/web";
import { findLazy } from "@webpack";
import { Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common";
import type { ComponentType, Ref, SyntheticEvent } from "react";
@@ -384,4 +385,20 @@ export function CspErrorCard() {
);
}
-export default wrapTab(ThemesTab, "Themes");
+function UserscriptThemesTab() {
+ return (
+
+
+ Themes are not supported on the Userscript!
+
+
+ You can instead install themes with the Stylus extension!
+
+
+
+ );
+}
+
+export default IS_USERSCRIPT
+ ? wrapTab(UserscriptThemesTab, "Themes")
+ : wrapTab(ThemesTab, "Themes");
diff --git a/src/globals.d.ts b/src/globals.d.ts
index 4456564c..8dd2bd8d 100644
--- a/src/globals.d.ts
+++ b/src/globals.d.ts
@@ -29,11 +29,12 @@ declare global {
* replace: "IS_WEB?foo:bar"
* // GOOD
* replace: IS_WEB ? "foo" : "bar"
- * // also good
+ * // also okay
* replace: `${IS_WEB}?foo:bar`
*/
export var IS_WEB: boolean;
export var IS_EXTENSION: boolean;
+ export var IS_USERSCRIPT: boolean;
export var IS_STANDALONE: boolean;
export var IS_UPDATER_DISABLED: boolean;
export var IS_DEV: boolean;
diff --git a/src/utils/quickCss.ts b/src/utils/quickCss.ts
index f32ae7e6..b2da24de 100644
--- a/src/utils/quickCss.ts
+++ b/src/utils/quickCss.ts
@@ -39,7 +39,7 @@ async function initSystemValues() {
createStyle("vencord-os-theme-values").textContent = `:root{${variables}}`;
}
-export async function toggle(isEnabled: boolean) {
+async function toggle(isEnabled: boolean) {
if (!style) {
if (isEnabled) {
style = createStyle("vencord-custom-css");
@@ -91,6 +91,8 @@ async function initThemes() {
}
document.addEventListener("DOMContentLoaded", () => {
+ if (IS_USERSCRIPT) return;
+
initSystemValues();
initThemes();
@@ -103,9 +105,11 @@ document.addEventListener("DOMContentLoaded", () => {
if (!IS_WEB) {
VencordNative.quickCss.addThemeChangeListener(initThemes);
}
-});
+}, { once: true });
export function initQuickCssThemeStore() {
+ if (IS_USERSCRIPT) return;
+
initThemes();
let currentTheme = ThemeStore.theme;
diff --git a/src/utils/web.ts b/src/utils/web.ts
index 5c46aec0..c65005a4 100644
--- a/src/utils/web.ts
+++ b/src/utils/web.ts
@@ -53,3 +53,11 @@ export function chooseFile(mimeTypes: string) {
setImmediate(() => document.body.removeChild(input));
});
}
+
+export function getStylusWebStoreUrl() {
+ const isChromium = (navigator as any).userAgentData?.brands?.some(b => b.brand === "Chromium");
+
+ return isChromium
+ ? "https://chromewebstore.google.com/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne"
+ : "https://addons.mozilla.org/firefox/addon/styl-us/";
+}