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,