From 523dae7fa6a59ec501042b456678afb1a9d9c66b Mon Sep 17 00:00:00 2001 From: SeaswimmerTheFsh Date: Tue, 23 Apr 2024 11:08:56 -0400 Subject: [PATCH] added QuickReactFrequents and DiscordColorways --- .../components/ColorPicker.tsx | 220 +++ .../components/ColorwaysButton.tsx | 108 ++ .../components/ConflictingColorsModal.tsx | 318 +++++ .../components/CreatorModal.tsx | 413 ++++++ .../DiscordColorways/components/Divider.tsx | 15 + .../DiscordColorways/components/Icons.tsx | 62 + .../DiscordColorways/components/InfoModal.tsx | 275 ++++ .../components/SelectorModal.tsx | 460 +++++++ .../SettingsTabs/ManageColorwaysPage.tsx | 129 ++ .../components/SettingsTabs/OnDemandPage.tsx | 68 + .../components/SettingsTabs/SelectorPage.tsx | 442 ++++++ .../components/SettingsTabs/SettingsPage.tsx | 303 ++++ .../DiscordColorways/components/Spinner.tsx | 17 + .../components/ThemePreview.tsx | 222 +++ src/userplugins/DiscordColorways/constants.ts | 317 +++++ src/userplugins/DiscordColorways/css.ts | 767 +++++++++++ src/userplugins/DiscordColorways/index.tsx | 225 +++ src/userplugins/DiscordColorways/style.css | 1214 +++++++++++++++++ src/userplugins/DiscordColorways/types.ts | 29 + src/userplugins/DiscordColorways/utils.ts | 133 ++ src/userplugins/QuickReactFrequents/index.ts | 22 + 21 files changed, 5759 insertions(+) create mode 100644 src/userplugins/DiscordColorways/components/ColorPicker.tsx create mode 100644 src/userplugins/DiscordColorways/components/ColorwaysButton.tsx create mode 100644 src/userplugins/DiscordColorways/components/ConflictingColorsModal.tsx create mode 100644 src/userplugins/DiscordColorways/components/CreatorModal.tsx create mode 100644 src/userplugins/DiscordColorways/components/Divider.tsx create mode 100644 src/userplugins/DiscordColorways/components/Icons.tsx create mode 100644 src/userplugins/DiscordColorways/components/InfoModal.tsx create mode 100644 src/userplugins/DiscordColorways/components/SelectorModal.tsx create mode 100644 src/userplugins/DiscordColorways/components/SettingsTabs/ManageColorwaysPage.tsx create mode 100644 src/userplugins/DiscordColorways/components/SettingsTabs/OnDemandPage.tsx create mode 100644 src/userplugins/DiscordColorways/components/SettingsTabs/SelectorPage.tsx create mode 100644 src/userplugins/DiscordColorways/components/SettingsTabs/SettingsPage.tsx create mode 100644 src/userplugins/DiscordColorways/components/Spinner.tsx create mode 100644 src/userplugins/DiscordColorways/components/ThemePreview.tsx create mode 100644 src/userplugins/DiscordColorways/constants.ts create mode 100644 src/userplugins/DiscordColorways/css.ts create mode 100644 src/userplugins/DiscordColorways/index.tsx create mode 100644 src/userplugins/DiscordColorways/style.css create mode 100644 src/userplugins/DiscordColorways/types.ts create mode 100644 src/userplugins/DiscordColorways/utils.ts create mode 100644 src/userplugins/QuickReactFrequents/index.ts diff --git a/src/userplugins/DiscordColorways/components/ColorPicker.tsx b/src/userplugins/DiscordColorways/components/ColorPicker.tsx new file mode 100644 index 00000000..195eecb9 --- /dev/null +++ b/src/userplugins/DiscordColorways/components/ColorPicker.tsx @@ -0,0 +1,220 @@ +/* + * 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 { colorVariables } from "../css"; + +interface ToolboxItem { + title: string; + onClick: () => void; + id?: string; + iconClassName?: string; +} + +const ColorVarItems: ToolboxItem[] = colorVariables.map((colorVariable: string) => { + return { + title: "Copy " + colorVariable, + onClick: () => { + function getHex(str: string): string { return Object.assign(document.createElement("canvas").getContext("2d") as {}, { fillStyle: str }).fillStyle; } + Clipboard.copy(getHex(getComputedStyle(document.body).getPropertyValue("--" + colorVariable))); + Toasts.show({ message: "Color " + colorVariable + " copied to clipboard", id: "toolbox-color-var-copied", type: 1 }); + }, + id: colorVariable + }; +}); + +const ToolboxItems: ToolboxItem[] = [ + { + title: "Copy Accent Color", + onClick: () => { + function getHex(str: string): string { + return Object.assign( + document.createElement("canvas").getContext("2d") as {}, + { fillStyle: str } + ).fillStyle; + } + Clipboard.copy( + getHex( + getComputedStyle(document.body).getPropertyValue( + "--brand-experiment" + ) + ) + ); + Toasts.show({ + message: "Accent color copied to clipboard", + id: "toolbox-accent-color-copied", + type: 1, + }); + }, + id: "colorways-toolbox_copy-accent", + iconClassName: "copy", + }, + { + title: "Copy Primary Color", + onClick: () => { + function getHex(str: string): string { + return Object.assign( + document.createElement("canvas").getContext("2d") as {}, + { fillStyle: str } + ).fillStyle; + } + Clipboard.copy( + getHex( + getComputedStyle(document.body).getPropertyValue( + "--background-primary" + ) + ) + ); + Toasts.show({ + message: "Primary color copied to clipboard", + id: "toolbox-primary-color-copied", + type: 1, + }); + }, + id: "colorways-toolbox_copy-primary", + iconClassName: "copy", + }, + { + title: "Copy Secondary Color", + onClick: () => { + function getHex(str: string): string { + return Object.assign( + document.createElement("canvas").getContext("2d") as {}, + { fillStyle: str } + ).fillStyle; + } + Clipboard.copy( + getHex( + getComputedStyle(document.body).getPropertyValue( + "--background-secondary" + ) + ) + ); + Toasts.show({ + message: "Secondary color copied to clipboard", + id: "toolbox-secondary-color-copied", + type: 1, + }); + }, + id: "colorways-toolbox_copy-secondary", + iconClassName: "copy", + }, + { + title: "Copy Tertiary Color", + onClick: () => { + function getHex(str: string): string { + return Object.assign( + document.createElement("canvas").getContext("2d") as {}, + { fillStyle: str } + ).fillStyle; + } + Clipboard.copy( + getHex( + getComputedStyle(document.body).getPropertyValue( + "--background-tertiary" + ) + ) + ); + Toasts.show({ + message: "Tertiary color copied to clipboard", + id: "toolbox-tertiary-color-copied", + type: 1, + }); + }, + id: "colorways-toolbox_copy-tertiary", + iconClassName: "copy", + } +]; + +export default function ({ modalProps }: { modalProps: ModalProps; }) { + const [colorVarItems, setColorVarItems] = useState(ColorVarItems); + const [collapsedSettings, setCollapsedSettings] = useState(true); + let results: ToolboxItem[]; + function searchToolboxItems(e: string) { + results = []; + ColorVarItems.find((ToolboxItem: ToolboxItem) => { + if (ToolboxItem.title.toLowerCase().includes(e.toLowerCase())) { + results.push(ToolboxItem); + } + }); + setColorVarItems(results); + } + + return ( + + + { + searchToolboxItems(e); + if (e) { + setCollapsedSettings(false); + } else { + setCollapsedSettings(true); + } + }} + /> + + + + {colorVarItems.map((toolboxItem: ToolboxItem) => { + return ( +
+ {toolboxItem.title} +
+ ); + })} +
+ + {ToolboxItems.map((toolboxItem: ToolboxItem, i: number) =>
+ + {toolboxItem.title} +
+ )} +
+
+ ); +} diff --git a/src/userplugins/DiscordColorways/components/ColorwaysButton.tsx b/src/userplugins/DiscordColorways/components/ColorwaysButton.tsx new file mode 100644 index 00000000..dcb9109e --- /dev/null +++ b/src/userplugins/DiscordColorways/components/ColorwaysButton.tsx @@ -0,0 +1,108 @@ +/* + * 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, useCallback, useEffect, useState } from "@webpack/common"; +import { FluxEvents } from "@webpack/types"; + +import { PalleteIcon } from "./Icons"; +import SelectorModal from "./SelectorModal"; + +export default function ({ + listItemClass = "ColorwaySelectorBtnContainer", + listItemWrapperClass = "", + listItemTooltipClass = "colorwaysBtn-tooltipContent" +}: { + listItemClass?: string; + listItemWrapperClass?: string; + listItemTooltipClass?: string; +}) { + const [activeColorway, setActiveColorway] = useState("None"); + const [visibility, setVisibility] = useState(true); + const [isThin, setIsThin] = useState(false); + async function setButtonVisibility() { + const [showColorwaysButton, useThinMenuButton] = await DataStore.getMany([ + "showColorwaysButton", + "useThinMenuButton" + ]); + + setVisibility(showColorwaysButton); + setIsThin(useThinMenuButton); + } + + const cached_setButtonVisibility = useCallback(setButtonVisibility, []); + + useEffect(() => { + cached_setButtonVisibility(); + }); + + FluxDispatcher.subscribe("COLORWAYS_UPDATE_BUTTON_HEIGHT" as FluxEvents, ({ isTall }) => { + setIsThin(isTall); + }); + + FluxDispatcher.subscribe("COLORWAYS_UPDATE_BUTTON_VISIBILITY" as FluxEvents, ({ isVisible }) => { + setVisibility(isVisible); + }); + + if (!isThin) { + return ( + Colorways + {"Active Colorway: " + activeColorway} + } position="right" tooltipContentClassName={listItemTooltipClass} + > + {({ onMouseEnter, onMouseLeave, onClick }) => { + return ( + <> + {visibility &&
+
{ + onMouseEnter(); + setActiveColorway(await DataStore.get("actveColorwayID") || "None"); + }} + onMouseLeave={onMouseLeave} + onClick={() => { + onClick(); + openModal(props => ); + }} + >
+
} + + ); + }} +
+ ); + } else { + return ( + Colorways + {"Active Colorway: " + activeColorway} + } position="right" tooltipContentClassName={listItemTooltipClass} + > + {({ onMouseEnter, onMouseLeave, onClick }) => { + return ( + <> + {visibility &&
+
{ + onMouseEnter(); + setActiveColorway(await DataStore.get("actveColorwayID") || "None"); + }} + onMouseLeave={onMouseLeave} + onClick={() => { + onClick(); + openModal(props => ); + }} + >Colorways
+
} + + ); + }} +
+ ); + } +} diff --git a/src/userplugins/DiscordColorways/components/ConflictingColorsModal.tsx b/src/userplugins/DiscordColorways/components/ConflictingColorsModal.tsx new file mode 100644 index 00000000..410f9aee --- /dev/null +++ b/src/userplugins/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/userplugins/DiscordColorways/components/CreatorModal.tsx b/src/userplugins/DiscordColorways/components/CreatorModal.tsx new file mode 100644 index 00000000..b63e2655 --- /dev/null +++ b/src/userplugins/DiscordColorways/components/CreatorModal.tsx @@ -0,0 +1,413 @@ +/* + * 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 { + ModalContent, + ModalFooter, + ModalHeader, + ModalProps, + ModalRoot, + openModal, +} from "@utils/modal"; +import { + Button, + Forms, + ScrollerThin, + Switch, + Text, + TextInput, + useEffect, + UserStore, + useState, +} from "@webpack/common"; + +import { ColorPicker } from ".."; +import { knownThemeVars } from "../constants"; +import { generateCss, getPreset } from "../css"; +import { Colorway } from "../types"; +import { getHex, hexToString, hslToHex, rgbToHex } from "../utils"; +import ConflictingColorsModal from "./ConflictingColorsModal"; +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 [collapsedSettings, setCollapsedSettings] = useState(true); + const [collapsedPresets, setCollapsedPresets] = useState(true); + const [preset, setPreset] = useState("default"); + const [presetColorArray, setPresetColorArray] = useState(["accent", "primary", "secondary", "tertiary"]); + + useEffect(() => { + const parsedID = colorwayID?.split("colorway:")[1]; + if (parsedID) { + const allEqual = (arr: any[]) => arr.every(v => v === arr[0]); + if (!parsedID) { + throw new Error("Please enter a Colorway ID"); + } else if (parsedID.length < 62) { + throw new Error("Invalid Colorway ID"); + } else if (!hexToString(parsedID).includes(",")) { + throw new Error("Invalid Colorway ID"); + } else if (!allEqual(hexToString(parsedID).split(",").map((e: string) => e.match("#")!.length)) && hexToString(parsedID).split(",").map((e: string) => e.match("#")!.length)[0] !== 1) { + throw new Error("Invalid Colorway ID"); + } else { + const colorArray: string[] = hexToString(parsedID).split(","); + setAccentColor(colorArray[0].split("#")[1]); + setPrimaryColor(colorArray[1].split("#")[1]); + setSecondaryColor(colorArray[2].split("#")[1]); + setTertiaryColor(colorArray[3].split("#")[1]); + } + } + }); + const colorPickerProps = { + suggestedColors: [ + "#313338", + "#2b2d31", + "#1e1f22", + "#5865f2", + ], + showEyeDropper: true + }; + + return ( + + + + Create Colorway + + + + + Name: + + + + Colors: + +
+ {presetColorArray.includes("primary") && + Primary} + color={parseInt(primaryColor, 16)} + onChange={(color: number) => { + let hexColor = color.toString(16); + while (hexColor.length < 6) { + hexColor = "0" + hexColor; + } + setPrimaryColor(hexColor); + }} + {...colorPickerProps} + />} + {presetColorArray.includes("secondary") && + Secondary} + color={parseInt(secondaryColor, 16)} + onChange={(color: number) => { + let hexColor = color.toString(16); + while (hexColor.length < 6) { + hexColor = "0" + hexColor; + } + setSecondaryColor(hexColor); + }} + {...colorPickerProps} + />} + {presetColorArray.includes("tertiary") && + Tertiary} + color={parseInt(tertiaryColor, 16)} + onChange={(color: number) => { + let hexColor = color.toString(16); + while (hexColor.length < 6) { + hexColor = "0" + hexColor; + } + setTertiaryColor(hexColor); + }} + {...colorPickerProps} + />} + {presetColorArray.includes("accent") && + Accent} + color={parseInt(accentColor, 16)} + onChange={(color: number) => { + let hexColor = color.toString(16); + while (hexColor.length < 6) { + hexColor = "0" + hexColor; + } + setAccentColor(hexColor); + }} + {...colorPickerProps} + />} +
+
+
setCollapsedSettings(!collapsedSettings)}> + Settings + +
+ +
setTintedText(!tintedText)}> + Use colored text + +
+
setDiscordSaturation(!discordSaturation)}> + Use Discord's saturation + +
+
+
+
+
setCollapsedPresets(!collapsedPresets)}> + Presets + +
+ +
{ + setPreset("default"); + setPresetColorArray(["primary", "secondary", "tertiary", "accent"]); + }}> + + Default +
+ {Object.values(getPreset()).map(pre => { + return
{ + setPreset(pre.id); + setPresetColorArray(pre.colors); + }}> + + {pre.name} +
; + })} +
+
+ +
+ + + + + + +
+ ); + }); + }} + > + Enter Colorway ID + + + + + ); +} diff --git a/src/userplugins/DiscordColorways/components/Divider.tsx b/src/userplugins/DiscordColorways/components/Divider.tsx new file mode 100644 index 00000000..ec27d0ac --- /dev/null +++ b/src/userplugins/DiscordColorways/components/Divider.tsx @@ -0,0 +1,15 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export default () => { + return
; +}; diff --git a/src/userplugins/DiscordColorways/components/Icons.tsx b/src/userplugins/DiscordColorways/components/Icons.tsx new file mode 100644 index 00000000..2545c000 --- /dev/null +++ b/src/userplugins/DiscordColorways/components/Icons.tsx @@ -0,0 +1,62 @@ +/* + * 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 ( + + + + ); +} diff --git a/src/userplugins/DiscordColorways/components/InfoModal.tsx b/src/userplugins/DiscordColorways/components/InfoModal.tsx new file mode 100644 index 00000000..24d7bdd1 --- /dev/null +++ b/src/userplugins/DiscordColorways/components/InfoModal.tsx @@ -0,0 +1,275 @@ +/* + * 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 { openUserProfile } from "@utils/discord"; +import { + ModalContent, + ModalFooter, + ModalHeader, + ModalProps, + ModalRoot, +} from "@utils/modal"; +import { Button, Clipboard, Forms, Text, Toasts } from "@webpack/common"; + +import { ColorwayCSS } from ".."; +import { generateCss } from "../css"; +import { Colorway } from "../types"; +import ThemePreviewCategory from "./ThemePreview"; + +export default function ({ + modalProps, + colorwayProps, + discrimProps = false, + loadUIProps +}: { + modalProps: ModalProps; + colorwayProps: Colorway; + discrimProps?: boolean; + loadUIProps: () => Promise; +}) { + const colors: string[] = colorwayProps.colors || [ + "accent", + "primary", + "secondary", + "tertiary", + ]; + return ( + + + + Colorway Details: {colorwayProps.name} + + + +
+
+ {colors.map(color => { + return ( +
{ + Clipboard.copy(colorwayProps[color]); + Toasts.show({ + message: + "Copied color successfully", + type: 1, + id: "copy-colorway-color-notify", + }); + }} + >
+ ); + })} +
+
+ + Author: + + +
+
+ + CSS: + + + {colorwayProps["dc-import"]} + +
+ +
+
+ + {discrimProps && } + + + {discrimProps ? : } + + +
+ ); +} diff --git a/src/userplugins/DiscordColorways/components/SelectorModal.tsx b/src/userplugins/DiscordColorways/components/SelectorModal.tsx new file mode 100644 index 00000000..e20b0da4 --- /dev/null +++ b/src/userplugins/DiscordColorways/components/SelectorModal.tsx @@ -0,0 +1,460 @@ +/* + * 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 { ModalContent, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal"; +import { + Button, + Forms, + Menu, + Popout, + ScrollerThin, + Select, + SettingsRouter, + TextInput, + Tooltip, + useCallback, + useEffect, + useState, +} from "@webpack/common"; + +import { ColorwayCSS } from ".."; +import { defaultColorwaySource, fallbackColorways } from "../constants"; +import { generateCss } from "../css"; +import { Colorway } from "../types"; +import { getHex } from "../utils"; +import ColorPickerModal from "./ColorPicker"; +import CreatorModal from "./CreatorModal"; +import { CloseIcon } from "./Icons"; +import ColorwayInfoModal from "./InfoModal"; + +export default function ({ + modalProps, +}: { + modalProps: ModalProps; +}): JSX.Element | any { + const [currentColorway, setCurrentColorway] = useState(""); + const [colorways, setColorways] = useState([]); + const [thirdPartyColorways, setThirdPartyColorways] = useState([]); + const [customColorways, setCustomColorways] = useState([]); + const [searchString, setSearchString] = useState(""); + const [loaderHeight, setLoaderHeight] = useState("2px"); + const [visibility, setVisibility] = useState("all"); + const [showReloadMenu, setShowReloadMenu] = useState(false); + let visibleColorwayArray: Colorway[]; + + switch (visibility) { + case "all": + visibleColorwayArray = [...colorways, ...thirdPartyColorways, ...customColorways]; + break; + case "official": + visibleColorwayArray = [...colorways]; + break; + case "3rdparty": + visibleColorwayArray = [...thirdPartyColorways]; + break; + case "custom": + visibleColorwayArray = [...customColorways]; + break; + default: + visibleColorwayArray = [...colorways, ...thirdPartyColorways, ...customColorways]; + break; + } + + async function loadUI() { + const colorwaySourceFiles = await DataStore.get( + "colorwaySourceFiles" + ); + const responses: Response[] = await Promise.all( + colorwaySourceFiles.map((url: string) => + fetch(url) + ) + ); + const data = await Promise.all( + responses.map((res: Response) => + res.json().then(dt => { return { colorways: dt.colorways, url: res.url }; }).catch(() => { return { colorways: [], url: res.url }; }) + )); + const colorways = data.flatMap((json) => json.url === defaultColorwaySource ? json.colorways : []); + const thirdPartyColorwaysArr = data.flatMap((json) => json.url !== defaultColorwaySource ? json.colorways : []); + const baseData = await DataStore.getMany([ + "customColorways", + "actveColorwayID", + ]); + setColorways(colorways || fallbackColorways); + setThirdPartyColorways(thirdPartyColorwaysArr); + setCustomColorways(baseData[0]); + setCurrentColorway(baseData[1]); + } + + const cached_loadUI = useCallback(loadUI, [setColorways, setCustomColorways, setCurrentColorway]); + + async function searchColorways(e: string) { + if (!e) { + cached_loadUI(); + return; + } + const colorwaySourceFiles = await DataStore.get("colorwaySourceFiles"); + const data = await Promise.all( + colorwaySourceFiles.map((url: string) => + fetch(url).then((res) => res.json().then(dt => { return { colorways: dt.colorways, url: res.url }; }).catch(() => { return { colorways: [], url: res.url }; })) + ) + ); + const colorways = data.flatMap((json) => json.url === defaultColorwaySource ? json.colorways : []); + const thirdPartyColorwaysArr = data.flatMap((json) => json.url !== defaultColorwaySource ? json.colorways : []); + const baseData = await DataStore.get("customColorways"); + var results: Colorway[] = []; + (colorways || fallbackColorways).find((Colorway: Colorway) => { + if (Colorway.name.toLowerCase().includes(e.toLowerCase())) + results.push(Colorway); + }); + var thirdPartyResults: Colorway[] = []; + (thirdPartyColorwaysArr).find((Colorway: Colorway) => { + if (Colorway.name.toLowerCase().includes(e.toLowerCase())) + thirdPartyResults.push(Colorway); + }); + var customResults: Colorway[] = []; + baseData.find((Colorway: Colorway) => { + if (Colorway.name.toLowerCase().includes(e.toLowerCase())) + customResults.push(Colorway); + }); + setColorways(results); + setThirdPartyColorways(thirdPartyResults); + setCustomColorways(customResults); + } + + useEffect(() => { + if (!searchString) { + cached_loadUI(); + } + setLoaderHeight("0px"); + }, [searchString]); + + function ReloadPopout(onClose: () => void) { + return ( + + { + setLoaderHeight("2px"); + const colorwaySourceFiles = await DataStore.get( + "colorwaySourceFiles" + ); + const responses: Response[] = await Promise.all( + colorwaySourceFiles.map((url: string) => + fetch(url, { cache: "no-store" }) + ) + ); + const data = await Promise.all( + responses.map((res: Response) => { + setLoaderHeight("0px"); + return res.json().then(dt => { return { colorways: dt.colorways, url: res.url }; }).catch(() => { return { colorways: [], url: res.url }; }); + } + )); + const colorways = data.flatMap((json) => json.url === defaultColorwaySource ? json.colorways : []); + const thirdPartyColorwaysArr = data.flatMap((json) => json.url !== defaultColorwaySource ? json.colorways : []); + const baseData = await DataStore.getMany([ + "customColorways", + "actveColorwayID", + ]); + setColorways(colorways || fallbackColorways); + setThirdPartyColorways(thirdPartyColorwaysArr); + setCustomColorways(baseData[0]); + setCurrentColorway(baseData[1]); + }} + /> + + ); + } + + return ( + + + { + setVisibility(value); + }} isSelected={value => visibility === value} serialize={String} /> + [searchColorways, setSearchString].forEach(t => t(e))} + /> + + {({ onMouseEnter, onMouseLeave }) => { + return setShowReloadMenu(false)} + renderPopout={() => ReloadPopout(() => setShowReloadMenu(false))} + > + {(_, { isShown }) => ( + + )} + ; + }} + + + {({ onMouseEnter, onMouseLeave }) => } + + + {({ onMouseEnter, onMouseLeave }) => } + + +
+
+ {visibleColorwayArray.length === 0 && + + No colorways... + + } + {visibleColorwayArray.map((color, ind) => { + var colors: Array = color.colors || [ + "accent", + "primary", + "secondary", + "tertiary", + ]; + return ( + + {({ onMouseEnter, onMouseLeave }) => { + return ( +
+
{ + openModal((props) => ( + + )); + }} + > +
+ + + +
+
+
+
+ + + + + + +
+
+
{ + if ( + currentColorway === + color.name + ) { + DataStore.set( + "actveColorwayID", + null + ); + DataStore.set( + "actveColorway", + null + ); + ColorwayCSS.remove(); + } else { + DataStore.set( + "actveColorwayID", + color.name + ); + DataStore.set( + "actveColorway", + color["dc-import"] + ); + ColorwayCSS.set( + color["dc-import"] + ); + } + DataStore.get( + "actveColorwayID" + ).then( + ( + actveColorwayID: string + ) => + setCurrentColorway( + actveColorwayID + ) + ); + }} + > + {colors.map((colorItm) => { + return ( +
+ ); + })} +
+
+ ); + }} + + ); + })} +
+
+ + ); +} diff --git a/src/userplugins/DiscordColorways/components/SettingsTabs/SettingsPage.tsx b/src/userplugins/DiscordColorways/components/SettingsTabs/SettingsPage.tsx new file mode 100644 index 00000000..c6ef192a --- /dev/null +++ b/src/userplugins/DiscordColorways/components/SettingsTabs/SettingsPage.tsx @@ -0,0 +1,303 @@ +/* + * 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 { CopyIcon } from "@components/Icons"; +import { Link } from "@components/Link"; +import { SettingsTab } from "@components/VencordSettings/shared"; +import { ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal"; +import { + Button, + Clipboard, + FluxDispatcher, + Forms, + Switch, + Text, + TextInput, + useCallback, + useEffect, + useState +} from "@webpack/common"; +import { FluxEvents } from "@webpack/types"; +import { versionData } from "userplugins/discordColorways"; + +import { defaultColorwaySource, fallbackColorways, knownColorwaySources } from "../../constants"; +import { Colorway } from "../../types"; +import Divider from "../Divider"; +import { CloseIcon } from "../Icons"; + +export default function () { + const [colorways, setColorways] = useState([]); + const [customColorways, setCustomColorways] = useState([]); + const [colorwaySourceFiles, setColorwaySourceFiles] = useState(); + const [colorsButtonVisibility, setColorsButtonVisibility] = useState(false); + const [isButtonThin, setIsButtonThin] = useState(false); + + async function loadUI() { + const colorwaySourceFiles = await DataStore.get( + "colorwaySourceFiles" + ); + 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); + const [ + customColorways, + colorwaySourceFiless, + showColorwaysButton, + useThinMenuButton + ] = await DataStore.getMany([ + "customColorways", + "colorwaySourceFiles", + "showColorwaysButton", + "useThinMenuButton" + ]); + setColorways(colorways || fallbackColorways); + setCustomColorways(customColorways); + setColorwaySourceFiles(colorwaySourceFiless); + setColorsButtonVisibility(showColorwaysButton); + setIsButtonThin(useThinMenuButton); + } + + const cached_loadUI = useCallback(loadUI, []); + + useEffect(() => { + cached_loadUI(); + }, []); + + return +
+ + Sources + + + + ; + }); + }}> + + Add a source... + + + + {colorwaySourceFiles?.map((colorwaySourceFile: string) =>
+ {knownColorwaySources.find(o => o.url === colorwaySourceFile) ?
+ + {knownColorwaySources.find(o => o.url === colorwaySourceFile)!.name} {colorwaySourceFile === defaultColorwaySource &&
DEFAULT
} +
+ + {colorwaySourceFile} + +
+ : + {colorwaySourceFile} + } + {colorwaySourceFile !== defaultColorwaySource + && } + +
+ )} +
+ + 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 + + +

+ Discord Colorways +

+ by Project Colorway + + Plugin Version: + + + {versionData.pluginVersion} + + + Creator Version: + + + {versionData.creatorVersion}{" "} + (Stable) + + + Loaded Colorways: + + + {[...colorways, ...customColorways].length} + + + Project Repositories: + + + DiscordColorways +
+ Project Colorway +
+
+
+
; +} diff --git a/src/userplugins/DiscordColorways/components/Spinner.tsx b/src/userplugins/DiscordColorways/components/Spinner.tsx new file mode 100644 index 00000000..b0e24557 --- /dev/null +++ b/src/userplugins/DiscordColorways/components/Spinner.tsx @@ -0,0 +1,17 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export default function ({ className }: { className?: string; }) { + return
+
+ + + + + +
+
; +} diff --git a/src/userplugins/DiscordColorways/components/ThemePreview.tsx b/src/userplugins/DiscordColorways/components/ThemePreview.tsx new file mode 100644 index 00000000..3424c991 --- /dev/null +++ b/src/userplugins/DiscordColorways/components/ThemePreview.tsx @@ -0,0 +1,222 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { + Forms, + Text, + useState +} from "@webpack/common"; + +import { HexToHSL } from "../utils"; +import { CloseIcon } from "./Icons"; + +export default function ({ + accent, + primary, + secondary, + tertiary, + className, + isCollapsed, + previewCSS +}: { + accent: string, + primary: string, + secondary: string, + tertiary: string, + className?: string, + isCollapsed: boolean, + previewCSS?: string; +}) { + const [collapsed, setCollapsed] = useState(isCollapsed); + return ( +
+
setCollapsed(!collapsed)} + > + + Preview + + +
+ + +
+ ); +} + +function ThemePreview({ + accent, + primary, + secondary, + tertiary, + previewCSS +}: { + accent: string, + primary: string, + secondary: string, + tertiary: string, + previewCSS?: string; +}) { + const [isFullscreen, setIsFullscreen] = useState(false); + return ( +
+ +
+
+
+
+
+
e.currentTarget.style.backgroundColor = accent} + onMouseLeave={e => e.currentTarget.style.backgroundColor = primary} + onClick={e => { + if (!document.fullscreenElement) { + e.currentTarget + .parentElement + ?.parentElement + ?.parentElement + ?.parentElement + ?.requestFullscreen(); + } else { + document.exitFullscreen(); + } + setIsFullscreen(!isFullscreen); + }} + > + {isFullscreen ? : } +
+
+
+
+
+
+
{ e.currentTarget.style.backgroundColor = accent; }} + onMouseLeave={e => { e.currentTarget.style.backgroundColor = primary; }} + /> +
+
+
{ e.currentTarget.style.backgroundColor = accent; }} + onMouseLeave={e => { e.currentTarget.style.backgroundColor = primary; }} + /> +
+
+
+
+
+
+ + Preview + +
+
+
+
+
+
+
+
+
+
+ ); +} diff --git a/src/userplugins/DiscordColorways/constants.ts b/src/userplugins/DiscordColorways/constants.ts new file mode 100644 index 00000000..81cda963 --- /dev/null +++ b/src/userplugins/DiscordColorways/constants.ts @@ -0,0 +1,317 @@ +/* + * 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 knownColorwaySources = [ + { + name: "Project Colorway", + url: "https://raw.githubusercontent.com/DaBluLite/ProjectColorway/master/index.json" + }, + { + name: "DaBluLite's Personal Colorways", + url: "https://raw.githubusercontent.com/DaBluLite/dablulite.github.io/master/colorways/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" + } + } +}; diff --git a/src/userplugins/DiscordColorways/css.ts b/src/userplugins/DiscordColorways/css.ts new file mode 100644 index 00000000..0d90db78 --- /dev/null +++ b/src/userplugins/DiscordColorways/css.ts @@ -0,0 +1,767 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +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", +]; + +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, +}; + +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 +}; + +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 +}; + +function gradientBase(accentColor?: string, discordSaturation = false) { + return `@import url(//dablulite.github.io/css-snippets/NoLightInDark/import.css); +@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) { + const colorwayCss = `/*Automatically Generated - Colorway Creator V${(Plugins.plugins.DiscordColorways as any).creatorVersion}*/ +: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)}%; + --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)}%;${tintedText ? `\n --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%)")};` : ""} +} +.emptyPage_feb902, +.scrollerContainer_dda72c, +.container__03ec9, +.header__71942 { + background-color: unset !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__6b2e5, +.theme-dark .container__03ec9, +.theme-dark .header__71942 { + background: transparent; +} + +.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*/`: ""}`; + return colorwayCss; +} + +export function getPreset(primaryColor?: string, secondaryColor?: string, tertiaryColor?: string, accentColor?: string) { + 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]}%/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 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 modular(discordSaturation = false) { + return `:root:root { + --modular-hue: ${HexToHSL("#" + accentColor)[0]}; + --modular-saturation: calc(var(--saturation-factor, 1)${HexToHSL("#" + accentColor)[1]}%); + --modular-lightness: ${HexToHSL("#" + accentColor)[2]}%; +}`; + } + + 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 `${gradientBase(accentColor, discordSaturation)} + --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%); +}`; + } + + function gradientType2(discordSaturation = false) { + return `${gradientBase(accentColor, discordSaturation)} + --custom-theme-background: linear-gradient(48.17deg, #${primaryColor} 11.21%, #${secondaryColor} 61.92%); +}`; + } + + function hueRotation(discordSaturation = false) { + return `: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)}%; + --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(discordSaturation = false) { + return `: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)}%; +}`; + } + + return { + cyan: { + name: "Cyan", + preset: cyan, + id: "cyan", + colors: ["primary", "secondary", "accent"] + }, + virtualBoy: { + name: "Virtual Boy", + preset: virtualBoy, + id: "virtualBoy", + colors: ["tertiary", "accent"] + }, + modular: { + name: "Modular", + preset: modular, + id: "modular", + colors: ["accent"] + }, + solana: { + name: "Solana", + preset: solana, + id: "solana", + colors: ["primary", "accent"] + }, + gradientType1: { + name: "Gradient Type 1", + preset: gradientType1, + id: "gradientType1", + colors: ["primary", "secondary", "tertiary", "accent"] + }, + gradientType2: { + name: "Gradient Type 2", + preset: gradientType2, + id: "gradientType2", + colors: ["primary", "secondary", "accent"] + }, + hueRotation: { + name: "Hue Rotation", + preset: hueRotation, + id: "hueRotation", + colors: ["accent"] + }, + accentSwap: { + name: "Accent Swap", + preset: accentSwap, + id: "accentSwap", + colors: ["accent"] + } + }; +} diff --git a/src/userplugins/DiscordColorways/index.tsx b/src/userplugins/DiscordColorways/index.tsx new file mode 100644 index 00000000..04db2cab --- /dev/null +++ b/src/userplugins/DiscordColorways/index.tsx @@ -0,0 +1,225 @@ +/* + * 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 { Devs } from "@utils/constants"; +import { openModal } from "@utils/modal"; +import definePlugin from "@utils/types"; +import { + Button, + SettingsRouter, +} from "@webpack/common"; + +import ColorPickerModal from "./components/ColorPicker"; +import ColorwaysButton from "./components/ColorwaysButton"; +import CreatorModal from "./components/CreatorModal"; +import SelectorModal from "./components/SelectorModal"; +import ManageColorwaysPage from "./components/SettingsTabs/ManageColorwaysPage"; +import OnDemandWaysPage from "./components/SettingsTabs/OnDemandPage"; +import SelectorPage from "./components/SettingsTabs/SelectorPage"; +import SettingsPage from "./components/SettingsTabs/SettingsPage"; +import Spinner from "./components/Spinner"; +import { defaultColorwaySource } from "./constants"; +import style from "./style.css?managed"; +import { ColorPickerProps } from "./types"; + +export let ColorPicker: React.FunctionComponent = () => { + return ; +}; + +(async function () { + const [ + customColorways, + colorwaySourcesFiles, + showColorwaysButton, + onDemandWays, + onDemandWaysTintedText, + useThinMenuButton, + onDemandWaysDiscordSaturation, + onDemandWaysColorArray + ] = await DataStore.getMany([ + "customColorways", + "colorwaySourceFiles", + "showColorwaysButton", + "onDemandWays", + "onDemandWaysTintedText", + "useThinMenuButton", + "onDemandWaysDiscordSaturation", + "onDemandWaysColorArray" + ]); + + if (!customColorways) + DataStore.set("customColorways", []); + + if (!colorwaySourcesFiles) + DataStore.set("colorwaySourceFiles", [defaultColorwaySource]); + + if (!showColorwaysButton) + DataStore.set("showColorwaysButton", false); + + if (!onDemandWays) + DataStore.set("onDemandWays", false); + + if (!onDemandWaysTintedText) + DataStore.set("onDemandWaysTintedText", true); + + if (!useThinMenuButton) + DataStore.set("useThinMenuButton", false); + + if (!onDemandWaysDiscordSaturation) + DataStore.set("onDemandWaysDiscordSaturation", false); + + if (!onDemandWaysColorArray) + DataStore.set("onDemandWaysColorArray", ["313338", "2b2d31", "1e1f22", "5865f2"]); + +})(); + +export const ColorwayCSS = { + get: () => document.getElementById("activeColorwayCSS")?.textContent || "", + set: (e: string) => { + if (!document.getElementById("activeColorwayCSS")) { + var activeColorwayCSS: HTMLStyleElement = + document.createElement("style"); + activeColorwayCSS.id = "activeColorwayCSS"; + activeColorwayCSS.textContent = e; + document.head.append(activeColorwayCSS); + } else document.getElementById("activeColorwayCSS")!.textContent = e; + }, + remove: () => document.getElementById("activeColorwayCSS")!.remove(), +}; + +export const versionData = { + pluginVersion: "5.6.1", + creatorVersion: "1.18", +}; + +export default definePlugin({ + name: "DiscordColorways", + description: + "A plugin that offers easy access to simple color schemes/themes for Discord, also known as Colorways", + authors: [{ + name: "DaBluLite", + id: 582170007505731594n + }, 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"), + }, + 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:(\i\.\i)\.HEADER,\s*label:(\i)\.\i\.Messages\.APP_SETTINGS\}/, + replace: "...$self.makeSettingsCategories($1),$&" + } + } + ], + set ColorPicker(e) { + ColorPicker = e; + }, + + makeSettingsCategories(SectionTypes: Record) { + console.log(SectionTypes); + return [ + { + section: SectionTypes.HEADER, + label: "DiscordColorways", + className: "vc-settings-header" + }, + { + section: "ColorwaysSelector", + label: "Colorways", + element: SelectorPage, + className: "dc-colorway-selector" + }, + { + section: "ColorwaysSettings", + label: "Settings", + element: SettingsPage, + className: "dc-colorway-settings" + }, + { + section: "ColorwaysOnDemand", + label: "On-Demand", + element: OnDemandWaysPage, + className: "dc-colorway-ondemand" + }, + { + section: "ColorwaysManagement", + label: "Manage...", + element: ManageColorwaysPage, + className: "dc-colorway-management" + }, + { + section: SectionTypes.DIVIDER + } + ].filter(Boolean); + }, + + ColorwaysButton: () => , + + async start() { + addServerListElement(ServerListRenderPosition.In, this.ColorwaysButton); + + enableStyle(style); + ColorwayCSS.set((await DataStore.get("actveColorway")) || ""); + + addAccessory("colorways-btn", props => { + if (String(props.message.content).match(/colorway:[0-9a-f]{0,71}/)) + return ; + return null; + }); + }, + stop() { + removeServerListElement(ServerListRenderPosition.In, this.ColorwaysButton); + + disableStyle(style); + ColorwayCSS.remove(); + removeAccessory("colorways-btn"); + }, +}); diff --git a/src/userplugins/DiscordColorways/style.css b/src/userplugins/DiscordColorways/style.css new file mode 100644 index 00000000..da4d66b1 --- /dev/null +++ b/src/userplugins/DiscordColorways/style.css @@ -0,0 +1,1214 @@ +/* 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-experiment); + border-radius: 16px; +} + +.discordColorway { + height: 60px; + width: 60px; + cursor: pointer; + display: flex; + flex-flow: wrap; + flex-direction: row; + position: relative; + align-items: center; + justify-content: 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 1px var(--interactive-normal); + box-sizing: border-box; +} + +.discordColorway::before { + content: ""; + position: absolute; + top: -2px; + left: -2px; + border-radius: 50%; + width: 64px; + height: 64px; + pointer-events: none; + transition: .15s; +} + +.discordColorway.active::before { + box-shadow: inset 0 0 0 2px var(--brand-500), inset 0 0 0 4px var(--background-primary); +} + +.discordColorwayPreviewColor { + width: calc(50% - 2px); + height: calc(50% - 2px); +} + +.discordColorwayPreviewColor:first-child { + margin-top: 2px; + margin-left: 2px; + border-top-left-radius: 52px; +} + +.discordColorwayPreviewColor:nth-child(2) { + margin-top: 2px; + margin-right: 2px; + border-top-right-radius: 52px; +} + +.discordColorwayPreviewColor:nth-child(3) { + margin-bottom: 2px; + margin-left: 2px; + border-bottom-left-radius: 52px; +} + +.discordColorwayPreviewColor:nth-child(4) { + margin-bottom: 2px; + margin-right: 2px; + border-bottom-right-radius: 52px; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(2)))>.discordColorwayPreviewColor { + height: calc(100% - 4px); + width: calc(100% - 4px); + margin: 2px; + border-radius: 52px; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor { + height: calc(100% - 4px); + margin-top: 2px; + margin-bottom: 2px; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor:nth-child(1) { + border-top-left-radius: 52px; + border-bottom-left-radius: 52px; + margin-left: 2px; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor:nth-child(2) { + border-top-right-radius: 52px; + border-bottom-right-radius: 52px; + margin-right: 2px; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(4)))>.discordColorwayPreviewColor:nth-child(3) { + width: calc(100% - 4px); + margin-right: 2px; + border-bottom-right-radius: 52px; + border-bottom-left-radius: 52px; +} + +.ColorwaySelectorWrapper { + position: relative; + display: flex; + gap: 16px 23px; + width: 100%; + flex-wrap: wrap; + padding: 2px; + scrollbar-width: none !important; +} + +.colorwaySelectorModal { + width: 100% !important; + min-width: 596px !important; +} + +.colorwaySelectorModalContent { + display: flex; + flex-direction: column; + gap: 8px; + width: 100%; + max-width: 596px; + overflow: visible !important; + padding: 0 16px 16px !important; +} + +.ColorwaySelectorBtnContainer { + position: relative; + margin: 0 0 8px; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 72px; +} + +.colorwayCheckIconContainer { + height: 20px; + width: 20px; + background-color: var(--brand-500); + position: absolute; + top: 0; + right: 0; + border-radius: 50%; + opacity: 0; + z-index: +1; +} + +.discordColorway.active .colorwayCheckIconContainer { + opacity: 1; +} + +.colorwayCheckIcon { + height: 20px; + width: 20px; + color: var(--white-500); +} + +.colorwayInfoIconContainer { + height: 20px; + width: 20px; + background-color: var(--brand-500); + position: absolute; + top: 0; + left: 0; + border-radius: 50%; + opacity: 0; + z-index: +1; +} + +.colorwayInfoIconContainer:hover { + background-color: var(--brand-700); +} + +.discordColorway:hover .colorwayInfoIconContainer { + opacity: 1; + transition: .15s; +} + +.colorwayInfoIcon { + height: 20px; + width: 20px; + color: var(--white-500); + padding: 2px; +} + +.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; + border-radius: 4px; + background-color: var(--background-secondary); + box-sizing: border-box; + padding: 10px; +} + +.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; +} + +.colorwayCreator-colorPreviews:has(>.colorways-creator-module-warning) { + background-color: transparent; +} + +.colorways-creator-module-warning { + color: var(--brand-500); +} + +.colorways-creator-module-warning~.colorways-creator-module-warning { + display: none; +} + +.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; + margin: 12px 0; + gap: 8px; +} + +.colorwayInfo-colorSwatch { + display: flex; + width: 100%; + height: 46px; + border-radius: 4px; + cursor: pointer; + position: relative; +} + +.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; + gap: 5px; + 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>.colorwaysCreator-settingsList, +.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-container { + 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 0 auto; +} + +.colorwayPreview-filler { + width: 100%; + height: 100%; +} + +.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; + flex: 1 0 auto; + transition: background-color .1s linear; + font-family: var(--font-display); + font-weight: 500; + padding: 12px 16px; + box-sizing: border-box; + align-items: center; + display: flex; +} + +.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-searchInput { + border-radius: 0 3px 3px 0 !important; + flex: 0 0 auto; +} + +.colorwaySelector-pill.colorwaySelector-pill_select { + border-radius: 3px 0 0 3px !important; + flex: 0 0 auto; + border: none; + height: 40px; +} + +.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: 0 8px; + gap: 5px; + border-radius: 4px; + box-sizing: border-box; + min-height: 44px; + align-items: center; + background-color: var(--background-secondary); +} + +.colorwaysSettings-colorwaySource:hover { + background-color: var(--background-secondary-alt); +} + +.colorwaysSettings-modalRoot { + min-width: 520px; +} + +.colorwaysSettings-colorwaySourceLabel { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.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: 1px; + 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; +} diff --git a/src/userplugins/DiscordColorways/types.ts b/src/userplugins/DiscordColorways/types.ts new file mode 100644 index 00000000..15fa776d --- /dev/null +++ b/src/userplugins/DiscordColorways/types.ts @@ -0,0 +1,29 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export interface Colorway { + name: string, + "dc-import": string, + accent: string, + primary: string, + secondary: string, + tertiary: string, + original?: boolean, + author: string, + authorID: string, + colors?: string[], + isGradient?: boolean, + sourceUrl?: string, + sourceName?: string; +} + +export interface ColorPickerProps { + color: number; + showEyeDropper: boolean; + suggestedColors: string[]; + label: any; + onChange(color: number): void; +} diff --git a/src/userplugins/DiscordColorways/utils.ts b/src/userplugins/DiscordColorways/utils.ts new file mode 100644 index 00000000..2b163b0c --- /dev/null +++ b/src/userplugins/DiscordColorways/utils.ts @@ -0,0 +1,133 @@ +/* + * 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)}`; +} diff --git a/src/userplugins/QuickReactFrequents/index.ts b/src/userplugins/QuickReactFrequents/index.ts new file mode 100644 index 00000000..1c08b144 --- /dev/null +++ b/src/userplugins/QuickReactFrequents/index.ts @@ -0,0 +1,22 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Devs } from "@utils/constants"; +import definePlugin from "@utils/types"; + +export default definePlugin({ + name: "QuickReactFrequents", + description: "Make quick react use top frecency emojis instead of favourites", + authors: [Devs.Ven], + + patches: [{ + find: "this.favoriteEmojisWithoutFetchingLatest.concat", + replacement: { + match: "this.favoriteEmojisWithoutFetchingLatest.concat", + replace: "[].concat" + } + }] +});