From 0865d4bb588234ce58220913d78f1632a7e1f36b Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:35:16 -0400 Subject: [PATCH] Add DiscordColorways Back --- README.md | 5 +- .../components/AutoColorwaySelector.tsx | 74 + .../components/ColorPicker.tsx | 91 ++ .../ColorwayCreatorSettingsModal.tsx | 70 + .../components/ColorwaysButton.tsx | 64 + .../components/ConflictingColorsModal.tsx | 318 ++++ .../components/CreatorModal.tsx | 349 +++++ .../discordColorways/components/Icons.tsx | 146 ++ .../discordColorways/components/InfoModal.tsx | 301 ++++ .../components/InputColorwayIdModal.tsx | 49 + .../components/SaveColorwayModal.tsx | 207 +++ .../components/SelectionCircle.tsx | 24 + .../discordColorways/components/Selector.tsx | 838 ++++++++++ .../components/SettingsTabs/OnDemandPage.tsx | 84 + .../components/SettingsTabs/SettingsPage.tsx | 184 +++ .../components/SettingsTabs/SourceManager.tsx | 387 +++++ .../components/SettingsTabs/Store.tsx | 149 ++ .../discordColorways/components/Spinner.tsx | 19 + .../components/ThemePreview.tsx | 150 ++ .../discordColorways/constants.ts | 313 ++++ src/equicordplugins/discordColorways/css.ts | 1001 ++++++++++++ .../discordColorways/index.tsx | 416 +++++ .../discordColorways/style.css | 1379 +++++++++++++++++ src/equicordplugins/discordColorways/types.ts | 65 + src/equicordplugins/discordColorways/utils.ts | 150 ++ 25 files changed, 6832 insertions(+), 1 deletion(-) create mode 100644 src/equicordplugins/discordColorways/components/AutoColorwaySelector.tsx create mode 100644 src/equicordplugins/discordColorways/components/ColorPicker.tsx create mode 100644 src/equicordplugins/discordColorways/components/ColorwayCreatorSettingsModal.tsx create mode 100644 src/equicordplugins/discordColorways/components/ColorwaysButton.tsx create mode 100644 src/equicordplugins/discordColorways/components/ConflictingColorsModal.tsx create mode 100644 src/equicordplugins/discordColorways/components/CreatorModal.tsx create mode 100644 src/equicordplugins/discordColorways/components/Icons.tsx create mode 100644 src/equicordplugins/discordColorways/components/InfoModal.tsx create mode 100644 src/equicordplugins/discordColorways/components/InputColorwayIdModal.tsx create mode 100644 src/equicordplugins/discordColorways/components/SaveColorwayModal.tsx create mode 100644 src/equicordplugins/discordColorways/components/SelectionCircle.tsx create mode 100644 src/equicordplugins/discordColorways/components/Selector.tsx create mode 100644 src/equicordplugins/discordColorways/components/SettingsTabs/OnDemandPage.tsx create mode 100644 src/equicordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx create mode 100644 src/equicordplugins/discordColorways/components/SettingsTabs/SourceManager.tsx create mode 100644 src/equicordplugins/discordColorways/components/SettingsTabs/Store.tsx create mode 100644 src/equicordplugins/discordColorways/components/Spinner.tsx create mode 100644 src/equicordplugins/discordColorways/components/ThemePreview.tsx create mode 100644 src/equicordplugins/discordColorways/constants.ts create mode 100644 src/equicordplugins/discordColorways/css.ts create mode 100644 src/equicordplugins/discordColorways/index.tsx create mode 100644 src/equicordplugins/discordColorways/style.css create mode 100644 src/equicordplugins/discordColorways/types.ts create mode 100644 src/equicordplugins/discordColorways/utils.ts diff --git a/README.md b/README.md index 407a05d9..9f3aaf56 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend - Request for plugins from Discord.
-Extra included plugins (58 additional plugins) +Extra included plugins (61 additional plugins) - AllCallTimers by MaxHerbold and D3SOX - AltKrispSwitch by newwares @@ -33,10 +33,12 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend - CleanChannelName by AutumnVN - CopyUserMention by Cortex and castdrian - CustomAppIcons by Happy Enderman and SerStars +- DiscordColorways by DaBluLite - DNDWhilePlaying by thororen - DoNotLeak by Perny - DoubleCounterBypass by nyx - EmojiDumper by Cortex, Samwich, Woosh +- Encryptcord by Inbestigator - EquicordCSS by FoxStorm1 and thororen (and all respective css developers) - ExportContacts by dat_insanity - FindReply by newwares @@ -68,6 +70,7 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend - Search by JacobTm and thororen - SearchFix by Jaxx - Sekai Stickers by MaiKokain +- ServerSearch by camila314 - ShowBadgesInChat by Inbestigator and KrystalSkull - Slap by Korbo - SoundBoardLogger by Moxxie, fres, echo, thororen diff --git a/src/equicordplugins/discordColorways/components/AutoColorwaySelector.tsx b/src/equicordplugins/discordColorways/components/AutoColorwaySelector.tsx new file mode 100644 index 00000000..6ebbdace --- /dev/null +++ b/src/equicordplugins/discordColorways/components/AutoColorwaySelector.tsx @@ -0,0 +1,74 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { DataStore } from "@api/index"; +import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot } from "@utils/modal"; +import { findByProps } from "@webpack"; +import { Button, Forms, Text, useState } from "@webpack/common"; + +import { getAutoPresets } from "../css"; + +export default function ({ modalProps, onChange, autoColorwayId = "" }: { modalProps: ModalProps, onChange: (autoPresetId: string) => void, autoColorwayId: string; }) { + const [autoId, setAutoId] = useState(autoColorwayId); + const { radioBar, item: radioBarItem, itemFilled: radioBarItemFilled, radioPositionLeft } = findByProps("radioBar"); + return + + + Auto Preset Settings + + + +
+ About the Auto Colorway + The auto colorway allows you to use your system's accent color in combination with a selection of presets that will fully utilize it. +
+
+ Presets: + {Object.values(getAutoPresets()).map(autoPreset => { + return
+
{ + setAutoId(autoPreset.id); + }}> + + {autoPreset.name} +
+
; + })} +
+
+ + + + +
; +} diff --git a/src/equicordplugins/discordColorways/components/ColorPicker.tsx b/src/equicordplugins/discordColorways/components/ColorPicker.tsx new file mode 100644 index 00000000..d4ae6adc --- /dev/null +++ b/src/equicordplugins/discordColorways/components/ColorPicker.tsx @@ -0,0 +1,91 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Flex } from "@components/Flex"; +import { CopyIcon } from "@components/Icons"; +import { + ModalProps, + ModalRoot, +} from "@utils/modal"; +import { + Button, + Clipboard, + ScrollerThin, + TextInput, + Toasts, + useState, +} from "@webpack/common"; + +import { mainColors } from "../constants"; +import { colorVariables } from "../css"; +import { getHex } from "../utils"; + +export default function ({ modalProps }: { modalProps: ModalProps; }) { + const [ColorVars, setColorVars] = useState(colorVariables); + const [collapsedSettings, setCollapsedSettings] = useState(true); + let results: string[]; + function searchToolboxItems(e: string) { + results = []; + colorVariables.find((colorVariable: string) => { + if (colorVariable.toLowerCase().includes(e.toLowerCase())) { + results.push(colorVariable); + } + }); + setColorVars(results); + } + + return + + { + searchToolboxItems(e); + if (e) { + setCollapsedSettings(false); + } else { + setCollapsedSettings(true); + } + }} + /> + + + + {ColorVars.map((colorVariable: string) =>
{ + Clipboard.copy(getHex(getComputedStyle(document.body).getPropertyValue("--" + colorVariable))); + Toasts.show({ message: "Color " + colorVariable + " copied to clipboard", id: "toolbox-color-var-copied", type: 1 }); + }} style={{ "--brand-experiment": `var(--${colorVariable})` } as React.CSSProperties}> + {`Copy ${colorVariable}`} +
)} +
+ + {mainColors.map(mainColor =>
+ { + Clipboard.copy(getHex(getComputedStyle(document.body).getPropertyValue(mainColor.var))); + Toasts.show({ message: `${mainColor.title} color copied to clipboard`, id: `toolbox-${mainColor.name}-color-copied`, type: 1 }); + }} width={20} height={20} className="colorwayToolbox-listItemSVG" /> + {`Copy ${mainColor.title} Color`} +
+ )} +
+
; +} diff --git a/src/equicordplugins/discordColorways/components/ColorwayCreatorSettingsModal.tsx b/src/equicordplugins/discordColorways/components/ColorwayCreatorSettingsModal.tsx new file mode 100644 index 00000000..c969b01c --- /dev/null +++ b/src/equicordplugins/discordColorways/components/ColorwayCreatorSettingsModal.tsx @@ -0,0 +1,70 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot } from "@utils/modal"; +import { findByProps } from "@webpack"; +import { Button, Forms, ScrollerThin, Switch, Text, useState } from "@webpack/common"; + +import { getPreset } from "../css"; + +export default function ({ modalProps, onSettings, presetId, hasTintedText, hasDiscordSaturation }: { modalProps: ModalProps, presetId: string, hasTintedText: boolean, hasDiscordSaturation: boolean, onSettings: ({ presetId, tintedText, discordSaturation }: { presetId: string, tintedText: boolean, discordSaturation: boolean; }) => void; }) { + const [tintedText, setTintedText] = useState(hasTintedText); + const [discordSaturation, setDiscordSaturation] = useState(hasDiscordSaturation); + const [preset, setPreset] = useState(presetId); + const { radioBar, item: radioBarItem, itemFilled: radioBarItemFilled, radioPositionLeft } = findByProps("radioBar"); + return + Creator Settings + + + Presets: + + + {Object.values(getPreset()).map(pre => { + return
+
{ + setPreset(pre.id); + }}> + + {pre.name} +
+
; + })} +
+ Use colored text + Use Discord's saturation +
+ + + + +
; +} diff --git a/src/equicordplugins/discordColorways/components/ColorwaysButton.tsx b/src/equicordplugins/discordColorways/components/ColorwaysButton.tsx new file mode 100644 index 00000000..cc8923f8 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/ColorwaysButton.tsx @@ -0,0 +1,64 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import * as DataStore from "@api/DataStore"; +import { openModal } from "@utils/modal"; +import { FluxDispatcher, Text, Tooltip, useEffect, useState } from "@webpack/common"; +import { FluxEvents } from "@webpack/types"; + +import { getAutoPresets } from "../css"; +import { ColorwayObject } from "../types"; +import { PalleteIcon } from "./Icons"; +import Selector from "./Selector"; + +export default function () { + const [activeColorway, setActiveColorway] = useState("None"); + const [visibility, setVisibility] = useState(true); + const [isThin, setIsThin] = useState(false); + const [autoPreset, setAutoPreset] = useState("hueRotation"); + useEffect(() => { + (async function () { + setVisibility(await DataStore.get("showColorwaysButton") as boolean); + setIsThin(await DataStore.get("useThinMenuButton") as boolean); + setAutoPreset(await DataStore.get("activeAutoPreset") as string); + })(); + }); + + FluxDispatcher.subscribe("COLORWAYS_UPDATE_BUTTON_HEIGHT" as FluxEvents, ({ isTall }) => { + setIsThin(isTall); + }); + + FluxDispatcher.subscribe("COLORWAYS_UPDATE_BUTTON_VISIBILITY" as FluxEvents, ({ isVisible }) => { + setVisibility(isVisible); + }); + + return + {!isThin ? <> + Colorways + {"Active Colorway: " + activeColorway} + : {"Active Colorway: " + activeColorway}} + {activeColorway === "Auto" ? {"Auto Preset: " + (getAutoPresets()[autoPreset].name || "None")} : <>} + + } position="right" tooltipContentClassName="colorwaysBtn-tooltipContent" + > + {({ onMouseEnter, onMouseLeave, onClick }) => visibility ?
+
{ + onMouseEnter(); + setActiveColorway((await DataStore.get("activeColorwayObject") as ColorwayObject).id || "None"); + setAutoPreset(await DataStore.get("activeAutoPreset") as string); + }} + onMouseLeave={onMouseLeave} + onClick={() => { + onClick(); + openModal((props: any) => ); + }} + >{isThin ? Colorways : }
+
: <>} +
; +} diff --git a/src/equicordplugins/discordColorways/components/ConflictingColorsModal.tsx b/src/equicordplugins/discordColorways/components/ConflictingColorsModal.tsx new file mode 100644 index 00000000..410f9aee --- /dev/null +++ b/src/equicordplugins/discordColorways/components/ConflictingColorsModal.tsx @@ -0,0 +1,318 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot } from "@utils/modal"; +import { Button, Forms, ScrollerThin, Text, useState } from "@webpack/common"; + +import { knownThemeVars } from "../constants"; +import { getFontOnBg, getHex } from "../utils"; + +export default function ({ + modalProps, + onFinished +}: { + modalProps: ModalProps; + onFinished: ({ accent, primary, secondary, tertiary }: { accent: string, primary: string, secondary: string, tertiary: string; }) => void; +}) { + const [accentColor, setAccentColor] = useState(getHex( + getComputedStyle( + document.body + ).getPropertyValue("--brand-experiment") + )); + const [primaryColor, setPrimaryColor] = useState(getHex( + getComputedStyle( + document.body + ).getPropertyValue("--background-primary") + )); + const [secondaryColor, setSecondaryColor] = useState(getHex( + getComputedStyle( + document.body + ).getPropertyValue("--background-secondary") + )); + const [tertiaryColor, setTertiaryColor] = useState(getHex( + getComputedStyle( + document.body + ).getPropertyValue("--background-tertiary") + )); + return + + + Conflicting Colors Found + + + + Multiple known themes have been found, select the colors you want to copy from below: + Colors to copy: +
+
Primary
+
Secondary
+
Tertiary
+
Accent
+
+
+ +
+ Discord +
+
setPrimaryColor( + getHex( + getComputedStyle( + document.body + ).getPropertyValue("--background-primary") + ) + )} + >Primary
+
setSecondaryColor( + getHex( + getComputedStyle( + document.body + ).getPropertyValue("--background-secondary") + ) + )} + >Secondary
+
setTertiaryColor( + getHex( + getComputedStyle( + document.body + ).getPropertyValue("--background-tertiary") + ) + )} + >Tertiary
+
setAccentColor( + getHex( + getComputedStyle( + document.body + ).getPropertyValue("--brand-experiment") + ) + )} + >Accent
+
+
+ {Object.values(knownThemeVars).map((theme: any, i) => { + if (getComputedStyle(document.body).getPropertyValue(theme.variable)) { + return ( +
+ {Object.keys(knownThemeVars)[i] + (theme.alt ? " (Main)" : "")} +
+ {theme.primary && getComputedStyle(document.body).getPropertyValue(theme.primary).match(/^\d.*%$/) + ?
{ + setPrimaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.primary)})`)); + }} + >Primary
+ : ( + theme.primary + ?
{ + setPrimaryColor(getHex(getComputedStyle(document.body).getPropertyValue(theme.primary))); + }} + >Primary
+ : (theme.primaryVariables + &&
{ + setPrimaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.h)} ${!getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.s).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.s) + "%") : getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.s)} ${!getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.l).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.l) + "%") : getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.l)})`)); + }} + >Primary
)) + } + {theme.secondary && getComputedStyle(document.body).getPropertyValue(theme.secondary).match(/^\d.*%$/) + ?
{ + setSecondaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.secondary)})`)); + }} + >Secondary
+ : (theme.secondary + ?
{ + setSecondaryColor(getHex(getComputedStyle(document.body).getPropertyValue(theme.secondary))); + }} + >Secondary
+ : (theme.secondaryVariables + &&
{ + setSecondaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.h)} ${!getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.s).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.s) + "%") : getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.s)} ${!getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.l).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.l) + "%") : getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.l)})`)); + }} + >Secondary
)) + } + {theme.tertiary && getComputedStyle(document.body).getPropertyValue(theme.tertiary).match(/^\d.*%$/) + ?
{ + setTertiaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.tertiary)})`)); + }} + >Tertiary
+ : (theme.tertiary + ?
{ + setTertiaryColor(getHex(getComputedStyle(document.body).getPropertyValue(theme.tertiary))); + }} + >Tertiary
+ : (theme.tertiaryVariables + &&
{ + setTertiaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.h)} ${!getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.s).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.s) + "%") : getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.s)} ${!getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.l).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.l) + "%") : getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.l)})`)); + }} + >Tertiary
))} + {theme.accent && getComputedStyle(document.body).getPropertyValue(theme.accent).match(/^\d.*%$/) + ?
{ + setAccentColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.accent)})`)); + }} + >Accent
+ : (theme.accent + ?
{ + setAccentColor(getHex(getComputedStyle(document.body).getPropertyValue(theme.accent))); + }} + >Accent
+ : (theme.accentVariables + &&
{ + setAccentColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.accentVariables.h)} ${!getComputedStyle(document.body).getPropertyValue(theme.accentVariables.s).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.accentVariables.s) + "%") : getComputedStyle(document.body).getPropertyValue(theme.accentVariables.s)} ${!getComputedStyle(document.body).getPropertyValue(theme.accentVariables.l).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.accentVariables.l) + "%") : getComputedStyle(document.body).getPropertyValue(theme.accentVariables.l)})`)); + }} + >Accent
))} +
+
+ ); + } + })} +
+
+
+ + + +
; +} diff --git a/src/equicordplugins/discordColorways/components/CreatorModal.tsx b/src/equicordplugins/discordColorways/components/CreatorModal.tsx new file mode 100644 index 00000000..0ea34849 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/CreatorModal.tsx @@ -0,0 +1,349 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { + ModalContent, + ModalFooter, + ModalHeader, + ModalProps, + ModalRoot, + openModal, +} from "@utils/modal"; +import { + Button, + Forms, + Slider, + Text, + TextInput, + useEffect, + UserStore, + useState, +} from "@webpack/common"; + +import { ColorPicker, versionData } from ".."; +import { knownThemeVars } from "../constants"; +import { generateCss, getPreset, gradientPresetIds, PrimarySatDiffs, pureGradientBase } from "../css"; +import { Colorway } from "../types"; +import { colorToHex, getHex, HexToHSL, hexToString } from "../utils"; +import ColorwayCreatorSettingsModal from "./ColorwayCreatorSettingsModal"; +import ConflictingColorsModal from "./ConflictingColorsModal"; +import InputColorwayIdModal from "./InputColorwayIdModal"; +import SaveColorwayModal from "./SaveColorwayModal"; +import ThemePreviewCategory from "./ThemePreview"; +export default function ({ + modalProps, + loadUIProps, + colorwayID +}: { + modalProps: ModalProps; + loadUIProps?: () => Promise; + colorwayID?: string; +}) { + const [accentColor, setAccentColor] = useState("5865f2"); + const [primaryColor, setPrimaryColor] = useState("313338"); + const [secondaryColor, setSecondaryColor] = useState("2b2d31"); + const [tertiaryColor, setTertiaryColor] = useState("1e1f22"); + const [colorwayName, setColorwayName] = useState(""); + const [tintedText, setTintedText] = useState(true); + const [discordSaturation, setDiscordSaturation] = useState(true); + const [preset, setPreset] = useState("default"); + const [presetColorArray, setPresetColorArray] = useState(["accent", "primary", "secondary", "tertiary"]); + const [mutedTextBrightness, setMutedTextBrightness] = useState(Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)); + + const colorProps = { + accent: { + get: accentColor, + set: setAccentColor, + name: "Accent" + }, + primary: { + get: primaryColor, + set: setPrimaryColor, + name: "Primary" + }, + secondary: { + get: secondaryColor, + set: setSecondaryColor, + name: "Secondary" + }, + tertiary: { + get: tertiaryColor, + set: setTertiaryColor, + name: "Tertiary" + } + }; + + useEffect(() => { + if (colorwayID) { + if (!colorwayID.includes(",")) { + throw new Error("Invalid Colorway ID"); + } else { + const setColor = [ + setAccentColor, + setPrimaryColor, + setSecondaryColor, + setTertiaryColor + ]; + colorwayID.split("|").forEach((prop: string) => { + if (prop.includes(",#")) { + prop.split(/,#/).forEach((color: string, i: number) => setColor[i](colorToHex(color))); + } + if (prop.includes("n:")) { + setColorwayName(prop.split("n:")[1]); + } + if (prop.includes("p:")) { + if (Object.values(getPreset()).map(preset => preset.id).includes(prop.split("p:")[1])) { + setPreset(prop.split("p:")[1]); + setPresetColorArray(getPreset()[prop.split("p:")[1]].colors); + } + } + }); + } + } + }); + const colorPickerProps = { + suggestedColors: [ + "#313338", + "#2b2d31", + "#1e1f22", + "#5865f2", + ], + showEyeDropper: true + }; + + return ( + + + + Create Colorway + + + + + Name: + + +
+ + Colors & Values: + +
+ {presetColorArray.map(presetColor => { + return {colorProps[presetColor].name}} + color={parseInt(colorProps[presetColor].get, 16)} + onChange={(color: number) => { + let hexColor = color.toString(16); + while (hexColor.length < 6) { + hexColor = "0" + hexColor; + } + colorProps[presetColor].set(hexColor); + }} + {...colorPickerProps} + />; + })} +
+ + Muted Text Brightness: + +
+
openModal((props: ModalProps) => { + setPreset(presetId); + setPresetColorArray(getPreset()[presetId].colors); + setDiscordSaturation(discordSaturation); + setTintedText(tintedText); + }} />)}> + Settings & Presets + +
+ +
+ + + + + + +
+ ); +} + diff --git a/src/equicordplugins/discordColorways/components/Icons.tsx b/src/equicordplugins/discordColorways/components/Icons.tsx new file mode 100644 index 00000000..62acf0f5 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/Icons.tsx @@ -0,0 +1,146 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { classes } from "@utils/misc"; +import type { PropsWithChildren, SVGProps } from "react"; + +interface BaseIconProps extends IconProps { + viewBox: string; +} + +interface IconProps extends SVGProps { + className?: string; + height?: string | number; + width?: string | number; +} + +function Icon({ height = 24, width = 24, className, children, viewBox, ...svgProps }: PropsWithChildren) { + return ( + + {children} + + ); +} + +export function PalleteIcon(props: IconProps) { + return ( + + + + ); +} + +export function CloseIcon(props: IconProps) { + return ( + + + + ); +} + +export function DownloadIcon(props: IconProps) { + return ( + + + + ); +} + +export function ImportIcon(props: IconProps) { + return ( + + + + ); +} + +export function IDIcon(props: IconProps) { + return ( + + + + + ); +} + +export function CodeIcon(props: IconProps) { + return ( + + + + ); +} + +export function MoreIcon(props: IconProps) { + return ( + + + + ); +} diff --git a/src/equicordplugins/discordColorways/components/InfoModal.tsx b/src/equicordplugins/discordColorways/components/InfoModal.tsx new file mode 100644 index 00000000..100bfb04 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/InfoModal.tsx @@ -0,0 +1,301 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import * as DataStore from "@api/DataStore"; +import { CodeBlock } from "@components/CodeBlock"; +import { Flex } from "@components/Flex"; +import { + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalProps, + ModalRoot, + openModal, +} from "@utils/modal"; +import { saveFile } from "@utils/web"; +import { findComponentByCodeLazy } from "@webpack"; +import { Button, Clipboard, Forms, Text, TextInput, Toasts, UserStore, useState, useStateFromStores } from "@webpack/common"; + +import { ColorwayCSS, versionData } from ".."; +import { generateCss, pureGradientBase } from "../css"; +import { Colorway } from "../types"; +import { colorToHex, stringToHex } from "../utils"; +import SaveColorwayModal from "./SaveColorwayModal"; +import ThemePreview from "./ThemePreview"; + +const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers"); + +function RenameColorwayModal({ modalProps, ogName, onFinish, colorwayList }: { modalProps: ModalProps, ogName: string, onFinish: (name: string) => void, colorwayList: Colorway[]; }) { + const [error, setError] = useState(""); + const [newName, setNewName] = useState(ogName); + return + + + Rename Colorway... + + modalProps.onClose()} /> + + + + + + + + + ; +} + +export default function ({ + modalProps, + colorway, + loadUIProps +}: { + modalProps: ModalProps; + colorway: Colorway; + loadUIProps: () => Promise; +}) { + const colors: string[] = colorway.colors || [ + "accent", + "primary", + "secondary", + "tertiary", + ]; + const profile = useStateFromStores([UserStore], () => UserStore.getUser(colorway.authorID)); + return + + + Colorway: {colorway.name} + + modalProps.onClose()} /> + + + + Creator: + + + {colorway.author} + + Colors: + + {colors.map(color =>
)} + + Actions: + + + + + {colorway.sourceType === "offline" && } + + + + {colorway.sourceType === "offline" && } + + +
+ + ; +} diff --git a/src/equicordplugins/discordColorways/components/InputColorwayIdModal.tsx b/src/equicordplugins/discordColorways/components/InputColorwayIdModal.tsx new file mode 100644 index 00000000..6100529c --- /dev/null +++ b/src/equicordplugins/discordColorways/components/InputColorwayIdModal.tsx @@ -0,0 +1,49 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { ModalContent, ModalFooter, ModalProps, ModalRoot } from "@utils/modal"; +import { Button, Forms, TextInput, useState } from "@webpack/common"; + +import { hexToString } from "../utils"; + +export default function ({ modalProps, onColorwayId }: { modalProps: ModalProps, onColorwayId: (colorwayID: string) => void; }) { + const [colorwayID, setColorwayID] = useState(""); + return + + Colorway ID: + setColorwayID(e.currentTarget.value)} /> + + + + + + ; +} diff --git a/src/equicordplugins/discordColorways/components/SaveColorwayModal.tsx b/src/equicordplugins/discordColorways/components/SaveColorwayModal.tsx new file mode 100644 index 00000000..8a034edb --- /dev/null +++ b/src/equicordplugins/discordColorways/components/SaveColorwayModal.tsx @@ -0,0 +1,207 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { DataStore } from "@api/index"; +import { PlusIcon } from "@components/Icons"; +import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal"; +import { findByProps } from "@webpack"; +import { Button, Text, TextInput, useEffect, useState } from "@webpack/common"; + +import { Colorway } from "../types"; +import { StoreNameModal } from "./SettingsTabs/SourceManager"; + +export default function ({ modalProps, colorways, onFinish }: { modalProps: ModalProps, colorways: Colorway[], onFinish: () => void; }) { + const [offlineColorwayStores, setOfflineColorwayStores] = useState<{ name: string, colorways: Colorway[], id?: string; }[]>([]); + const [storename, setStorename] = useState(); + const [noStoreError, setNoStoreError] = useState(false); + const { radioBar, item: radioBarItem, itemFilled: radioBarItemFilled, radioPositionLeft } = findByProps("radioBar"); + useEffect(() => { + (async () => { + setOfflineColorwayStores(await DataStore.get("customColorways") as { name: string, colorways: Colorway[], id?: string; }[]); + })(); + }); + return + + Select Offline Colorway Source + + + {noStoreError ? Error: No store selected : <>} + {offlineColorwayStores.map(store => { + return
+
{ + setStorename(store.name); + }}> + + {store.name} +
+
; + })} +
+
{ + openModal(props => { + await DataStore.set("customColorways", [...await DataStore.get("customColorways"), { name: e, colorways: [] }]); + setOfflineColorwayStores(await DataStore.get("customColorways") as { name: string, colorways: Colorway[]; }[]); + }} />); + }}> + + Create new store... +
+
+
+ + + + + +
; + } + openModal(propss => { + const newStore = { name: storeToModify.name, colorways: [...storeToModify.colorways, { ...colorway, name: e }] }; + DataStore.set("customColorways", [...oldStores!.filter(source => source.name !== storename), newStore]); + props.onClose(); + if (i + 1 === colorways.length) { + modalProps.onClose(); + onFinish!(); + } + }} />); + }} + > + Rename + + + + ); + } else { + const newStore = { name: storeToModify.name, colorways: [...storeToModify.colorways, colorway] }; + DataStore.set("customColorways", [...oldStores!.filter(source => source.name !== storename), newStore]); + if (i + 1 === colorways.length) { + modalProps.onClose(); + onFinish(); + } + } + }); + } + }} + > + Finish + + + + ; +} diff --git a/src/equicordplugins/discordColorways/components/SelectionCircle.tsx b/src/equicordplugins/discordColorways/components/SelectionCircle.tsx new file mode 100644 index 00000000..22e919f2 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/SelectionCircle.tsx @@ -0,0 +1,24 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export default function () { + return
+ +
; +} diff --git a/src/equicordplugins/discordColorways/components/Selector.tsx b/src/equicordplugins/discordColorways/components/Selector.tsx new file mode 100644 index 00000000..5dde6a72 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/Selector.tsx @@ -0,0 +1,838 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/* eslint-disable arrow-parens */ + +import * as DataStore from "@api/DataStore"; +import { Flex } from "@components/Flex"; +import { DeleteIcon, PlusIcon } from "@components/Icons"; +import { SettingsTab } from "@components/VencordSettings/shared"; +import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal"; +import { findByProps } from "@webpack"; +import { + Button, + ButtonLooks, + Clipboard, + Forms, + Menu, + Popout, + ScrollerThin, + Select, + SettingsRouter, + Text, + TextInput, + Toasts, + Tooltip, + useEffect, + useState +} from "@webpack/common"; +import { ReactNode } from "react"; + +import { ColorwayCSS } from ".."; +import { generateCss, getAutoPresets, gradientBase } from "../css"; +import { Colorway, ColorwayObject, SortOptions, SourceObject } from "../types"; +import { colorToHex, getHex, stringToHex } from "../utils"; +import AutoColorwaySelector from "./AutoColorwaySelector"; +import ColorPickerModal from "./ColorPicker"; +import CreatorModal from "./CreatorModal"; +import { CodeIcon, IDIcon, MoreIcon, PalleteIcon } from "./Icons"; +import ColorwayInfoModal from "./InfoModal"; +import SelectionCircle from "./SelectionCircle"; + +function SelectorContainer({ children, isSettings, modalProps }: { children: ReactNode, isSettings?: boolean, modalProps: ModalProps; }) { + if (!isSettings) { + return + {children} + ; + } else { + return +
+ {children} +
+
; + } +} + +function SelectorHeader({ children, isSettings }: { children: ReactNode, isSettings?: boolean; }) { + if (!isSettings) { + return + {children} + ; + } else { + return + {children} + ; + } +} + +function SelectorContent({ children, isSettings }: { children: ReactNode, isSettings?: boolean; }) { + if (!isSettings) { + return {children}; + } else { + return <>{children}; + } +} + +export default function ({ + modalProps, + isSettings, + settings = { selectorType: "normal" } +}: { + modalProps: ModalProps, + isSettings?: boolean, + settings?: { selectorType: "preview" | "multiple-selection" | "normal", previewSource?: string, onSelected?: (colorways: Colorway[]) => void; }; +}): JSX.Element | any { + const [colorwayData, setColorwayData] = useState([]); + const [searchValue, setSearchValue] = useState(""); + const [sortBy, setSortBy] = useState(SortOptions.NAME_AZ); + const [activeColorwayObject, setActiveColorwayObject] = useState({ id: null, css: null, sourceType: null, source: null }); + const [customColorwayData, setCustomColorwayData] = useState([]); + const [loaderHeight, setLoaderHeight] = useState<"2px" | "0px">("2px"); + const [visibleSources, setVisibleSources] = useState("all"); + const [showReloadMenu, setShowReloadMenu] = useState(false); + const [viewMode, setViewMode] = useState<"list" | "grid">("grid"); + const [showLabelsInSelectorGridView, setShowLabelsInSelectorGridView] = useState(false); + const [showSortingMenu, setShowSotringMenu] = useState(false); + const [selectedColorways, setSelectedColorways] = useState([]); + const [errorCode, setErrorCode] = useState(0); + + const { item: radioBarItem, itemFilled: radioBarItemFilled } = findByProps("radioBar"); + + const filters = [ + { + name: "All", + id: "all", + sources: [...colorwayData, ...customColorwayData] + }, + ...colorwayData.map((source) => ({ + name: source.source, + id: source.source.toLowerCase().replaceAll(" ", "-"), + sources: [source] + })), + ...customColorwayData.map((source) => ({ + name: source.source, + id: source.source.toLowerCase().replaceAll(" ", "-"), + sources: [source] + })) + ]; + + async function loadUI(force?: boolean) { + setActiveColorwayObject(await DataStore.get("activeColorwayObject") as ColorwayObject); + setViewMode(await DataStore.get("selectorViewMode") as "list" | "grid"); + setShowLabelsInSelectorGridView(await DataStore.get("showLabelsInSelectorGridView") as boolean); + setLoaderHeight("0px"); + + if (settings.previewSource) { + + const res: Response = await fetch(settings.previewSource); + + const dataPromise = res.json().then(data => data).catch(() => ({ colorways: [], errorCode: 1, errorMsg: "Colorway Source format is invalid" })); + + const data = await dataPromise; + + if (data.errorCode) { + setErrorCode(data.errorCode); + } + + const colorwayList: Colorway[] = data.css ? data.css.map(customStore => customStore.colorways).flat() : data.colorways; + + setColorwayData([{ colorways: colorwayList || [], source: res.url, type: "online" }] as { type: "online" | "offline" | "temporary", source: string, colorways: Colorway[]; }[]); + + } else { + setCustomColorwayData((await DataStore.get("customColorways") as { name: string, colorways: Colorway[], id?: string; }[]).map((colorSrc: { name: string, colorways: Colorway[], id?: string; }) => ({ type: "offline", source: colorSrc.name, colorways: colorSrc.colorways }))); + + const onlineSources: { name: string, url: string; }[] = await DataStore.get("colorwaySourceFiles") as { name: string, url: string; }[]; + + const responses: Response[] = await Promise.all( + onlineSources.map((source) => + fetch(source.url, force ? { cache: "no-store" } : {}) + ) + ); + + setColorwayData(await Promise.all( + responses + .map((res, i) => ({ response: res, name: onlineSources[i].name })) + .map((res: { response: Response, name: string; }) => + res.response.json().then(dt => ({ colorways: dt.colorways as Colorway[], source: res.name, type: "online" })).catch(() => ({ colorways: [] as Colorway[], source: res.name, type: "online" })) + )) as { type: "online" | "offline" | "temporary", source: string, colorways: Colorway[]; }[]); + } + } + + useEffect(() => { loadUI(); }, [searchValue]); + + function ReloadPopout(onClose: () => void) { + return ( + + loadUI(true)} + /> + + ); + } + + function SortingPopout(onClose: () => void) { + return ( + + + { + setViewMode("grid"); + DataStore.set("selectorViewMode", "grid"); + }} + /> + { + setViewMode("list"); + DataStore.set("selectorViewMode", "list"); + }} + /> + + + setSortBy(SortOptions.NAME_AZ)} + /> + setSortBy(SortOptions.NAME_ZA)} + /> + setSortBy(SortOptions.SOURCE_AZ)} + /> + setSortBy(SortOptions.SOURCE_ZA)} + /> + + + ); + } + + return ( + + + {settings.selectorType !== "preview" ? <> + + + {({ onMouseEnter, onMouseLeave }) => setShowReloadMenu(false)} + renderPopout={() => ReloadPopout(() => setShowReloadMenu(false))} + > + {(_, { isShown }) => } + } + + + {({ onMouseEnter, onMouseLeave }) => } + + + {({ onMouseEnter, onMouseLeave }) => setShowSotringMenu(false)} + renderPopout={() => SortingPopout(() => setShowSotringMenu(false))} + > + {(_, { isShown }) => } + } + + + {({ onMouseEnter, onMouseLeave }) => } + + {isSettings ? { return { label: filter.name, value: (filter.id as string) }; })} + select={value => setVisibleSources(value)} + isSelected={value => visibleSources === value} + serialize={String} + popoutPosition="top" /> + : <>} + + ); +} diff --git a/src/equicordplugins/discordColorways/components/SettingsTabs/OnDemandPage.tsx b/src/equicordplugins/discordColorways/components/SettingsTabs/OnDemandPage.tsx new file mode 100644 index 00000000..b3fe9810 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/SettingsTabs/OnDemandPage.tsx @@ -0,0 +1,84 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { DataStore } from "@api/index"; +import { SettingsTab } from "@components/VencordSettings/shared"; +import { Switch, useCallback, useEffect, useState } from "@webpack/common"; + +export default function () { + const [onDemand, setOnDemand] = useState(false); + const [onDemandTinted, setOnDemandTinted] = useState(false); + const [onDemandDiscordSat, setOnDemandDiscordSat] = useState(false); + const [onDemandOsAccent, setOnDemandOsAccent] = useState(false); + async function loadUI() { + const [ + onDemandWays, + onDemandWaysTintedText, + onDemandWaysDiscordSaturation, + onDemandWaysOsAccentColor + ] = await DataStore.getMany([ + "onDemandWays", + "onDemandWaysTintedText", + "onDemandWaysDiscordSaturation", + "onDemandWaysOsAccentColor" + ]); + setOnDemand(onDemandWays); + setOnDemandTinted(onDemandWaysTintedText); + setOnDemandDiscordSat(onDemandWaysDiscordSaturation); + if (getComputedStyle(document.body).getPropertyValue("--os-accent-color") !== "") { + setOnDemandOsAccent(onDemandWaysOsAccentColor); + } + } + + const cached_loadUI = useCallback(loadUI, []); + + useEffect(() => { + cached_loadUI(); + }, []); + return + { + setOnDemand(v); + DataStore.set("onDemandWays", v); + }} + note="Always utilise the latest of what DiscordColorways has to offer. CSS is being directly generated on the device and gets applied in the place of the normal import/CSS given by the colorway." + > + Enable Colorways On Demand + + { + setOnDemandTinted(v); + DataStore.set("onDemandWaysTintedText", v); + }} + disabled={!onDemand} + > + Use tinted text + + { + setOnDemandDiscordSat(v); + DataStore.set("onDemandWaysDiscordSaturation", v); + }} + disabled={!onDemand} + > + Use Discord's saturation + + { + setOnDemandOsAccent(v); + DataStore.set("onDemandWaysOsAccentColor", v); + }} + disabled={!onDemand || !getComputedStyle(document.body).getPropertyValue("--os-accent-color")} + > + Use Operating System's Accent Color + + ; +} diff --git a/src/equicordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx b/src/equicordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx new file mode 100644 index 00000000..274491bc --- /dev/null +++ b/src/equicordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx @@ -0,0 +1,184 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { DataStore } from "@api/index"; +import { Flex } from "@components/Flex"; +import { Link } from "@components/Link"; +import { SettingsTab } from "@components/VencordSettings/shared"; +import { + FluxDispatcher, + Forms, + Switch, + Text, + useEffect, + useState +} from "@webpack/common"; +import { FluxEvents } from "@webpack/types"; + +import { versionData } from "../../."; +import { fallbackColorways } from "../../constants"; +import { Colorway } from "../../types"; + +export default function () { + const [colorways, setColorways] = useState([]); + const [customColorways, setCustomColorways] = useState([]); + const [colorsButtonVisibility, setColorsButtonVisibility] = useState(false); + const [isButtonThin, setIsButtonThin] = useState(false); + const [showLabelsInSelectorGridView, setShowLabelsInSelectorGridView] = useState(false); + + useEffect(() => { + (async function () { + const [ + customColorways, + colorwaySourceFiles, + showColorwaysButton, + useThinMenuButton, + showLabelsInSelectorGridView + ] = await DataStore.getMany([ + "customColorways", + "colorwaySourceFiles", + "showColorwaysButton", + "useThinMenuButton", + "showLabelsInSelectorGridView" + ]); + const responses: Response[] = await Promise.all( + colorwaySourceFiles.map((url: string) => + fetch(url) + ) + ); + const data = await Promise.all( + responses.map((res: Response) => + res.json().catch(() => { return { colorways: [] }; }) + )); + const colorways = data.flatMap(json => json.colorways); + setColorways(colorways || fallbackColorways); + setCustomColorways(customColorways.map(source => source.colorways).flat(2)); + setColorsButtonVisibility(showColorwaysButton); + setIsButtonThin(useThinMenuButton); + setShowLabelsInSelectorGridView(showLabelsInSelectorGridView); + })(); + }, []); + + return +
+ Quick Switch + { + setColorsButtonVisibility(v); + DataStore.set("showColorwaysButton", v); + FluxDispatcher.dispatch({ + type: "COLORWAYS_UPDATE_BUTTON_VISIBILITY" as FluxEvents, + isVisible: v + }); + }} + note="Shows a button on the top of the servers list that opens a colorway selector modal." + > + Enable Quick Switch + + { + setIsButtonThin(v); + DataStore.set("useThinMenuButton", v); + FluxDispatcher.dispatch({ + type: "COLORWAYS_UPDATE_BUTTON_HEIGHT" as FluxEvents, + isTall: v + }); + }} + note="Replaces the icon on the colorways launcher button with text, making it more compact." + > + Use thin Quick Switch button + + Selector + { + setShowLabelsInSelectorGridView(v); + DataStore.set("showLabelsInSelectorGridView", v); + }} + > + Show labels in Grid View + + +

+ Discord Colorways +

+ by Project Colorway + + Plugin Version: + + + {versionData.pluginVersion} + + + Creator Version: + + + {versionData.creatorVersion}{" (Stable)"} + + + Loaded Colorways: + + + {[...colorways, ...customColorways].length + 1} + + + Project Repositories: + + + DiscordColorways +
+ Project Colorway +
+
+
+
; +} diff --git a/src/equicordplugins/discordColorways/components/SettingsTabs/SourceManager.tsx b/src/equicordplugins/discordColorways/components/SettingsTabs/SourceManager.tsx new file mode 100644 index 00000000..2cc3eeb9 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/SettingsTabs/SourceManager.tsx @@ -0,0 +1,387 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { DataStore } from "@api/index"; +import { Flex } from "@components/Flex"; +import { CopyIcon, DeleteIcon, PlusIcon } from "@components/Icons"; +import { SettingsTab } from "@components/VencordSettings/shared"; +import { Logger } from "@utils/Logger"; +import { closeModal, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal"; +import { chooseFile, saveFile } from "@utils/web"; +import { findByProps } from "@webpack"; +import { Button, Clipboard, Forms, ScrollerThin, Text, TextInput, useEffect, useState } from "@webpack/common"; + +import { defaultColorwaySource } from "../../constants"; +import { Colorway } from "../../types"; +import { DownloadIcon, ImportIcon } from "../Icons"; +import Spinner from "../Spinner"; + +export function StoreNameModal({ modalProps, originalName, onFinish, conflicting }: { modalProps: ModalProps, originalName: string, onFinish: (newName: string) => Promise, conflicting: boolean; }) { + const [error, setError] = useState(""); + const [newStoreName, setNewStoreName] = useState(originalName); + return + + {conflicting ? "Duplicate Store Name" : "Give this store a name"} + + + {conflicting ? A store with the same name already exists. Please give a different name to the imported store: : <>} + Name: + setNewStoreName(e)} style={{ marginBottom: "16px" }} /> + + + + + + ; +} + +function AddOnlineStoreModal({ modalProps, onFinish }: { modalProps: ModalProps, onFinish: (name: string, url: string) => void; }) { + const [colorwaySourceName, setColorwaySourceName] = useState(""); + const [colorwaySourceURL, setColorwaySourceURL] = useState(""); + const [nameError, setNameError] = useState(""); + const [URLError, setURLError] = useState(""); + const [nameReadOnly, setNameReadOnly] = useState(false); + return + + + Add a source: + + + + Name: + + URL: + { + setColorwaySourceURL(value); + if (value === defaultColorwaySource) { + setNameReadOnly(true); + setColorwaySourceName("Project Colorway"); + } + }} + value={colorwaySourceURL} + error={URLError} + style={{ marginBottom: "16px" }} + /> + + + + + + ; +} + +export default function () { + const [colorwaySourceFiles, setColorwaySourceFiles] = useState<{ name: string, url: string; }[]>([]); + const [customColorwayStores, setCustomColorwayStores] = useState<{ name: string, colorways: Colorway[]; }[]>([]); + + const { item: radioBarItem, itemFilled: radioBarItemFilled } = findByProps("radioBar"); + + useEffect(() => { + (async function () { + setColorwaySourceFiles(await DataStore.get("colorwaySourceFiles") as { name: string, url: string; }[]); + setCustomColorwayStores(await DataStore.get("customColorways") as { name: string, colorways: Colorway[]; }[]); + })(); + }, []); + return + + Online + + + + {!colorwaySourceFiles.length &&
{ + DataStore.set("colorwaySourceFiles", [{ name: "Project Colorway", url: defaultColorwaySource }]); + setColorwaySourceFiles([{ name: "Project Colorway", url: defaultColorwaySource }]); + }}> + + + Add Project Colorway Source + +
} + {colorwaySourceFiles.map((colorwaySourceFile: { name: string, url: string; }, i: number) =>
+
+ + {colorwaySourceFile.name} {colorwaySourceFile.url === defaultColorwaySource &&
Built-In
} +
+ + {colorwaySourceFile.url} + +
+ + + {colorwaySourceFile.url !== defaultColorwaySource + && <> + + + } + +
+ )} +
+ + Offline + + + + + {getComputedStyle(document.body).getPropertyValue("--os-accent-color") ?
+ + OS Accent Color{" "} +
Built-In
+
+
+
: <>} + {customColorwayStores.map(({ name: customColorwaySourceName, colorways: offlineStoreColorways }) =>
+ + {customColorwaySourceName} + + + + + +
+ )} +
+
; +} diff --git a/src/equicordplugins/discordColorways/components/SettingsTabs/Store.tsx b/src/equicordplugins/discordColorways/components/SettingsTabs/Store.tsx new file mode 100644 index 00000000..c3e141cd --- /dev/null +++ b/src/equicordplugins/discordColorways/components/SettingsTabs/Store.tsx @@ -0,0 +1,149 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { DataStore } from "@api/index"; +import { Flex } from "@components/Flex"; +import { DeleteIcon } from "@components/Icons"; +import { Link } from "@components/Link"; +import { SettingsTab } from "@components/VencordSettings/shared"; +import { getTheme, Theme } from "@utils/discord"; +import { openModal } from "@utils/modal"; +import { findByProps } from "@webpack"; +import { Button, ScrollerThin, Text, TextInput, Tooltip, useEffect, useState } from "@webpack/common"; + +import { StoreItem } from "../../types"; +import { DownloadIcon, PalleteIcon } from "../Icons"; +import Selector from "../Selector"; + +const GithubIconLight = "/assets/3ff98ad75ac94fa883af5ed62d17c459.svg"; +const GithubIconDark = "/assets/6a853b4c87fce386cbfef4a2efbacb09.svg"; + +function GithubIcon() { + const src = getTheme() === Theme.Light ? GithubIconLight : GithubIconDark; + return GitHub; +} + +export default function () { + const [storeObject, setStoreObject] = useState([]); + const [colorwaySourceFiles, setColorwaySourceFiles] = useState<{ name: string, url: string; }[]>([]); + const [searchValue, setSearchValue] = useState(""); + + useEffect(() => { + if (!searchValue) { + (async function () { + const res: Response = await fetch("https://dablulite.vercel.app/"); + const data = await res.json(); + setStoreObject(data.sources); + setColorwaySourceFiles(await DataStore.get("colorwaySourceFiles") as { name: string, url: string; }[]); + })(); + } + }, []); + + const { item: radioBarItem, itemFilled: radioBarItemFilled } = findByProps("radioBar"); + + return + + + + {({ onMouseEnter, onMouseLeave }) => } + + + + {storeObject.map((item: StoreItem) => + item.name.toLowerCase().includes(searchValue.toLowerCase()) ?
+ + + {item.name} + + + {item.description} + + + by {item.authorGh} + + + + + + + +
: <> + )} +
+
; +} diff --git a/src/equicordplugins/discordColorways/components/Spinner.tsx b/src/equicordplugins/discordColorways/components/Spinner.tsx new file mode 100644 index 00000000..650db512 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/Spinner.tsx @@ -0,0 +1,19 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { CSSProperties } from "react"; + +export default function ({ className, style }: { className?: string, style?: CSSProperties; }) { + return
+
+ + + + + +
+
; +} diff --git a/src/equicordplugins/discordColorways/components/ThemePreview.tsx b/src/equicordplugins/discordColorways/components/ThemePreview.tsx new file mode 100644 index 00000000..593c0b16 --- /dev/null +++ b/src/equicordplugins/discordColorways/components/ThemePreview.tsx @@ -0,0 +1,150 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { ModalProps, ModalRoot, openModal } from "@utils/modal"; +import { Text } from "@webpack/common"; + +import { HexToHSL } from "../utils"; +import { CloseIcon } from "./Icons"; + +export default function ThemePreview({ + accent, + primary, + secondary, + tertiary, + previewCSS, + modalProps, + isModal +}: { + accent: string, + primary: string, + secondary: string, + tertiary: string, + previewCSS?: string, + modalProps?: ModalProps, + isModal?: boolean; +}) { + return <> + +
+
+
+
+
+
e.currentTarget.style.background = accent} + onMouseLeave={e => e.currentTarget.style.background = `var(--dc-guild-button, ${primary})`} + onClick={() => { + if (isModal) { + modalProps?.onClose(); + } else { + openModal((props: ModalProps) => + + + ); + } + }} + > + {isModal ? : } +
+
+
+
+
+
+
e.currentTarget.style.background = accent} + onMouseLeave={e => e.currentTarget.style.background = `var(--dc-guild-button, ${primary})`} + /> +
+
+
e.currentTarget.style.background = accent} + onMouseLeave={e => e.currentTarget.style.background = `var(--dc-guild-button, ${primary})`} + /> +
+
+
+
+
+
+
+
+
+
+ + Preview + +
+
+
+
+
+
+
+
+
+ ; +} diff --git a/src/equicordplugins/discordColorways/constants.ts b/src/equicordplugins/discordColorways/constants.ts new file mode 100644 index 00000000..fdcdf90c --- /dev/null +++ b/src/equicordplugins/discordColorways/constants.ts @@ -0,0 +1,313 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export const defaultColorwaySource = "https://raw.githubusercontent.com/DaBluLite/ProjectColorway/master/index.json"; + +export const fallbackColorways = [ + { + name: "Keyboard Purple", + original: false, + accent: "hsl(235 85.6% 64.7%)", + primary: "#222456", + secondary: "#1c1f48", + tertiary: "#080d1d", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/KeyboardPurple/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Eclipse", + original: false, + accent: "hsl(87 85.6% 64.7%)", + primary: "#000000", + secondary: "#181818", + tertiary: "#0a0a0a", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Eclipse/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Cyan", + original: false, + accent: "#009f88", + primary: "#202226", + secondary: "#1c1e21", + tertiary: "#141517", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Cyan/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Spotify", + original: false, + accent: "hsl(141 76% 48%)", + primary: "#121212", + secondary: "#090909", + tertiary: "#090909", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Spotify/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Bright n' Blue", + original: true, + accent: "hsl(234, 68%, 33%)", + primary: "#394aae", + secondary: "#29379d", + tertiary: "#1b278d", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/BrightBlue/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Still Young", + original: true, + accent: "hsl(58 85.6% 89%)", + primary: "#443a31", + secondary: "#7c3d3e", + tertiary: "#207578", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/StillYoung/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Sea", + original: true, + accent: "hsl(184, 100%, 50%)", + primary: "#07353b", + secondary: "#0b5e60", + tertiary: "#08201d", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Sea/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Lava", + original: true, + accent: "hsl(4, 80.4%, 32%)", + primary: "#401b17", + secondary: "#351917", + tertiary: "#230b0b", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Lava/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Solid Pink", + original: true, + accent: "hsl(340, 55.2%, 56.3%)", + primary: "#1e151c", + secondary: "#21181f", + tertiary: "#291e27", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/SolidPink/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Sand", + original: true, + accent: "hsl(41, 31%, 45%)", + primary: "#7f6c43", + secondary: "#665b33", + tertiary: "#5c5733", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Sand/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "AMOLED", + original: true, + accent: "hsl(235 85.6% 64.7%)", + primary: "#000000", + secondary: "#000000", + tertiary: "#000000", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Amoled/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Zorin", + original: false, + accent: "hsl(200, 89%, 86%)", + primary: "#171d20", + secondary: "#171d20", + tertiary: "#1e2529", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Zorin/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Desaturated", + original: false, + accent: "hsl(227, 58%, 65%)", + primary: "#35383d", + secondary: "#2c2f34", + tertiary: "#1e1f24", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Desaturated/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Crimson", + original: false, + accent: "hsl(0, 100%, 50%)", + primary: "#050000", + secondary: "#0a0000", + tertiary: "#0f0000", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Crimson/import.css);", + author: "Riddim_GLiTCH", + authorID: "801089753038061669", + }, + { + name: "Jupiter", + original: true, + accent: "#ffd89b", + primary: "#ffd89b", + secondary: "#19547b", + tertiary: "#1e1f22", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Jupiter/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + isGradient: true, + colors: ["accent", "primary", "secondary"], + }, + { + name: "Neon Candy", + original: true, + accent: "#FC00FF", + primary: "#00DBDE", + secondary: "#00DBDE", + tertiary: "#00DBDE", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/NeonCandy/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + isGradient: true, + colors: ["accent", "primary"], + }, + { + name: "Wildberry", + original: false, + accent: "#f40172", + primary: "#180029", + secondary: "#340057", + tertiary: "#4b007a", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Wildberry/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Facebook", + original: false, + accent: "#2375e1", + primary: "#18191a", + secondary: "#242526", + tertiary: "#3a3b3c", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Facebook/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Material You", + original: false, + accent: "#004977", + primary: "#1f1f1f", + secondary: "#28292a", + tertiary: "#2d2f31", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/MaterialYou/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "Discord Teal", + original: false, + accent: "#175f6d", + primary: "#313338", + secondary: "#2b2d31", + tertiary: "#1e1f22", + "dc-import": "@import url(//dablulite.github.io/css-snippets/DiscordTeal/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + colors: ["accent"], + }, + { + name: "黄昏の花 (Twilight Blossom)", + original: true, + accent: "#e100ff", + primary: "#04000a", + secondary: "#0b0024", + tertiary: "#210042", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/TwilightBlossom/import.css);", + author: "Riddim_GLiTCH", + authorID: "801089753038061669", + }, + { + name: "Chai", + original: true, + accent: "#59cd51", + primary: "#1c1e15", + secondary: "#1e2118", + tertiary: "#24291e", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Chai/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, + { + name: "CS1.6", + original: false, + accent: "#929a8d", + primary: "#3f4738", + secondary: "#5b6c51", + tertiary: "#4d5945", + "dc-import": "@import url(//dablulite.github.io/DiscordColorways/CS16/import.css);", + author: "DaBluLite", + authorID: "582170007505731594", + }, +]; + + +export const knownThemeVars = { + "Cyan": { + variable: "--cyan-accent-color", + accent: "--cyan-accent-color", + primary: "--cyan-background-primary", + secondary: "--cyan-background-secondary" + }, + "Virtual Boy": { + variable: "--VBaccent", + tertiary: "--VBaccent-muted", + alt: { + tertiary: "--VBaccent-dimmest" + } + }, + "Modular": { + variable: "--modular-hue", + accentVariables: { + h: "--modular-hue", + s: "--modular-saturation", + l: "--modular-lightness" + } + }, + "Solana": { + variable: "--accent-hue", + accentVariables: { + h: "--accent-hue", + s: "--accent-saturation", + l: "--accent-brightness" + }, + primaryVariables: { + h: "--background-accent-hue", + s: "--background-accent-saturation", + l: "--background-accent-brightness" + } + } +}; + +export const mainColors = [ + { name: "accent", title: "Accent", var: "--brand-experiment" }, + { name: "primary", title: "Primary", var: "--background-primary" }, + { name: "secondary", title: "Secondary", var: "--background-secondary" }, + { name: "tertiary", title: "Tertiary", var: "--background-tertiary" } +]; diff --git a/src/equicordplugins/discordColorways/css.ts b/src/equicordplugins/discordColorways/css.ts new file mode 100644 index 00000000..565b808e --- /dev/null +++ b/src/equicordplugins/discordColorways/css.ts @@ -0,0 +1,1001 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { UserStore } from "@webpack/common"; +import { Plugins } from "Vencord"; + +import { HexToHSL } from "./utils"; + +export const colorVariables: string[] = [ + "brand-100", + "brand-130", + "brand-160", + "brand-200", + "brand-230", + "brand-260", + "brand-300", + "brand-330", + "brand-345", + "brand-360", + "brand-400", + "brand-430", + "brand-460", + "brand-500", + "brand-530", + "brand-560", + "brand-600", + "brand-630", + "brand-660", + "brand-700", + "brand-730", + "brand-760", + "brand-800", + "brand-830", + "brand-860", + "brand-900", + "primary-900", + "primary-860", + "primary-830", + "primary-800", + "primary-760", + "primary-730", + "primary-700", + "primary-660", + "primary-645", + "primary-630", + "primary-600", + "primary-560", + "primary-530", + "primary-500", + "primary-460", + "primary-430", + "primary-400", + "primary-360", + "primary-330", + "primary-300", + "primary-260", + "primary-230", + "primary-200", + "primary-160", + "primary-130", + "primary-100", + "white-900", + "white-860", + "white-830", + "white-800", + "white-760", + "white-730", + "white-700", + "white-660", + "white-630", + "white-600", + "white-560", + "white-530", + "white-500", + "white-460", + "white-430", + "white-400", + "white-360", + "white-330", + "white-300", + "white-260", + "white-230", + "white-200", + "white-160", + "white-130", + "white-100", + "teal-900", + "teal-860", + "teal-830", + "teal-800", + "teal-760", + "teal-730", + "teal-700", + "teal-660", + "teal-630", + "teal-600", + "teal-560", + "teal-530", + "teal-500", + "teal-460", + "teal-430", + "teal-400", + "teal-360", + "teal-330", + "teal-300", + "teal-260", + "teal-230", + "teal-200", + "teal-160", + "teal-130", + "teal-100", + "black-900", + "black-860", + "black-830", + "black-800", + "black-760", + "black-730", + "black-700", + "black-660", + "black-630", + "black-600", + "black-560", + "black-530", + "black-500", + "black-460", + "black-430", + "black-400", + "black-360", + "black-330", + "black-300", + "black-260", + "black-230", + "black-200", + "black-160", + "black-130", + "black-100", + "red-900", + "red-860", + "red-830", + "red-800", + "red-760", + "red-730", + "red-700", + "red-660", + "red-630", + "red-600", + "red-560", + "red-530", + "red-500", + "red-460", + "red-430", + "red-400", + "red-360", + "red-330", + "red-300", + "red-260", + "red-230", + "red-200", + "red-160", + "red-130", + "red-100", + "yellow-900", + "yellow-860", + "yellow-830", + "yellow-800", + "yellow-760", + "yellow-730", + "yellow-700", + "yellow-660", + "yellow-630", + "yellow-600", + "yellow-560", + "yellow-530", + "yellow-500", + "yellow-460", + "yellow-430", + "yellow-400", + "yellow-360", + "yellow-330", + "yellow-300", + "yellow-260", + "yellow-230", + "yellow-200", + "yellow-160", + "yellow-130", + "yellow-100", + "green-900", + "green-860", + "green-830", + "green-800", + "green-760", + "green-730", + "green-700", + "green-660", + "green-630", + "green-600", + "green-560", + "green-530", + "green-500", + "green-460", + "green-430", + "green-400", + "green-360", + "green-330", + "green-300", + "green-260", + "green-230", + "green-200", + "green-160", + "green-130", + "green-100", +]; + +export const PrimarySatDiffs = { + 130: 63.9594, + 160: 49.4382, + 200: 37.5758, + 230: 30.3797, + 260: 22.5166, + 300: 32.5, + 330: 27.0968, + 345: 22.5166, + 360: 18.9189, + 400: -14.4, + 430: -33.0435, + 460: 25.2101, + 500: -11.0236, + 530: -3.0303, + 645: 7.40741, + 660: 3.0303, + 730: 11.9403, + 800: 25, +}; + +export const BrandSatDiffs = { + 100: -9.54712, + 130: 2.19526, + 160: -1.17509, + 200: -2.72351, + 230: 1.62225, + 260: 0.698487, + 300: 0.582411, + 330: -0.585823, + 345: -0.468384, + 360: 0.582411, + 400: 0.582411, + 430: 0.116754, + 460: -0.116891, + 530: -24.8194, + 560: -49.927, + 600: -58.8057, + 630: -58.8057, + 660: -58.0256, + 700: -58.2202, + 730: -58.6103, + 760: -58.4151, + 800: -57.2502, + 830: -57.4436, + 860: -58.4151, + 900: -52.5074 +}; + +export const BrandLightDiffs = { + 100: 33.5, + 130: 32.2, + 160: 30.2, + 200: 28.2, + 230: 26.2999, + 260: 23.8999, + 300: 21.2, + 330: 16.8999, + 345: 14.0999, + 360: 12.7999, + 400: 7.0999, + 430: 5.0999, + 460: 2.7999, + 530: -5.9, + 560: -12.3, + 600: -20.6, + 630: -26.5, + 660: -31.4, + 700: -38.8, + 730: -40.4, + 760: -42.5, + 800: -45.3, + 830: -49.8, + 860: -55.1, + 900: -61.6 +}; + +export const pureGradientBase = ` +.theme-dark :is(.colorwaysPreview-modal, .colorwaysPreview-wrapper) { + --dc-overlay-color: 0 0 0; + --dc-overlay-color-inverse: 255 255 255; + --dc-overlay-opacity-1: 0.85; + --dc-overlay-opacity-2: 0.8; + --dc-overlay-opacity-3: 0.7; + --dc-overlay-opacity-4: 0.5; + --dc-overlay-opacity-5: 0.4; + --dc-overlay-opacity-6: 0.1; + --dc-overlay-opacity-hover: 0.5; + --dc-overlay-opacity-hover-inverse: 0.08; + --dc-overlay-opacity-active: 0.45; + --dc-overlay-opacity-active-inverse: 0.1; + --dc-overlay-opacity-selected: 0.4; + --dc-overlay-opacity-selected-inverse: 0.15; + --dc-overlay-opacity-chat: 0.8; + --dc-overlay-opacity-home: 0.85; + --dc-overlay-opacity-home-card: 0.8; + --dc-overlay-opacity-app-frame: var(--dc-overlay-opacity-4); + --dc-guild-button: rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-6)); + --dc-secondary-alt: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-chat-header: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-2)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-2))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; +} +.theme-light :is(.colorwaysPreview-modal, .colorwaysPreview-wrapper) { + --dc-overlay-color: 255 255 255; + --dc-overlay-color-inverse: 0 0 0; + --dc-overlay-opacity-1: 0.9; + --dc-overlay-opacity-2: 0.8; + --dc-overlay-opacity-3: 0.7; + --dc-overlay-opacity-4: 0.6; + --dc-overlay-opacity-5: 0.3; + --dc-overlay-opacity-6: 0.15; + --dc-overlay-opacity-hover: 0.7; + --dc-overlay-opacity-hover-inverse: 0.02; + --dc-overlay-opacity-active: 0.65; + --dc-overlay-opacity-active-inverse: 0.03; + --dc-overlay-opacity-selected: 0.6; + --dc-overlay-opacity-selected-inverse: 0.04; + --dc-overlay-opacity-chat: 0.9; + --dc-overlay-opacity-home: 0.7; + --dc-overlay-opacity-home-card: 0.9; + --dc-overlay-opacity-app-frame: var(--dc-overlay-opacity-5); + --dc-guild-button: rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3)); + --dc-secondary-alt: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-chat-header: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; +} +.colorwaysPreview-modal, +.colorwaysPreview-wrapper { + --dc-overlay-1: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-2: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-2)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-2))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-3: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-4: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-4)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-4))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-5: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-5)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-5))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-6: linear-gradient(rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-6)),rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-6))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-hover: linear-gradient(rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-hover-inverse)),rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-hover-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-hover)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-hover))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-active: linear-gradient(rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-active-inverse)),rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-active-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-active)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-active))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-selected: linear-gradient(rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-selected-inverse)),rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-selected-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-selected)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-selected))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-chat: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-chat)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-chat))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-home: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-home)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-home))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-home-card: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-home-card)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-home-card))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; + --dc-overlay-app-frame: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-app-frame)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-app-frame))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; +}`; + + +export function gradientBase(accentColor?: string, discordSaturation = false) { + return `@import url(//dablulite.github.io/css-snippets/NitroThemesFix/import.css); +.theme-dark { + --bg-overlay-color: 0 0 0; + --bg-overlay-color-inverse: 255 255 255; + --bg-overlay-opacity-1: 0.85; + --bg-overlay-opacity-2: 0.8; + --bg-overlay-opacity-3: 0.7; + --bg-overlay-opacity-4: 0.5; + --bg-overlay-opacity-5: 0.4; + --bg-overlay-opacity-6: 0.1; + --bg-overlay-opacity-hover: 0.5; + --bg-overlay-opacity-hover-inverse: 0.08; + --bg-overlay-opacity-active: 0.45; + --bg-overlay-opacity-active-inverse: 0.1; + --bg-overlay-opacity-selected: 0.4; + --bg-overlay-opacity-selected-inverse: 0.15; + --bg-overlay-opacity-chat: 0.8; + --bg-overlay-opacity-home: 0.85; + --bg-overlay-opacity-home-card: 0.8; + --bg-overlay-opacity-app-frame: var(--bg-overlay-opacity-4); +} +.theme-light { + --bg-overlay-color: 255 255 255; + --bg-overlay-color-inverse: 0 0 0; + --bg-overlay-opacity-1: 0.9; + --bg-overlay-opacity-2: 0.8; + --bg-overlay-opacity-3: 0.7; + --bg-overlay-opacity-4: 0.6; + --bg-overlay-opacity-5: 0.3; + --bg-overlay-opacity-6: 0.15; + --bg-overlay-opacity-hover: 0.7; + --bg-overlay-opacity-hover-inverse: 0.02; + --bg-overlay-opacity-active: 0.65; + --bg-overlay-opacity-active-inverse: 0.03; + --bg-overlay-opacity-selected: 0.6; + --bg-overlay-opacity-selected-inverse: 0.04; + --bg-overlay-opacity-chat: 0.9; + --bg-overlay-opacity-home: 0.7; + --bg-overlay-opacity-home-card: 0.9; + --bg-overlay-opacity-app-frame: var(--bg-overlay-opacity-5); +} +.children_cde9af:after, .form_d8a4a1:before { + content: none; +} +.scroller_de945b { + background: var(--bg-overlay-app-frame,var(--background-tertiary)); +} +.expandedFolderBackground_b1385f { + background: rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6)); +} +.wrapper__8436d:not(:hover):not(.selected_ae80f7) .childWrapper_a6ce15 { + background: rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6)); +} +.folder__17546:has(.expandedFolderIconWrapper__324c1) { + background: var(--bg-overlay-6,var(--background-secondary)); +} +.circleIconButton__05cf2:not(.selected_aded59) { + background: rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6)); +} +.auto_a3c0bd::-webkit-scrollbar-thumb, +.thin_b1c063::-webkit-scrollbar-thumb { + background-size: 200vh; + background-image: -webkit-gradient(linear,left top,left bottom,from(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-4))),to(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-4)))),var(--custom-theme-background); + background-image: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-4)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-4))),var(--custom-theme-background); +} +.auto_a3c0bd::-webkit-scrollbar-track { + background-size: 200vh; + background-image: -webkit-gradient(linear,left top,left bottom,from(rgb(var(--bg-overlay-color)/.4)),to(rgb(var(--bg-overlay-color)/.4))),var(--custom-theme-background); + background-image: linear-gradient(rgb(var(--bg-overlay-color)/.4),rgb(var(--bg-overlay-color)/.4)),var(--custom-theme-background); +} +:root:root { + --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[100])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)}; + --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[130])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[130]) * 10) / 10, 0)}%; + --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[160])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[160]) * 10) / 10, 0)}%; + --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[200])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[200]) * 10) / 10, 0)}%; + --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[230])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[230]) * 10) / 10, 0)}%; + --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[260])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[260]) * 10) / 10, 0)}%; + --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[300])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[300]) * 10) / 10, 0)}%; + --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[330])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[330]) * 10) / 10, 0)}%; + --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[345])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[345]) * 10) / 10, 0)}%; + --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[360])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[360]) * 10) / 10, 0)}%; + --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[400])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[400]) * 10) / 10, 0)}%; + --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[430])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[430]) * 10) / 10, 0)}%; + --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[460])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[460]) * 10) / 10, 0)}%; + --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; + --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[530])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[530]) * 10) / 10, 100)}%; + --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[560])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[560]) * 10) / 10, 100)}%; + --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[600])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[600]) * 10) / 10, 100)}%; + --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[630])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[630]) * 10) / 10, 100)}%; + --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[660])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[660]) * 10) / 10, 100)}%; + --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[700])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[700]) * 10) / 10, 100)}%; + --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[730])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[730]) * 10) / 10, 100)}%; + --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[760])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[760]) * 10) / 10, 100)}%; + --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[800])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[800]) * 10) / 10, 100)}%; + --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[830])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[830]) * 10) / 10, 100)}%; + --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[860])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[860]) * 10) / 10, 100)}%; + --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[900])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[900]) * 10) / 10, 100)}%; + --bg-overlay-1: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-2: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-2)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-2))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-3: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-3)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-3))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-4: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-4)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-4))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-5: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-5)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-5))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-6: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-hover: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-hover-inverse)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-hover-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-hover)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-hover))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-active: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-active-inverse)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-active-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-active)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-active))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-selected: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-selected-inverse)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-selected-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-selected)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-selected))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-chat: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-home: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-home-card: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; + --bg-overlay-app-frame: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; +}`; +} + +export function generateCss(primaryColor: string, secondaryColor: string, tertiaryColor: string, accentColor: string, tintedText: boolean, discordSaturation: boolean, mutedTextBrightness?: number, name?: string) { + return `/** + * @name ${name} + * @version ${(Plugins.plugins.DiscordColorways as any).creatorVersion} + * @description Automatically generated Colorway. + * @author ${UserStore.getCurrentUser().username} + * @authorId ${UserStore.getCurrentUser().id} + */ +:root:root { + --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[100])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)}; + --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[130])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[130]) * 10) / 10, 0)}%; + --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[160])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[160]) * 10) / 10, 0)}%; + --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[200])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[200]) * 10) / 10, 0)}%; + --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[230])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[230]) * 10) / 10, 0)}%; + --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[260])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[260]) * 10) / 10, 0)}%; + --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[300])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[300]) * 10) / 10, 0)}%; + --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[330])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[330]) * 10) / 10, 0)}%; + --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[345])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[345]) * 10) / 10, 0)}%; + --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[360])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[360]) * 10) / 10, 0)}%; + --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[400])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[400]) * 10) / 10, 0)}%; + --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[430])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[430]) * 10) / 10, 0)}%; + --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[460])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[460]) * 10) / 10, 0)}%; + --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; + --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[530])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[530]) * 10) / 10, 100)}%; + --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[560])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[560]) * 10) / 10, 100)}%; + --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[600])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[600]) * 10) / 10, 100)}%; + --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[630])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[630]) * 10) / 10, 100)}%; + --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[660])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[660]) * 10) / 10, 100)}%; + --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[700])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[700]) * 10) / 10, 100)}%; + --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[730])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[730]) * 10) / 10, 100)}%; + --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[760])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[760]) * 10) / 10, 100)}%; + --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[800])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[800]) * 10) / 10, 100)}%; + --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[830])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[830]) * 10) / 10, 100)}%; + --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[860])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[860]) * 10) / 10, 100)}%; + --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[900])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[900]) * 10) / 10, 100)}%; +} +.theme-dark { + --primary-800-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%; + --primary-730-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[730])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - 3.6, 0)}%; + --primary-700-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%; + --primary-660-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[660])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 3.6, 0)}%; + --primary-645-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[645])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 1.1, 0)}%; + --primary-630-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${HexToHSL("#" + secondaryColor)[2]}%; + --primary-600-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%; + --primary-560-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 3.6, 100)}%; + --primary-530-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[530])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 2), 100)}%; + --primary-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[500])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${mutedTextBrightness || Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)}%; + --interactive-muted: hsl(${HexToHSL("#" + primaryColor)[0]} ${HexToHSL("#" + primaryColor)[1] / 2}% ${Math.max(Math.min(HexToHSL("#" + primaryColor)[2] - 5, 100), 45)}%); + ${tintedText ? `--primary-460-hsl: 0 calc(var(--saturation-factor, 1)*0%) 50%; + --primary-430: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL(`#${primaryColor}`)[1] / 100) * (100 + PrimarySatDiffs[430])) * 10) / 10 : HexToHSL(`#${primaryColor}`)[1]}%), 90%)` : `hsl(${HexToHSL(`#${secondaryColor}`)[0]}, calc(var(--saturation-factor, 1)*100%), 20%)`)}; + --primary-400: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL(`#${primaryColor}`)[1] / 100) * (100 + PrimarySatDiffs[400])) * 10) / 10 : HexToHSL(`#${primaryColor}`)[1]}%), 90%)` : `hsl(${HexToHSL(`#${secondaryColor}`)[0]}, calc(var(--saturation-factor, 1)*100%), 20%)`)}; + --primary-360: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL(`#${primaryColor}`)[1] / 100) * (100 + PrimarySatDiffs[360])) * 10) / 10 : HexToHSL(`#${primaryColor}`)[1]}%), 90%)` : `hsl(${HexToHSL(`#${secondaryColor}`)[0]}, calc(var(--saturation-factor, 1)*100%), 20%)`)};` : ""} +} +.theme-light { + --white-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 80, 90)}%; + --primary-130-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 80, 85)}%; + --primary-160-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[660])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 76.4, 82.5)}%; + --primary-200-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.min(HexToHSL("#" + tertiaryColor)[2] + 80, 80)}%; +} +.emptyPage_feb902, +.scrollerContainer_dda72c, +.container__03ec9, +.header__71942 { + background-color: unset !important; +} +.container__6b2e5, +.container__03ec9, +.header__71942 { + background: transparent !important; +}${(Math.round(HexToHSL("#" + primaryColor)[2]) > 80) ? `\n\n/*Primary*/ +.theme-dark .container_bd15da, +.theme-dark .body__616e6, +.theme-dark .toolbar__62fb5, +.theme-dark .container_e1387b, +.theme-dark .messageContent_abea64, +.theme-dark .attachButtonPlus_fd0021, +.theme-dark .username__0b0e7:not([style]), +.theme-dark .children_cde9af, +.theme-dark .buttonContainer__6de7e, +.theme-dark .listItem__48528, +.theme-dark .body__616e6 .caret__33d19, +.theme-dark .body__616e6 .titleWrapper_d6133e > h1, +.theme-dark .body__616e6 .icon_ae0b42 { + --white-500: black !important; + --interactive-normal: black !important; + --text-normal: black !important; + --text-muted: black !important; + --header-primary: black !important; + --header-secondary: black !important; +} + +.theme-dark .contentRegionScroller__9ae20 :not(.mtk1,.mtk2,.mtk3,.mtk4,.mtk5,.mtk6,.mtk7,.mtk8,.mtk9,.monaco-editor .line-numbers) { + --white-500: black !important; +} + +.theme-dark .container__26baa { + --channel-icon: black; +} + +.theme-dark .callContainer__1477d { + --white-500: ${(HexToHSL("#" + tertiaryColor)[2] > 80) ? "black" : "white"} !important; +} + +.theme-dark .channelTextArea_c2094b { + --text-normal: ${(HexToHSL("#" + primaryColor)[2] + 3.6 > 80) ? "black" : "white"}; +} + +.theme-dark .placeholder_dec8c7 { + --channel-text-area-placeholder: ${(HexToHSL("#" + primaryColor)[2] + 3.6 > 80) ? "black" : "white"}; + opacity: .6; +} + +.theme-dark .colorwaySelectorIcon { + background-color: black; +} + +.theme-dark .root_a28985 > .header__5e5a6 > h1 { + color: black; +} +/*End Primary*/`: ""}${(HexToHSL("#" + secondaryColor)[2] > 80) ? `\n\n/*Secondary*/ +.theme-dark .wrapper__3c6d5 *, +.theme-dark .sidebar_e031be *:not(.hasBanner__04337 *), +.theme-dark .members__573eb *:not([style]), +.theme-dark .sidebarRegionScroller__8113e *, +.theme-dark .header__8e271, +.theme-dark .lookFilled__950dd.colorPrimary_ebe632 { + --white-500: black !important; + --channels-default: black !important; + --channel-icon: black !important; + --interactive-normal: var(--white-500); + --interactive-hover: var(--white-500); + --interactive-active: var(--white-500); +} + +.theme-dark .channelRow__538ef { + background-color: var(--background-secondary); +} + +.theme-dark .channelRow__538ef * { + --channel-icon: black; +} + +.theme-dark #app-mount .activity_bafb94 { + --channels-default: var(--white-500) !important; +} + +.theme-dark .nameTag__77ab2 { + --header-primary: black !important; + --header-secondary: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 90%)" : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")} !important; +} + +.theme-dark .bannerVisible_ef30fe .headerContent__6fcc7 { + color: #fff; +} + +.theme-dark .embedFull__14919 { + --text-normal: black; +} +/*End Secondary*/`: ""}${HexToHSL("#" + tertiaryColor)[2] > 80 ? `\n\n/*Tertiary*/ +.theme-dark .winButton_f17fb6, +.theme-dark .searchBar__310d8 *, +.theme-dark .wordmarkWindows_ffbc5e, +.theme-dark .searchBar__5a20a *, +.theme-dark .searchBarComponent__8f95f { + --white-500: black !important; +} + +.theme-dark [style="background-color: var(--background-secondary);"] { + color: ${HexToHSL("#" + secondaryColor)[2] > 80 ? "black" : "white"}; +} + +.theme-dark .popout__24e32 > * { + --interactive-normal: black !important; + --header-secondary: black !important; +} + +.theme-dark .tooltip__7b090 { + --text-normal: black !important; +} +.theme-dark .children_cde9af .icon_ae0b42 { + color: var(--interactive-active) !important; +} +/*End Tertiary*/`: ""}${HexToHSL("#" + accentColor)[2] > 80 ? `\n\n/*Accent*/ +.selected_aded59 *, +.selected_ae80f7 *, +#app-mount .lookFilled__950dd.colorBrand__27d57:not(.buttonColor__7bad9), +.colorDefault_e361cf.focused_dcafb9, +.row__9e25f:hover, +.colorwayInfoIcon, +.checkmarkCircle_b1b1cc > circle { + --white-500: black !important; +} + +.ColorwaySelectorBtn:hover .vc-pallete-icon { + color: #000 !important; +} + +:root:root { + --mention-foreground: black !important; +} +/*End Accent*/`: ""}`; +} + +export function getAutoPresets(accentColor?: string) { + function hueRotation() { + return `:root:root { + --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)}; + --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[130]) * 10) / 10, 0)}%; + --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[160]) * 10) / 10, 0)}%; + --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[200]) * 10) / 10, 0)}%; + --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[230]) * 10) / 10, 0)}%; + --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[260]) * 10) / 10, 0)}%; + --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[300]) * 10) / 10, 0)}%; + --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[330]) * 10) / 10, 0)}%; + --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[345]) * 10) / 10, 0)}%; + --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[360]) * 10) / 10, 0)}%; + --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[400]) * 10) / 10, 0)}%; + --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[430]) * 10) / 10, 0)}%; + --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[460]) * 10) / 10, 0)}%; + --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; + --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[530]) * 10) / 10, 100)}%; + --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[560]) * 10) / 10, 100)}%; + --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[600]) * 10) / 10, 100)}%; + --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[630]) * 10) / 10, 100)}%; + --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[660]) * 10) / 10, 100)}%; + --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[700]) * 10) / 10, 100)}%; + --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[730]) * 10) / 10, 100)}%; + --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[760]) * 10) / 10, 100)}%; + --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[800]) * 10) / 10, 100)}%; + --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[830]) * 10) / 10, 100)}%; + --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[860]) * 10) / 10, 100)}%; + --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[900]) * 10) / 10, 100)}%; + --primary-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 7%; + --primary-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*10%) 13%; + --primary-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*10%) 13%; + --primary-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 15%; + --primary-645-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 16%; + --primary-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 18%; + --primary-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 21%; + --primary-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 24%; + --primary-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 24%; + --primary-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 24%; +}`; + } + + function accentSwap() { + return `:root:root { + --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)}; + --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[130]) * 10) / 10, 0)}%; + --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[160]) * 10) / 10, 0)}%; + --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[200]) * 10) / 10, 0)}%; + --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[230]) * 10) / 10, 0)}%; + --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[260]) * 10) / 10, 0)}%; + --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[300]) * 10) / 10, 0)}%; + --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[330]) * 10) / 10, 0)}%; + --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[345]) * 10) / 10, 0)}%; + --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[360]) * 10) / 10, 0)}%; + --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[400]) * 10) / 10, 0)}%; + --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[430]) * 10) / 10, 0)}%; + --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[460]) * 10) / 10, 0)}%; + --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; + --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[530]) * 10) / 10, 100)}%; + --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[560]) * 10) / 10, 100)}%; + --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[600]) * 10) / 10, 100)}%; + --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[630]) * 10) / 10, 100)}%; + --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[660]) * 10) / 10, 100)}%; + --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[700]) * 10) / 10, 100)}%; + --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[730]) * 10) / 10, 100)}%; + --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[760]) * 10) / 10, 100)}%; + --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[800]) * 10) / 10, 100)}%; + --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[830]) * 10) / 10, 100)}%; + --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[860]) * 10) / 10, 100)}%; + --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[900]) * 10) / 10, 100)}%; +}`; + } + + function materialYou() { + return `:root:root { + --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*90.5%) 56.5; + --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*102.2%) 55.2%; + --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*98.8%) 53.2%; + --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*97.3%) 51.2%; + --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*101.6%) 49.3%; + --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.7%) 46.9%; + --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.6%) 44.2%; + --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*99.4%) 39.9%; + --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*99.5%) 37.1%; + --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.6%) 35.8%; + --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.6%) 30.1%; + --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.1%) 28.1%; + --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*99.9%) 25.8%; + --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100%) 23%; + --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*75.2%) 17.1%; + --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*50.1%) 10.7%; + --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.2%) 2.4%; + --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.2%) -3.5%; + --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*42%) -8.4%; + --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.8%) -15.8%; + --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.4%) -17.4%; + --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.6%) -19.5%; + --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*42.7%) -22.3%; + --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*42.6%) -26.8%; + --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.6%) -32.1%; + --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*47.5%) -38.6%; + --primary-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*10%) 10.8%; + --primary-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*8%) 14.4%; + --primary-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*16%) 18%; + --primary-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*14%) 12.4%; + --primary-645-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*14%) 14.9%; + --primary-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 16%; + --primary-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 12%; + --primary-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 15.6%; + --primary-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 19.2%; + --primary-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 22.8%; + --primary-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 50%; + --primary-430: hsl(${HexToHSL("#" + accentColor)[0]}, calc(var(--saturation-factor, 1)*12%), 90%); + --primary-400: hsl(${HexToHSL("#" + accentColor)[0]}, calc(var(--saturation-factor, 1)*12%), 90%); + --primary-360: hsl(${HexToHSL("#" + accentColor)[0]}, calc(var(--saturation-factor, 1)*12%), 90%); +} +.emptyPage_feb902, +.scrollerContainer_dda72c, +.container__03ec9, +.header__71942 { + background-color: unset !important; +}`; + } + + return { + hueRotation: { + name: "Hue Rotation", + id: "hueRotation", + preset: hueRotation + }, + accentSwap: { + name: "Accent Swap", + id: "accentSwap", + preset: accentSwap + }, + materialYou: { + name: "Material You", + id: "materialYou", + preset: materialYou + } + } as { [key: string]: { name: string, id: string, preset: () => string; }; }; +} + +export function getPreset(primaryColor?: string, secondaryColor?: string, tertiaryColor?: string, accentColor?: string): { [preset: string]: { name: string, preset: (...args: any) => string | { full: string, base: string; }, id: string, colors: string[]; }; } { + function cyanLegacy(discordSaturation = false) { + return `:root:root { + --cyan-accent-color: #${accentColor}; + --cyan-background-primary: hsl(${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%/40%); + --cyan-background-secondary: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.min(HexToHSL("#" + tertiaryColor)[2] + (3.6 * 2), 100)}%); +}`; + } + + function cyan(discordSaturation = false) { + return `:root:root { + --cyan-accent-color: #${accentColor}; + --cyan-background-primary: hsl(${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%/60%); + --cyan-second-layer: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.min(HexToHSL("#" + tertiaryColor)[2] + (3.6 * 2), 100)}%/60%); +}`; + } + + function nexusRemastered(discordSaturation = false) { + return `:root:root { + --nexus-accent-color: #${accentColor}; + --nexus-background-secondary: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%); + --nexus-background-elevated: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%); + --nexus-background-floating: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%); + --nexus-background-tertiary: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%); + --home-background: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%); + --nexus-background-primary: hsl(${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%); + --primary-800-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%; + --primary-730-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[730])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - 3.6, 0)}%; + --primary-700-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%; + --primary-660-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[660])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 3.6, 0)}%; + --primary-645-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[645])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 1.1, 0)}%; + --primary-630-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${HexToHSL("#" + secondaryColor)[2]}%; + --primary-600-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%; + --primary-560-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 3.6, 100)}%; + --primary-530-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[530])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 2), 100)}%; + --primary-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[500])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)}%; + --primary-200: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[200])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")} +} +.theme-dark { + --background-tertiary: var(--primary-700) !important; +} +.theme-light { + --background-tertiary: var(--primary-200) !important; +}`; + } + + function modular(discordSaturation = false) { + return `:root:root { + --brand-experiment: #${accentColor}; + --primary-800-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%; + --primary-730-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[730])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - 3.6, 0)}%; + --primary-700-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%; + --primary-660-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[660])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 3.6, 0)}%; + --primary-645-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[645])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 1.1, 0)}%; + --primary-630-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${HexToHSL("#" + secondaryColor)[2]}%; + --primary-600-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%; + --primary-560-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 3.6, 100)}%; + --primary-530-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[530])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 2), 100)}% !important; + --primary-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[500])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)}% !important; + --primary-330: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[330])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")}; + --primary-360: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[360])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")}; + --primary-400: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[400])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")} +}`; + } + + function virtualBoy(discordSaturation = false) { + return `:root:root { + --VBaccent: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; + --VBaccent-muted: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(((HexToHSL("#" + tertiaryColor)[2]) - 10), 0)}%; + --VBaccent-dimmest: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.min((HexToHSL("#" + tertiaryColor)[2] + (3.6 * 5) - 3), 100)}%; +}`; + } + + function solana(discordSaturation = false) { + return `:root:root { + --accent-hue: ${HexToHSL("#" + accentColor)[0]}; + --accent-saturation: calc(var(--saturation-factor, 1)${HexToHSL("#" + accentColor)[1]}%); + --accent-brightness: ${HexToHSL("#" + accentColor)[2]}%; + --background-accent-hue: ${HexToHSL("#" + primaryColor)[0]}; + --background-accent-saturation: calc(var(--saturation-factor, 1)${HexToHSL("#" + primaryColor)[1]}%); + --background-accent-brightness: ${HexToHSL("#" + primaryColor)[2]}%; + --background-overlay-opacity: 0%; +}`; + } + + function gradientType1(discordSaturation = false) { + return { + full: `${gradientBase(accentColor, discordSaturation)} + :root:root { + --custom-theme-background: linear-gradient(239.16deg, #${primaryColor} 10.39%, #${secondaryColor} 26.87%, #${tertiaryColor} 48.31%, hsl(${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 3.6, 100)}%) 64.98%, #${primaryColor} 92.5%); + }`, + base: `239.16deg, #${primaryColor} 10.39%, #${secondaryColor} 26.87%, #${tertiaryColor} 48.31%, hsl(${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 3.6, 100)}%) 64.98%, #${primaryColor} 92.5%` + }; + } + + function gradientType2(discordSaturation = false) { + return { + full: `${gradientBase(accentColor, discordSaturation)} + :root:root { + --custom-theme-background: linear-gradient(48.17deg, #${primaryColor} 11.21%, #${secondaryColor} 61.92%); + }`, base: `48.17deg, #${primaryColor} 11.21%, #${secondaryColor} 61.92%` + }; + } + + return { + default: { + name: "Default", + preset: generateCss, + id: "default", + colors: ["accent", "primary", "secondary", "tertiary"] + }, + cyan: { + name: "Cyan", + preset: cyan, + id: "cyan", + colors: ["accent", "primary", "secondary"] + }, + cyanLegacy: { + name: "Cyan 1 (Legacy)", + preset: cyanLegacy, + id: "cyanLegacy", + colors: ["accent", "primary", "secondary"] + }, + nexusRemastered: { + name: "Nexus Remastered", + preset: nexusRemastered, + id: "nexusRemastered", + colors: ["accent", "primary", "secondary", "tertiary"] + }, + virtualBoy: { + name: "Virtual Boy", + preset: virtualBoy, + id: "virtualBoy", + colors: ["accent", "tertiary"] + }, + modular: { + name: "Modular", + preset: modular, + id: "modular", + colors: ["accent", "primary", "secondary", "tertiary"] + }, + solana: { + name: "Solana", + preset: solana, + id: "solana", + colors: ["accent", "primary"] + }, + gradientType1: { + name: "Gradient Type 1", + preset: gradientType1, + id: "gradientType1", + colors: ["accent", "primary", "secondary", "tertiary"] + }, + gradientType2: { + name: "Gradient Type 2", + preset: gradientType2, + id: "gradientType2", + colors: ["accent", "primary", "secondary"] + }, + hueRotation: { + name: "Hue Rotation", + preset: getAutoPresets(accentColor).hueRotation.preset, + id: "hueRotation", + colors: ["accent"] + }, + accentSwap: { + name: "Accent Swap", + preset: getAutoPresets(accentColor).accentSwap.preset, + id: "accentSwap", + colors: ["accent"] + }, + materialYou: { + name: "Material You", + preset: getAutoPresets(accentColor).materialYou.preset, + id: "materialYou", + colors: ["accent"] + } + }; +} +export const gradientPresetIds = [ + "gradientType1", + "gradientType2" +]; diff --git a/src/equicordplugins/discordColorways/index.tsx b/src/equicordplugins/discordColorways/index.tsx new file mode 100644 index 00000000..d85580b3 --- /dev/null +++ b/src/equicordplugins/discordColorways/index.tsx @@ -0,0 +1,416 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import * as DataStore from "@api/DataStore"; +import { addAccessory, removeAccessory } from "@api/MessageAccessories"; +import { addServerListElement, removeServerListElement, ServerListRenderPosition } from "@api/ServerList"; +import { disableStyle, enableStyle } from "@api/Styles"; +import { Flex } from "@components/Flex"; +import { Devs, EquicordDevs } from "@utils/constants"; +import { ModalProps, openModal } from "@utils/modal"; +import definePlugin from "@utils/types"; +import { findByProps } from "@webpack"; +import { + Button, + Clipboard, + Forms, + Heading, + i18n, + SettingsRouter, + Toasts +} from "@webpack/common"; +import { CSSProperties } from "react"; +import { Plugins } from "Vencord"; + +import AutoColorwaySelector from "./components/AutoColorwaySelector"; +import ColorPickerModal from "./components/ColorPicker"; +import ColorwaysButton from "./components/ColorwaysButton"; +import CreatorModal from "./components/CreatorModal"; +import Selector from "./components/Selector"; +import OnDemandWaysPage from "./components/SettingsTabs/OnDemandPage"; +import SettingsPage from "./components/SettingsTabs/SettingsPage"; +import SourceManager from "./components/SettingsTabs/SourceManager"; +import Store from "./components/SettingsTabs/Store"; +import Spinner from "./components/Spinner"; +import { defaultColorwaySource } from "./constants"; +import { generateCss, getAutoPresets } from "./css"; +import style from "./style.css?managed"; +import { ColorPickerProps, ColorwayObject } from "./types"; +import { colorToHex, hexToString } from "./utils"; + +export let ColorPicker: React.FunctionComponent = () => { + return ; +}; + +(async function () { + const [ + customColorways, + colorwaySourceFiles, + showColorwaysButton, + onDemandWays, + onDemandWaysTintedText, + useThinMenuButton, + onDemandWaysDiscordSaturation, + onDemandWaysOsAccentColor, + activeColorwayObject, + selectorViewMode, + showLabelsInSelectorGridView + ] = await DataStore.getMany([ + "customColorways", + "colorwaySourceFiles", + "showColorwaysButton", + "onDemandWays", + "onDemandWaysTintedText", + "useThinMenuButton", + "onDemandWaysDiscordSaturation", + "onDemandWaysOsAccentColor", + "activeColorwayObject", + "selectorViewMode", + "showLabelsInSelectorGridView" + ]); + + const defaults = [ + { name: "showColorwaysButton", value: showColorwaysButton, default: false }, + { name: "onDemandWays", value: onDemandWays, default: false }, + { name: "onDemandWaysTintedText", value: onDemandWaysTintedText, default: true }, + { name: "useThinMenuButton", value: useThinMenuButton, default: false }, + { name: "onDemandWaysDiscordSaturation", value: onDemandWaysDiscordSaturation, default: false }, + { name: "onDemandWaysOsAccentColor", value: onDemandWaysOsAccentColor, default: false }, + { name: "activeColorwayObject", value: activeColorwayObject, default: { id: null, css: null, sourceType: null, source: null } }, + { name: "selectorViewMode", value: selectorViewMode, default: "grid" }, + { name: "showLabelsInSelectorGridView", value: showLabelsInSelectorGridView, default: false } + ]; + + defaults.forEach(({ name, value, default: def }) => { + if (!value) DataStore.set(name, def); + }); + + if (customColorways) { + if (!customColorways[0].colorways) { + DataStore.set("customColorways", [{ name: "Custom", colorways: customColorways }]); + } + } else { + DataStore.set("customColorways", []); + } + + if (colorwaySourceFiles) { + if (typeof colorwaySourceFiles[0] === "string") { + DataStore.set("colorwaySourceFiles", colorwaySourceFiles.map((sourceURL: string, i: number) => { + return { name: sourceURL === defaultColorwaySource ? "Project Colorway" : `Source #${i}`, url: sourceURL }; + })); + } + } else { + DataStore.set("colorwaySourceFiles", [{ + name: "Project Colorway", + url: defaultColorwaySource + }]); + } + +})(); + +export const ColorwayCSS = { + get: () => document.getElementById("activeColorwayCSS")!.textContent || "", + set: (e: string) => { + if (!document.getElementById("activeColorwayCSS")) { + document.head.append(Object.assign(document.createElement("style"), { + id: "activeColorwayCSS", + textContent: e + })); + } else document.getElementById("activeColorwayCSS")!.textContent = e; + }, + remove: () => document.getElementById("activeColorwayCSS")!.remove(), +}; + +export const versionData = { + pluginVersion: "5.7.1", + creatorVersion: "1.20", +}; + +export default definePlugin({ + name: "DiscordColorways", + description: "A plugin that offers easy access to simple color schemes/themes for Discord, also known as Colorways", + authors: [EquicordDevs.DaBluLite, Devs.ImLvna], + dependencies: ["ServerListAPI", "MessageAccessoriesAPI"], + pluginVersion: versionData.pluginVersion, + creatorVersion: versionData.creatorVersion, + toolboxActions: { + "Change Colorway": () => openModal(props => ), + "Open Colorway Creator": () => openModal(props => ), + "Open Color Stealer": () => openModal(props => ), + "Open Settings": () => SettingsRouter.open("ColorwaysSettings"), + "Open On-Demand Settings": () => SettingsRouter.open("ColorwaysOnDemand"), + "Manage Colorways...": () => SettingsRouter.open("ColorwaysManagement"), + "Change Auto Colorway Preset": async () => { + const [ + activeAutoPreset, + activeColorwayObject + ] = await DataStore.getMany([ + "activeAutoPreset", + "activeColorwayObject" + ]); + openModal((props: ModalProps) => { + if (activeColorwayObject.id === "Auto") { + const demandedColorway = getAutoPresets(colorToHex(getComputedStyle(document.body).getPropertyValue("--os-accent-color")))[autoPresetId].preset(); + DataStore.set("activeColorwayObject", { id: "Auto", css: demandedColorway, sourceType: "online", source: null }); + ColorwayCSS.set(demandedColorway); + } + }} />); + } + }, + patches: [ + // Credits to Kyuuhachi for the BetterSettings plugin patches + { + find: "this.renderArtisanalHack()", + replacement: { + match: /createPromise:\(\)=>([^:}]*?),webpackId:"\d+",name:(?!="CollectiblesShop")"[^"]+"/g, + replace: "$&,_:$1", + predicate: () => true + } + + }, + { + find: "Messages.USER_SETTINGS_WITH_BUILD_OVERRIDE.format", + replacement: { + match: /(?<=(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?openContextMenuLazy.{0,100}?(await Promise\.all[^};]*?\)\)).*?,)(?=\1\(this)/, + replace: "(async ()=>$2)()," + }, + predicate: () => true + }, + { + find: "colorPickerFooter:", + replacement: { + match: /function (\i).{0,200}colorPickerFooter:/, + replace: "$self.ColorPicker=$1;$&", + }, + }, + { + find: "Messages.ACTIVITY_SETTINGS", + replacement: { + match: /(?<=section:(.{0,50})\.DIVIDER\}\))([,;])(?=.{0,200}(\i)\.push.{0,100}label:(\i)\.header)/, + replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}` + } + }, + { + find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL", + replacement: { + match: /(?<=function\((\i),\i\)\{)(?=let \i=Object.values\(\i.UserSettingsSections\).*?(\i)\.default\.open\()/, + replace: "$2.default.open($1);return;" + } + } + ], + + set ColorPicker(e) { + ColorPicker = e; + }, + + isRightSpot({ header, settings }: { header?: string; settings?: string[]; }) { + const firstChild = settings?.[0]; + // lowest two elements... sanity backup + if (firstChild === "LOGOUT" || firstChild === "SOCIAL_LINKS") return true; + + const settingsLocation = "belowNitro"; + + if (!header) return; + + const names = { + top: i18n.Messages.USER_SETTINGS, + aboveNitro: i18n.Messages.BILLING_SETTINGS, + belowNitro: i18n.Messages.APP_SETTINGS, + aboveActivity: i18n.Messages.ACTIVITY_SETTINGS + }; + return header === names[settingsLocation]; + }, + + patchedSettings: new WeakSet(), + + addSettings(elements: any[], element: { header?: string; settings: string[]; }, sectionTypes: Record) { + if (this.patchedSettings.has(elements) || !this.isRightSpot(element)) return; + + this.patchedSettings.add(elements); + + elements.push(...this.makeSettingsCategories(sectionTypes)); + }, + + makeSettingsCategories(SectionTypes: Record) { + const { headerText, header } = findByProps("headerText", "header", "separator"); + return [ + { + section: SectionTypes.CUSTOM, + label: "Discord Colorways", + className: "vc-settings-header", + element: () =>
+ + Discord Colorways + + + v{(Plugins.plugins.DiscordColorways as any).pluginVersion} + +
+ }, + { + section: "ColorwaysSelector", + label: "Colorways", + element: () => new Promise(() => true), transitionState: 1 }} />, + className: "dc-colorway-selector" + }, + { + section: "ColorwaysSettings", + label: "Settings", + element: SettingsPage, + className: "dc-colorway-settings" + }, + { + section: "ColorwaysSourceManager", + label: "Sources", + element: SourceManager, + className: "dc-colorway-sources-manager" + }, + { + section: "ColorwaysOnDemand", + label: "On-Demand", + element: OnDemandWaysPage, + className: "dc-colorway-ondemand" + }, + { + section: "ColorwaysStore", + label: "Store", + element: Store, + className: "dc-colorway-store" + }, + { + section: SectionTypes.DIVIDER + } + ].filter(Boolean); + }, + + ColorwaysButton: () => , + + async start() { + addServerListElement(ServerListRenderPosition.In, this.ColorwaysButton); + + enableStyle(style); + ColorwayCSS.set((await DataStore.get("activeColorwayObject") as ColorwayObject).css || ""); + + addAccessory("colorways-btn", props => { + if (String(props.message.content).match(/colorway:[0-9a-f]{0,100}/)) { + return + {String(props.message.content).match(/colorway:[0-9a-f]{0,100}/g)?.map((colorID: string) => { + colorID = hexToString(colorID.split("colorway:")[1]); + return
+
+ {(() => { + if (colorID) { + if (!colorID.includes(",")) { + throw new Error("Invalid Colorway ID"); + } else { + return colorID.split("|").filter(string => string.includes(",#"))[0].split(/,#/).map((color: string) =>
); + } + } else return null; + })()} +
+
+ Colorway{/n:([A-Za-z0-9]+( [A-Za-z0-9]+)+)/i.exec(colorID) ? `: ${/n:([A-Za-z0-9]+( [A-Za-z0-9]+)+)/i.exec(colorID)![1]}` : ""} + + + + + +
+
; + })} + ; + } else { + return null; + } + }); + }, + stop() { + removeServerListElement(ServerListRenderPosition.In, this.ColorwaysButton); + disableStyle(style); + ColorwayCSS.remove(); + removeAccessory("colorways-btn"); + }, +}); diff --git a/src/equicordplugins/discordColorways/style.css b/src/equicordplugins/discordColorways/style.css new file mode 100644 index 00000000..b6516b63 --- /dev/null +++ b/src/equicordplugins/discordColorways/style.css @@ -0,0 +1,1379 @@ +/* stylelint-disable no-descending-specificity */ +/* stylelint-disable declaration-block-no-redundant-longhand-properties */ +/* stylelint-disable selector-id-pattern */ +/* stylelint-disable selector-class-pattern */ +@import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css"); + +.ColorwaySelectorBtn { + height: 48px; + width: 48px; + border-radius: 50px; + display: flex; + justify-content: center; + align-items: center; + transition: .15s ease-out; + background-color: var(--background-primary); + cursor: pointer; + color: var(--text-normal); +} + +.ColorwaySelectorBtn:hover { + background-color: var(--brand-500); + border-radius: 16px; +} + +.discordColorway { + width: 56px; + cursor: pointer; + display: flex; + flex-direction: column; + position: relative; + align-items: center; + transition: 170ms ease; +} + +.discordColorway:hover { + filter: brightness(.8); +} + +.discordColorwayPreviewColorContainer { + display: flex; + flex-flow: wrap; + flex-direction: row; + overflow: hidden; + border-radius: 50%; + width: 56px; + height: 56px; + box-shadow: 0 0 0 1.5px var(--interactive-normal); + box-sizing: border-box; +} + +.discordColorwayPreviewColor { + width: 50%; + height: 50%; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(2)))>.discordColorwayPreviewColor { + height: 100%; + width: 100%; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor { + height: 100%; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(4)))>.discordColorwayPreviewColor:nth-child(3) { + width: 100%; +} + +.ColorwaySelectorWrapper { + position: relative; + display: flex; + gap: 16px 28px; + width: 100%; + flex-wrap: wrap; + padding: 2px; + scrollbar-width: none !important; +} + +.ColorwaySelectorWrapper::-webkit-scrollbar { + width: 0; +} + +.colorwaySelectorModal { + width: 100% !important; + min-width: 596px !important; +} + +.colorwaySelectorModalContent { + display: flex; + flex-direction: column; + width: 100%; + max-width: 596px; + overflow: visible !important; + padding: 0 16px !important; +} + +.ColorwaySelectorBtnContainer { + position: relative; + margin: 0 0 8px; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 72px; +} + +.colorwayInfoIconContainer { + height: 22px; + width: 22px; + background-color: var(--brand-500); + position: absolute; + top: -1px; + left: -1px; + border-radius: 50%; + opacity: 0; + z-index: +1; + color: var(--white-500); + padding: 1px; + box-sizing: border-box; +} + +.colorwayInfoIconContainer:hover { + background-color: var(--brand-experiment-560); +} + +.discordColorway:hover .colorwayInfoIconContainer { + opacity: 1; + transition: .15s; +} + +.colorwayCreator-swatch { + display: flex; + align-items: center; + justify-content: center; + height: 50px; + border-radius: 4px; + box-sizing: border-box; + border: none; + width: 100%; + position: relative; + color: #fff; +} + +.colorwayCreator-swatchName { + color: currentcolor; + pointer-events: none; +} + +.colorwayCreator-colorPreviews { + width: 100%; + height: fit-content; + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 8px; + position: relative; + box-sizing: border-box; +} + +.colorwayCreator-colorInput { + width: 1px; + height: 1px; + opacity: 0; + position: absolute; + pointer-events: none; +} + +.colorwayCreator-menuWrapper { + display: flex; + flex-direction: column; + gap: 8px; + padding: 20px 16px !important; + overflow: visible !important; + min-height: unset; +} + +.colorwayCreator-modal { + width: 620px !important; + max-width: 620px; + max-height: unset !important; +} + +.colorways-creator-module-warning { + color: var(--brand-500); +} + +.colorwayCreator-colorPreviews>[class^="colorSwatch"], +.colorwayCreator-colorPreviews>[class^="colorSwatch"]>[class^="swatch"] { + width: 100%; + border: none; + position: relative; +} + +.colorwaysPicker-colorLabel { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; +} + +.colorwayCreator-colorPreviews>.colorSwatch-2UxEuG:has([fill="var(--primary-530)"])>.colorwaysPicker-colorLabel { + color: var(--primary-530); +} + +.colorwaySelector-noDisplay { + display: none; +} + +.colorwayInfo-wrapper { + display: flex; + flex-direction: column; + color: var(--header-primary); +} + +.colorwayInfo-colorSwatches { + width: 100%; + height: 46px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + margin: 12px 0; + gap: 8px; +} + +.colorwayInfo-colorSwatch { + display: flex; + width: 100%; + height: 38px; + border-radius: 3px; + cursor: pointer; + position: relative; + transition: .15s; +} + +.colorwayInfo-colorSwatch:hover { + filter: brightness(.8); +} + +.colorwayInfo-row { + font-weight: 400; + font-size: 20px; + color: var(--header-secondary); + margin-bottom: 4px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + gap: 8px; + border-radius: 4px; + background-color: var(--background-secondary); + padding: 8px 12px; +} + +.colorwayInfo-css { + flex-direction: column; + align-items: start; +} + +.colorwayInfo-cssCodeblock { + border-radius: 4px; + border: 1px solid var(--background-accent); + padding: 3px 6px; + white-space: pre; + max-height: 400px; + overflow: auto; + font-size: 0.875rem; + line-height: 1.125rem; + width: 100%; + box-sizing: border-box; +} + +.colorwayInfo-cssCodeblock::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +.colorwayInfo-cssCodeblock::-webkit-scrollbar-corner { + background-color: transparent; +} + +.colorwayInfo-cssCodeblock::-webkit-scrollbar-thumb { + background-color: var(--scrollbar-auto-thumb); + min-height: 40px; +} + +.colorwayInfo-cssCodeblock::-webkit-scrollbar-thumb, +.colorwayInfo-cssCodeblock::-webkit-scrollbar-track { + border: 2px solid transparent; + background-clip: padding-box; + border-radius: 8px; +} + +.colorwayInfo-cssCodeblock::-webkit-scrollbar-track { + margin-bottom: 8px; +} + +.colorwaysCreator-settingCat { + display: flex; + flex-direction: column; + padding: 10px; + border-radius: 4px; + background-color: var(--background-secondary); + box-sizing: border-box; + color: var(--header-secondary); + max-height: 250px; + overflow: hidden overlay; +} + +.colorwaysColorpicker-settingCat { + padding: 0; + background-color: transparent; + border-radius: 0; +} + +.colorwaysColorpicker-search { + width: 100%; +} + +.colorwaysCreator-settingItm { + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + border-radius: 4px; + cursor: pointer; + box-sizing: border-box; + padding: 8px; + justify-content: space-between; +} + +.colorwaysCreator-settingItm:hover { + background-color: var(--background-modifier-hover); +} + +.colorwaysCreator-settingsList .colorwaysCreator-preset { + justify-content: start; + gap: 8px; +} + +.colorwaysCreator-settingsList { + overflow: auto; + max-height: 185px; +} + +.colorwaysCreator-settingCat-collapsed>:is(.colorwaysCreator-settingsList, .colorwayInfo-cssCodeblock), +.colorwaysColorpicker-collapsed { + display: none !important; +} + +.colorwayColorpicker { + display: flex; + flex-direction: column; + padding: 20px 16px !important; + width: 620px !important; + min-height: unset; +} + +.colorwaysCreator-noHeader { + margin-top: 12px; + margin-bottom: 12px; +} + +.colorwaysCreator-noMinHeight { + min-height: unset; + height: fit-content; +} + +.colorwaysPreview-wrapper { + display: flex; + flex-direction: column; + width: 100%; + height: 270px; + flex: 1 0 auto; + border-radius: 4px; + overflow: hidden; +} + +.colorwaysPreview-modal { + max-width: unset !important; + max-height: unset !important; + width: fit-content; + height: fit-content; +} + +.colorwaysPreview-titlebar { + height: 22px; + width: 100%; + display: flex; + flex: 1 0 auto; +} + +.colorwaysPreview-body { + height: 100%; + width: 100%; + display: flex; +} + +.colorwayPreview-guilds { + width: 72px; + height: 100%; + display: flex; + flex: 1 0 auto; + padding-top: 4px; + flex-direction: column; +} + +.colorwayPreview-channels { + width: 140px; + height: 100%; + display: flex; + flex-direction: column-reverse; + border-top-left-radius: 8px; + flex: 1 0 auto; +} + +.colorwaysPreview-wrapper:fullscreen .colorwayPreview-channels { + width: 240px; +} + +.colorwayPreview-chat { + width: 100%; + height: 100%; + display: flex; + position: relative; + flex-direction: column-reverse; +} + +.colorwayPreview-userArea { + width: 100%; + height: 40px; + display: flex; + flex: 1 0 auto; +} + +.colorwaysPreview-wrapper:fullscreen .colorwayPreview-userArea { + height: 52px; +} + +.colorwaysPreview { + display: flex; + flex-direction: column; + padding: 10px; + gap: 5px; + border-radius: 4px; + background-color: var(--background-secondary); + box-sizing: border-box; + color: var(--header-secondary); + overflow: hidden overlay; + margin-bottom: 4px; +} + +.colorwaysPreview-collapsed .colorwaysPreview-wrapper { + display: none; +} + +.colorwayInfo-lastCat, +.colorwaysCreator-lastCat { + margin-bottom: 12px; +} + +.colorwayPreview-guild { + width: 100%; + margin-bottom: 8px; + display: flex; + justify-content: center; +} + +.colorwayPreview-guildItem { + cursor: pointer; + width: 48px; + height: 48px; + border-radius: 50px; + transition: .2s ease; + display: flex; + justify-content: center; + align-items: center; +} + +.colorwayPreview-guildItem:hover { + border-radius: 16px; +} + +.colorwayPreview-guildSeparator { + width: 32px; + height: 2px; + opacity: .48; + border-radius: 1px; +} + +.colorwayToolbox-listItem { + align-items: center; + border-radius: 4px; + color: var(--interactive-normal); + display: flex; + flex-direction: column; + gap: 12px; + background-color: transparent !important; + width: calc(564px / 4); + cursor: default; + float: left; + box-sizing: border-box; + margin: 0; + padding: 0; +} + +.colorwayToolbox-listItemSVG { + padding: 19px; + overflow: visible; + border-radius: 50%; + background-color: var(--background-tertiary); + border: 1px solid transparent; + display: flex; + justify-content: center; + align-items: center; + transition: .15s ease; + cursor: pointer; + color: var(--interactive-normal); +} + +.colorwayToolbox-listItem:hover { + color: var(--interactive-normal) !important; +} + +.colorwayToolbox-listItemSVG:hover { + border-color: var(--brand-500); + background-color: var(--brand-experiment-15a); + color: var(--interactive-hover) !important; +} + +.colorwayToolbox-title { + align-items: center; + display: flex; + text-transform: uppercase; + margin-top: 2px; + padding-bottom: 8px; + margin-bottom: 0; +} + +.colorwayToolbox-list { + box-sizing: border-box; + height: 100%; + display: flex; + flex-direction: column; + gap: 12px; + overflow: hidden; +} + +.colorwayPreview-chatBox { + height: 32px; + border-radius: 6px; + margin: 8px; + margin-bottom: 12px; + margin-top: 0; + flex: 1 1 auto; +} + +.colorwayPreview-filler { + width: 100%; + height: 100%; + flex: 0 1 auto; +} + +.colorwayPreview-topShadow { + box-shadow: 0 1px 0 hsl(var(--primary-900-hsl)/20%), 0 1.5px 0 hsl(var(--primary-860-hsl)/5%), 0 2px 0 hsl(var(--primary-900-hsl)/5%); + width: 100%; + height: 32px; + font-family: var(--font-display); + font-weight: 500; + padding: 12px 16px; + box-sizing: border-box; + align-items: center; + display: flex; + flex: 1 0 auto; +} + +.colorwayPreview-channels>.colorwayPreview-topShadow { + border-top-left-radius: 8px; +} + +.colorwayPreview-channels>.colorwayPreview-topShadow:hover { + background-color: hsl(var(--primary-500-hsl)/30%); +} + +.colorwaysPreview-wrapper:fullscreen .colorwayPreview-topShadow { + height: 48px; +} + +.colorwaysPreview-wrapper:fullscreen .colorwayPreview-chatBox { + height: 44px; + border-radius: 8px; + margin: 16px; + margin-bottom: 24px; +} + +.colorwaysBtn-tooltipContent { + font-weight: 600; + font-size: 16px; + line-height: 20px; +} + +.colorwaySelector-headerIcon { + box-sizing: border-box; + width: 100%; + height: 100%; + transition: transform .1s ease-out, opacity .1s ease-out; + color: var(--interactive-normal); +} + +.colorwaySelector-header { + align-items: center; + justify-content: center; + padding-bottom: 0; + box-shadow: none !important; +} + +.colorwaySelector-search { + width: 100%; +} + +.colorwaySelector-sources { + flex: 0 0 auto; + margin-right: auto; + color: var(--button-outline-primary-text); + border-color: var(--button-outline-primary-border); +} + +.colorwaySelector-sources:hover { + background-color: var(--button-outline-primary-background-hover); + border-color: var(--button-outline-primary-border-hover); + color: var(--button-outline-primary-text-hover); +} + +.colorwaySelector-headerBtn { + position: absolute; + top: 64px; + right: 20px; +} + +.theme-light .colorwaySelector-pill_selected { + border-color: var(--brand-500) !important; + background-color: var(--brand-experiment-160) !important; +} + +.theme-dark .colorwaySelector-pill_selected { + border-color: var(--brand-500) !important; + background-color: var(--brand-experiment-15a) !important; +} + +.colorwaysTooltip-tooltipPreviewRow { + display: flex; + align-items: center; + margin-top: 8px; +} + +.colorwayCreator-colorPreview { + width: 100%; + border-radius: 4px; + height: 50px; + display: flex; + justify-content: center; + align-items: center; +} + +.colorwaysCreator-colorPreviewItm .colorwayCreator-colorPreviews { + padding: 0; + background-color: transparent; + border-radius: 0; +} + +.colorwaysCreator-colorPreviewItm { + flex-direction: column; + align-items: start; +} + +.colorwaysTooltip-header { + background-color: var(--background-primary); + padding: 2px 8px; + border-radius: 16px; + height: min-content; + color: var(--header-primary); + margin-bottom: 2px; + display: inline-flex; + margin-left: -4px; +} + +.colorwaySelector-pillSeparator { + height: 24px; + width: 1px; + background-color: var(--primary-400); +} + +.colorwaysSelector-changelog { + font-weight: 400; + font-size: 20px; + color: var(--header-secondary); + border-radius: 4px; + background-color: var(--background-secondary); + padding: 8px 12px; +} + +.colorwaysChangelog-li { + position: relative; + font-size: 16px; + line-height: 20px; +} + +.colorwaysChangelog-li::before { + content: ""; + position: absolute; + top: 10px; + left: -15px; + width: 6px; + height: 6px; + margin-top: -4px; + margin-left: -3px; + border-radius: 50%; + opacity: .3; +} + +.theme-dark .colorwaysChangelog-li::before { + background-color: hsl(216deg calc(var(--saturation-factor, 1)*9.8%) 90%); +} + +.theme-light .colorwaysChangelog-li::before { + background-color: hsl(223deg calc(var(--saturation-factor, 1)*5.8%) 52.9%); +} + +.ColorwaySelectorWrapper .colorwayToolbox-list { + width: 100%; +} + +.colorwaysToolbox-label { + border-radius: 20px; + box-sizing: border-box; + color: var(--text-normal); + transition: .15s ease; + width: 100%; + margin-left: 0; + height: fit-content; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: wrap; + cursor: default; + max-height: 2rem; + padding: 0 8px; +} + +.colorwaysSelector-changelogHeader { + font-weight: 700; + font-size: 16px; + line-height: 20px; + text-transform: uppercase; + position: relative; + display: flex; + align-items: center; +} + +.colorwaysSelector-changelogHeader::after { + content: ""; + height: 1px; + flex: 1 1 auto; + margin-left: 4px; + opacity: .6; + background-color: currentcolor; +} + +.colorwaysSelector-changelogHeader_added { + color: var(--text-positive); +} + +.colorwaysSelector-changelogHeader_fixed { + color: hsl(359deg calc(var(--saturation-factor, 1)*87.3%) 59.8%); +} + +.colorwaysSelector-changelogHeader_changed { + color: var(--text-warning); +} + +.is-mobile .colorwaySelectorModal, +.is-mobile .colorwayCreator-modal { + width: 100vw !important; + box-sizing: border-box; + min-width: unset; + border-radius: 0; + height: 100vh; + max-height: unset; + border: none; +} + +.is-mobile .colorwaySelectorModalContent { + box-sizing: border-box; + width: 100vw; +} + +.is-mobile .colorwaySelector-doublePillBar { + flex-direction: column-reverse; + align-items: end; +} + +.is-mobile .colorwaySelector-doublePillBar>.colorwaySelector-pillWrapper:first-child { + width: 100%; + gap: 4px; + overflow-x: auto; + justify-content: space-between; +} + +.is-mobile .colorwaySelector-doublePillBar>.colorwaySelector-pillWrapper:first-child>.colorwaySelector-pill { + border-radius: 0; + border-top: none; + border-left: none; + border-right: none; + background-color: transparent; + width: 100%; + justify-content: center; + flex: 0 0 min-content; +} + +.is-mobile .colorwaySelector-doublePillBar>.colorwaySelector-pillWrapper:first-child>.colorwaySelector-pillSeparator { + display: none; +} + +.is-mobile .layer-fP3xEz:has(.colorwaySelectorModal, .colorwayCreator-modal) { + padding: 0; +} + +.is-mobile .ColorwaySelectorWrapper { + justify-content: space-around; + gap: 10px; +} + +#colorwaySelector-pill_closeSelector { + display: none !important; +} + +.is-mobile #colorwaySelector-pill_closeSelector { + display: flex !important; +} + +.colorwaysBtn-spinner { + display: flex; + justify-content: center; + align-items: center; + width: 100%; +} + +.colorwaysBtn-spinnerInner { + transform: rotate(280deg); + position: relative; + display: inline-block; + width: 32px; + height: 32px; + contain: paint; +} + +@keyframes spinner-spinning-circle-rotate { + 100% { + transform: rotate(1turn); + } +} + +@keyframes spinner-spinning-circle-dash { + 0% { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + } + + 50% { + stroke-dasharray: 130, 200; + } + + 100% { + stroke-dasharray: 130, 200; + stroke-dashoffset: -124; + } +} + +.colorwaysBtn-spinnerCircular { + animation: spinner-spinning-circle-rotate 2s linear infinite; + height: 100%; + width: 100%; +} + +.colorwaysBtn-spinnerBeam { + animation: spinner-spinning-circle-dash 2s ease-in-out infinite; + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + fill: none; + stroke-width: 6; + stroke-miterlimit: 10; + stroke-linecap: round; + stroke: currentcolor; +} + +.colorwaysBtn-spinnerBeam2 { + stroke: currentcolor; + opacity: 0.6; + animation-delay: .15s; +} + +.colorwaysBtn-spinnerBeam3 { + stroke: currentcolor; + opacity: 0.3; + animation-delay: .23s; +} + +.colorwaysSettings-colorwaySource { + display: flex; + flex-direction: row; + justify-content: space-between; + padding: 8px; + gap: 5px; + border-radius: 4px; + box-sizing: border-box; + align-items: center; +} + +.discordColorway-listItem { + display: flex; + flex-direction: row; + justify-content: start; + padding: 0 8px; + gap: 5px; + border-radius: 4px; + box-sizing: border-box; + min-height: 44px; + align-items: center; +} + +.colorwaysSettings-modalRoot { + min-width: 520px; +} + +.colorwaysSettings-colorwaySourceLabel { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex-grow: 1; + line-height: 30px; +} + +.colorwaysSettings-colorwaySourceLabelHeader { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex-grow: 1; + font-weight: 700; + font-size: 16px; +} + +.colorwaysSettings-colorwaySourceDesc { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex-grow: 1; +} + +.colorwaysSettings-iconButton { + background-color: transparent !important; + border-radius: 0; +} + +.colorwaysSettings-iconButtonInner { + display: flex; + gap: 4px; + align-items: center; +} + +.colorwaysSettings-modalContent { + margin: 8px 0; +} + +@keyframes loading-bar { + 0% { + left: 0; + right: 100%; + width: 0; + } + + 10% { + left: 0; + right: 75%; + width: 25%; + } + + 90% { + right: 0; + left: 75%; + width: 25%; + } + + 100% { + left: 100%; + right: 0; + width: 0; + } +} + +.colorwaysLoader-barContainer { + width: 100%; + border-radius: var(--radius-round); + border: 0; + position: relative; + padding: 0; +} + +.colorwaysLoader-bar { + position: absolute; + border-radius: var(--radius-round); + top: 0; + right: 100%; + bottom: 0; + left: 0; + background: var(--brand-500); + width: 0; + animation: loading-bar 2s linear infinite; + transition: .2s ease; +} + +.colorwaysSettingsSelector-wrapper { + display: flex; + flex-direction: column; + gap: 8px; +} + +.colorwaysSettingsPage-wrapper .colorwayToolbox-listItem { + gap: 8px; + border-radius: 50px; + padding: 12px 16px; + background-color: var(--background-tertiary); + transition: .15s ease; + border: 1px solid transparent; + color: var(--interactive-normal); +} + +.colorwaysSettingsPage-wrapper .colorwayToolbox-listItem:hover { + border-color: var(--brand-500); + background-color: var(--brand-experiment-15a); + color: var(--interactive-hover); +} + +.colorwaysSettingsSelector-wrapper .colorwaySelector-doublePillBar { + justify-content: start; +} + +.colorwaysCreator-toolboxItm:hover { + background-color: var(--brand-experiment) !important; +} + +.colorwayCreator-colorPreview_primary+.colorwayCreator-colorPreview_primary, +.colorwayCreator-colorPreview_secondary+.colorwayCreator-colorPreview_secondary, +.colorwayCreator-colorPreview_tertiary+.colorwayCreator-colorPreview_tertiary, +.colorwayCreator-colorPreview_accent+.colorwayCreator-colorPreview_accent { + display: none; +} + +.colorwaysConflictingColors-warning { + width: 100%; + text-align: center; + justify-content: center; +} + +.ColorwaySelectorBtn_thin { + height: 21px !important; + width: 56px !important; +} + +.ColorwaySelectorBtn_thin:hover { + border-radius: 8px; +} + +.colorwaySelector-searchPopout { + display: none !important; +} + +.colorways-badge { + font-size: .625rem; + text-transform: uppercase; + vertical-align: top; + display: inline-flex; + align-items: center; + text-indent: 0; + background: var(--brand-experiment); + color: var(--white-500); + flex: 0 0 auto; + height: 15px; + padding: 0 4px; + margin-top: 7.5px; + border-radius: 4px; +} + +.hoverRoll { + display: inline-block; + vertical-align: top; + cursor: default; + text-align: left; + box-sizing: border-box; + position: relative; + width: 100%; + contain: paint; +} + +.hoverRoll_hovered { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + display: block; + transition: all.22s ease; + transform-style: preserve-3d; + pointer-events: none; + width: 100%; + opacity: 0; + transform: translate3d(0, 107%, 0); + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +.hoverRoll:hover .hoverRoll_hovered, +.colorwaysSettings-colorwaySource:hover .hoverRoll_hovered { + transform: translateZ(0); + opacity: 1; +} + +.hoverRoll_normal { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + display: block; + transition: all .22s ease; + transform-style: preserve-3d; + pointer-events: none; + width: 100%; +} + +.hoverRoll:hover .hoverRoll_normal, +.colorwaysSettings-colorwaySource:hover .hoverRoll_normal { + transform: translate3d(0,-107%,0); + opacity: 0; + user-select: none; +} + +.dc-warning-card { + padding: 1em; + margin-bottom: 1em; + background-color: var(--info-warning-background); + border-color: var(--info-warning-foreground); + color: var(--info-warning-text); +} + +/* stylelint-disable-next-line no-duplicate-selectors */ +.colorwaysPreview-modal { + width: 90vw !important; + height: 90vh !important; + max-height: unset !important; +} + +.colorwaysPresetPicker-content { + padding: 16px; +} + +.colorwaysPresetPicker { + width: 600px; +} + +.colorwaysCreator-setting { + display: flex; + flex-direction: row; + justify-content: space-between; + border-radius: 4px; + background-color: var(--background-secondary); + box-sizing: border-box; + color: var(--header-secondary); + padding: 10px 18px; + padding-right: 10px; + cursor: pointer; + align-items: center; +} + +.colorwaysCreator-setting:hover { + background-color: var(--background-modifier-hover); +} + +.dc-colorway-selector::before { + /* stylelint-disable-next-line property-no-vendor-prefix */ + -webkit-mask: var(--si-appearance) center/contain no-repeat !important; + mask: var(--si-appearance) center/contain no-repeat !important +} + +.dc-colorway-settings::before { + /* stylelint-disable-next-line property-no-vendor-prefix */ + -webkit-mask: var(--si-vencordsettings) center/contain no-repeat !important; + mask: var(--si-vencordsettings) center/contain no-repeat !important +} + +.dc-colorway-ondemand::before { + /* stylelint-disable-next-line property-no-vendor-prefix */ + -webkit-mask: var(--si-vencordupdater) center/contain no-repeat !important; + mask: var(--si-vencordupdater) center/contain no-repeat !important +} + +.dc-colorway-sources-manager::before { + /* stylelint-disable-next-line property-no-vendor-prefix */ + -webkit-mask: var(--si-instantinvites) center/contain no-repeat !important; + mask: var(--si-instantinvites) center/contain no-repeat !important +} + +.colorwaySourceModal { + min-height: unset; +} + +.colorwaySelector-sourceSelect { + width: fit-content !important; +} + +.dc-info-card { + border-radius: 5px; + border: 1px solid var(--blue-345); + padding: 1em; + margin-bottom: 1em; + display: flex; + gap: 1em; + flex-direction: column; +} + +.theme-dark .dc-info-card { + color: var(--white-500); +} + +.theme-light .dc-info-card { + color: var(--black-500); +} + +.colorwaysSettings-sourceScroller { + scrollbar-width: none; +} + +.colorwaysSettings-sourceScroller::-webkit-scrollbar { + width: 0; +} + +.colorwayMessage { + padding: 20px; + border: 1px solid; + border-radius: 5px; + display: flex; +} + +.colorwayMessage-contents { + display: flex; + flex-direction: column; +} + +.theme-dark .colorwayMessage { + background: hsl(var(--primary-630-hsl)/60%); + border-color: hsl(var(--primary-630-hsl)/90%); +} + +.theme-light .colorwayMessage { + background: hsl(var(--primary-100-hsl)/60%); + border-color: hsl(var(--primary-200-hsl)/30%); +} + +.colorwaySelector-sources_settings { + margin-left: 8px; +} + +.colorwaysLoadingModal, +.colorwayInfo-cssModal { + width: fit-content; + height: fit-content; + min-width: unset; + min-height: unset; + background: none; + box-shadow: none !important; + border: none; +} + +.ColorwaySelectorWrapper-list { + display: flex; + flex-direction: column; + gap: 0; + flex-wrap: nowrap; + padding-bottom: 0; +} + +.discordColorway-listItem .discordColorwayPreviewColorContainer { + width: 30px; + height: 30px; +} + +.colorwayLabel.labelInGrid { + max-height: 2rem; + overflow: hidden; + text-overflow: ellipsis; + margin-top: 4px; + text-align: center; +} + +.discordColorway-listItem .colorwayInfoIconContainer { + height: 28px; + width: 28px; + border-radius: 3px; + position: static; + opacity: 1; + justify-content: center; + display: flex; + align-items: center; + background: transparent; + border: 1px solid var(--button-outline-primary-border); + color: var(--button-outline-primary-text); + transition: .15s; +} + +.discordColorway-listItem .colorwayInfoIconContainer:hover { + background-color: var(--button-outline-primary-background-hover); + border-color: var(--button-outline-primary-border-hover); + color: var(--button-outline-primary-text-hover); +} + +.colorwayLabel:not(.labelInGrid) { + margin-right: auto; + margin-top: 0 !important; + margin-left: .5rem; +} + +.colorwaySelectionCircle { + position: absolute; + width: 56px; + height: 56px; + top: 0; + left: 0; +} + +.ColorwaySelectorWrapper-grid { + margin-bottom: 16px; +} + +.colorwaySelector-sorter { + height: 50px; + width: 100%; + box-shadow: var(--elevation-low); + margin-bottom: 8px; + display: flex; +} + +.colorwaySelector-sorter_selectedSpacer { + width: 80px; + height: 50px; +} + +.colorwaySelector-sorter_text { + line-height: 50px; + margin: 0; +} + +.colorwaySelector-sorter_name { + margin-right: auto; + cursor: pointer; +} + +.colorwayPresetLabel { + margin-right: 1rem; +} + +.colorwayPreview-channel { + margin: 10px; + width: calc(100% - 20px); + height: 8px; + border-radius: 16px; +} diff --git a/src/equicordplugins/discordColorways/types.ts b/src/equicordplugins/discordColorways/types.ts new file mode 100644 index 00000000..dbc09aa4 --- /dev/null +++ b/src/equicordplugins/discordColorways/types.ts @@ -0,0 +1,65 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export interface Colorway { + [key: string]: any, + name: string, + "dc-import": string, + accent: string, + primary: string, + secondary: string, + tertiary: string, + original?: boolean, + author: string, + authorID: string, + colors?: string[], + isGradient?: boolean, + sourceType?: "online" | "offline" | "temporary" | null, + source?: string, + linearGradient?: string, + preset?: string, + creatorVersion: string; +} + +export interface ColorPickerProps { + color: number; + showEyeDropper: boolean; + suggestedColors: string[]; + label: any; + onChange(color: number): void; +} + +export interface ColorwayObject { + id: string | null, + css: string | null, + sourceType: "online" | "offline" | "temporary" | null, + source: string | null | undefined; +} + +export interface SourceObject { + type: "online" | "offline" | "temporary", + source: string, + colorways: Colorway[]; +} + +export enum SortOptions { + NAME_AZ = 1, + NAME_ZA = 2, + SOURCE_AZ = 3, + SOURCE_ZA = 4 +} + +export interface StoreObject { + sources: StoreItem[]; +} + +export interface StoreItem { + name: string, + id: string, + description: string, + url: string, + authorGh: string; +} diff --git a/src/equicordplugins/discordColorways/utils.ts b/src/equicordplugins/discordColorways/utils.ts new file mode 100644 index 00000000..62e3859e --- /dev/null +++ b/src/equicordplugins/discordColorways/utils.ts @@ -0,0 +1,150 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export function HexToHSL(H: string) { + let r: any = 0, g: any = 0, b: any = 0; + if (H.length === 4) r = "0x" + H[1] + H[1], g = "0x" + H[2] + H[2], b = "0x" + H[3] + H[3]; + else if (H.length === 7) { + r = "0x" + H[1] + H[2]; + g = "0x" + H[3] + H[4]; + b = "0x" + H[5] + H[6]; + } + r /= 255, g /= 255, b /= 255; + var cmin = Math.min(r, g, b), + cmax = Math.max(r, g, b), + delta = cmax - cmin, + h = 0, + s = 0, + l = 0; + if (delta === 0) h = 0; + else if (cmax === r) h = ((g - b) / delta) % 6; + else if (cmax === g) h = (b - r) / delta + 2; + else h = (r - g) / delta + 4; + h = Math.round(h * 60); + if (h < 0) h += 360; + l = (cmax + cmin) / 2; + s = delta === 0 + ? 0 + : delta / (1 - Math.abs(2 * l - 1)); + s = +(s * 100).toFixed(1); + l = +(l * 100).toFixed(1); + + return [Math.round(h), Math.round(s), Math.round(l)]; +} + +export const canonicalizeHex = (hex: string) => { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d")!; + + ctx.fillStyle = hex; + hex = ctx.fillStyle; + canvas.remove(); + + return hex; +}; + +export const stringToHex = (str: string) => { + let hex = ""; + for ( + let i = 0; + i < str.length; + i++ + ) { + const charCode = str.charCodeAt(i); + const hexValue = charCode.toString(16); + hex += hexValue.padStart(2, "0"); + } + return hex; +}; + +export const hexToString = (hex: string) => { + let str = ""; + for (let i = 0; i < hex.length; i += 2) { + const hexValue = hex.substr(i, 2); + const decimalValue = parseInt(hexValue, 16); + str += String.fromCharCode(decimalValue); + } + return str; +}; + +export function getHex(str: string): string { + const color = Object.assign( + document.createElement("canvas").getContext("2d") as {}, + { fillStyle: str } + ).fillStyle; + if (color.includes("rgba(")) { + return getHex(String([...color.split(",").slice(0, 3), ")"]).replace(",)", ")").replace("a", "")); + } else { + return color; + } +} + +export function getFontOnBg(bgColor: string) { + var color = (bgColor.charAt(0) === "#") ? bgColor.substring(1, 7) : bgColor; + var r = parseInt(color.substring(0, 2), 16); + var g = parseInt(color.substring(2, 4), 16); + var b = parseInt(color.substring(4, 6), 16); + return (((r * 0.299) + (g * 0.587) + (b * 0.114)) > 186) ? + "#000000" : "#ffffff"; +} + +export function $e(funcArray: Array<(...vars: any) => void>, ...vars: any[]) { + funcArray.forEach(e => e(vars)); +} + +export function hslToHex(h: number, s: number, l: number) { + h /= 360; + s /= 100; + l /= 100; + let r: any, g: any, b: any; + if (s === 0) { + r = g = b = l; // achromatic + } else { + const hue2rgb = (p: number, q: number, t: number) => { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + }; + const q = l < 0.5 ? l * (1 + s) : l + s - l * s; + const p = 2 * l - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + const toHex = (x: number) => { + const hex = Math.round(x * 255).toString(16); + return hex.length === 1 ? "0" + hex : hex; + }; + return `#${toHex(r)}${toHex(g)}${toHex(b)}`; +} + +export function rgbToHex(r: number, g: number, b: number) { + const toHex = (x: number) => { + const hex = Math.round(x * 255).toString(16); + return hex.length === 1 ? "0" + hex : hex; + }; + return `#${toHex(r)}${toHex(g)}${toHex(b)}`; +} + +export function colorToHex(color: string) { + var colorType = "hex"; + if (color.includes("hsl")) { + colorType = "hsl"; + } else if (color.includes("rgb")) { + colorType = "rgb"; + } + color = color.replaceAll(",", "").replace(/.+?\(/, "").replace(")", "").replaceAll(/[ \t]+\/[ \t]+/g, " ").replaceAll("%", "").replaceAll("/", ""); + if (colorType === "hsl") { + color = hslToHex(Number(color.split(" ")[0]), Number(color.split(" ")[1]), Number(color.split(" ")[2])); + } + if (colorType === "rgb") { + color = rgbToHex(Number(color.split(" ")[0]), Number(color.split(" ")[1]), Number(color.split(" ")[2])); + } + return color.replace("#", ""); +}