From 27e81b20db23f09ca7334cc74bc5aee841cd6705 Mon Sep 17 00:00:00 2001
From: Maddie <52103563+maddie480@users.noreply.github.com>
Date: Mon, 2 Sep 2024 06:51:29 +0200
Subject: [PATCH] Allow online themes to be applied only in dark or light mode
(#2701)
---
src/components/VencordSettings/ThemesTab.tsx | 19 ++++++++++++++-----
src/plugins/clientTheme/index.tsx | 3 +--
src/utils/quickCss.ts | 15 ++++++++++++++-
src/webpack/common/stores.ts | 2 ++
src/webpack/common/types/stores.d.ts | 8 ++++++++
5 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/src/components/VencordSettings/ThemesTab.tsx b/src/components/VencordSettings/ThemesTab.tsx
index bb9d3789..f718ab11 100644
--- a/src/components/VencordSettings/ThemesTab.tsx
+++ b/src/components/VencordSettings/ThemesTab.tsx
@@ -77,8 +77,16 @@ function Validators({ themeLinks }: { themeLinks: string[]; }) {
Validator
This section will tell you whether your themes can successfully be loaded
- {themeLinks.map(link => (
- {
+ const { label, link } = (() => {
+ const match = /^@(light|dark) (.*)/.exec(rawLink);
+ if (!match) return { label: rawLink, link: rawLink };
+
+ const [, mode, link] = match;
+ return { label: `[${mode} mode only] ${link}`, link };
+ })();
+
+ return
- {link}
+ {label}
-
- ))}
+ ;
+ })}
>
);
@@ -296,6 +304,7 @@ function ThemesTab() {
Paste links to css files here
One link per line
+ You can prefix lines with @light or @dark to toggle them based on your Discord theme
Make sure to use direct links to files (raw or github.io)!
diff --git a/src/plugins/clientTheme/index.tsx b/src/plugins/clientTheme/index.tsx
index 358bae01..59f3d5fe 100644
--- a/src/plugins/clientTheme/index.tsx
+++ b/src/plugins/clientTheme/index.tsx
@@ -12,7 +12,7 @@ import { Margins } from "@utils/margins";
import { classes } from "@utils/misc";
import definePlugin, { OptionType, StartAt } from "@utils/types";
import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
-import { Button, Forms, useStateFromStores } from "@webpack/common";
+import { Button, Forms, ThemeStore, useStateFromStores } from "@webpack/common";
const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
@@ -36,7 +36,6 @@ function setTheme(theme: string) {
saveClientTheme({ theme });
}
-const ThemeStore = findStoreLazy("ThemeStore");
const NitroThemeStore = findStoreLazy("ClientThemesBackgroundStore");
function ThemeSettings() {
diff --git a/src/utils/quickCss.ts b/src/utils/quickCss.ts
index 99f06004..6a18948d 100644
--- a/src/utils/quickCss.ts
+++ b/src/utils/quickCss.ts
@@ -17,6 +17,7 @@
*/
import { Settings, SettingsStore } from "@api/Settings";
+import { ThemeStore } from "@webpack/common";
let style: HTMLStyleElement;
@@ -59,7 +60,18 @@ async function initThemes() {
const { themeLinks, enabledThemes } = Settings;
- const links: string[] = [...themeLinks];
+ // "darker" and "midnight" both count as dark
+ const activeTheme = ThemeStore.theme === "light" ? "light" : "dark";
+
+ const links = themeLinks
+ .map(rawLink => {
+ const match = /^@(light|dark) (.*)/.exec(rawLink);
+ if (!match) return rawLink;
+
+ const [, mode, link] = match;
+ return mode === activeTheme ? link : null;
+ })
+ .filter(link => link !== null);
if (IS_WEB) {
for (const theme of enabledThemes) {
@@ -85,6 +97,7 @@ document.addEventListener("DOMContentLoaded", () => {
SettingsStore.addChangeListener("themeLinks", initThemes);
SettingsStore.addChangeListener("enabledThemes", initThemes);
+ ThemeStore.addChangeListener(initThemes);
if (!IS_WEB)
VencordNative.quickCss.addThemeChangeListener(initThemes);
diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts
index 74813357..8579f8b9 100644
--- a/src/webpack/common/stores.ts
+++ b/src/webpack/common/stores.ts
@@ -53,6 +53,7 @@ export let RelationshipStore: Stores.RelationshipStore & t.FluxStore & {
};
export let EmojiStore: t.EmojiStore;
+export let ThemeStore: t.ThemeStore;
export let WindowStore: t.WindowStore;
export let DraftStore: t.DraftStore;
@@ -84,3 +85,4 @@ waitForStore("GuildChannelStore", m => GuildChannelStore = m);
waitForStore("MessageStore", m => MessageStore = m);
waitForStore("WindowStore", m => WindowStore = m);
waitForStore("EmojiStore", m => EmojiStore = m);
+waitForStore("ThemeStore", m => ThemeStore = m);
diff --git a/src/webpack/common/types/stores.d.ts b/src/webpack/common/types/stores.d.ts
index 037b2d81..9ca7dfc9 100644
--- a/src/webpack/common/types/stores.d.ts
+++ b/src/webpack/common/types/stores.d.ts
@@ -220,6 +220,14 @@ export class GuildStore extends FluxStore {
getAllGuildRoles(): Record>;
}
+export class ThemeStore extends FluxStore {
+ theme: "light" | "dark" | "darker" | "midnight";
+ darkSidebar: boolean;
+ isSystemThemeAvailable: boolean;
+ systemPrefersColorScheme: "light" | "dark";
+ systemTheme: null;
+}
+
export type useStateFromStores = (
stores: t.FluxStore[],
mapper: () => T,