From 6008aea91d6d12f173ea9410f3316e079284e297 Mon Sep 17 00:00:00 2001 From: verticalsync <60797172+verticalsync@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:20:09 +0300 Subject: [PATCH] add a couple plugins --- README.md | 11 +- .../betterShopPreview/index.tsx | 88 ++ .../components/ColorPicker.tsx | 220 ++++ .../components/ColorwaysButton.tsx | 94 ++ .../components/ConflictingColorsModal.tsx | 318 +++++ .../components/CreatorModal.tsx | 342 +++++ .../discordColorways/components/Divider.tsx | 15 + .../discordColorways/components/Icons.tsx | 62 + .../discordColorways/components/InfoModal.tsx | 264 ++++ .../components/InputColorwayIdModal.tsx | 49 + .../components/SelectorModal.tsx | 469 +++++++ .../SettingsTabs/ManageColorwaysPage.tsx | 129 ++ .../components/SettingsTabs/OnDemandPage.tsx | 68 + .../components/SettingsTabs/SelectorPage.tsx | 421 ++++++ .../components/SettingsTabs/SettingsPage.tsx | 305 +++++ .../discordColorways/components/Spinner.tsx | 17 + .../components/ThemePreview.tsx | 209 +++ .../discordColorways/constants.ts | 317 +++++ src/suncordplugins/discordColorways/css.ts | 771 +++++++++++ src/suncordplugins/discordColorways/index.tsx | 222 ++++ src/suncordplugins/discordColorways/style.css | 1146 +++++++++++++++++ src/suncordplugins/discordColorways/types.ts | 29 + src/suncordplugins/discordColorways/utils.ts | 150 +++ src/suncordplugins/godMode/index.ts | 33 + src/suncordplugins/repeatMessage/index.tsx | 127 ++ src/suncordplugins/runInConsole/index.tsx | 158 +++ src/suncordplugins/runInConsole/style.css | 27 + .../slashCommandMentionOptions/index.tsx | 138 ++ .../slashCommandMentionOptions/types.ts | 9 + src/suncordplugins/talkInReverse/index.tsx | 65 + src/utils/constants.ts | 12 + 31 files changed, 6284 insertions(+), 1 deletion(-) create mode 100644 src/suncordplugins/betterShopPreview/index.tsx create mode 100644 src/suncordplugins/discordColorways/components/ColorPicker.tsx create mode 100644 src/suncordplugins/discordColorways/components/ColorwaysButton.tsx create mode 100644 src/suncordplugins/discordColorways/components/ConflictingColorsModal.tsx create mode 100644 src/suncordplugins/discordColorways/components/CreatorModal.tsx create mode 100644 src/suncordplugins/discordColorways/components/Divider.tsx create mode 100644 src/suncordplugins/discordColorways/components/Icons.tsx create mode 100644 src/suncordplugins/discordColorways/components/InfoModal.tsx create mode 100644 src/suncordplugins/discordColorways/components/InputColorwayIdModal.tsx create mode 100644 src/suncordplugins/discordColorways/components/SelectorModal.tsx create mode 100644 src/suncordplugins/discordColorways/components/SettingsTabs/ManageColorwaysPage.tsx create mode 100644 src/suncordplugins/discordColorways/components/SettingsTabs/OnDemandPage.tsx create mode 100644 src/suncordplugins/discordColorways/components/SettingsTabs/SelectorPage.tsx create mode 100644 src/suncordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx create mode 100644 src/suncordplugins/discordColorways/components/Spinner.tsx create mode 100644 src/suncordplugins/discordColorways/components/ThemePreview.tsx create mode 100644 src/suncordplugins/discordColorways/constants.ts create mode 100644 src/suncordplugins/discordColorways/css.ts create mode 100644 src/suncordplugins/discordColorways/index.tsx create mode 100644 src/suncordplugins/discordColorways/style.css create mode 100644 src/suncordplugins/discordColorways/types.ts create mode 100644 src/suncordplugins/discordColorways/utils.ts create mode 100644 src/suncordplugins/godMode/index.ts create mode 100644 src/suncordplugins/repeatMessage/index.tsx create mode 100644 src/suncordplugins/runInConsole/index.tsx create mode 100644 src/suncordplugins/runInConsole/style.css create mode 100644 src/suncordplugins/slashCommandMentionOptions/index.tsx create mode 100644 src/suncordplugins/slashCommandMentionOptions/types.ts create mode 100644 src/suncordplugins/talkInReverse/index.tsx diff --git a/README.md b/README.md index ba3f1719..b25410e3 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,14 @@ Visit [1_INSTALLING.md](/docs/1_INSTALLING.md) - - QuestionMarkReplacement (for smuki, i think he's acoustic) - - SmukiCommands (roblox tax calculation and profile commands for smuki) +- Plugins by [Tolgchu](https://github.com/Tolga1452/Vencord) +- - BetterShopPreview +- - GodMode +- - RepeatMessage +- - RunInConsole +- - SlashCommandMentionOptions +- - TalkInReverse + - PurgeMessages (by [bhop](https://github.com/prettylittlelies)) - PlatformSpoofer (by [drag](https://github.com/dragdotpng)) - Timezones (by [mantikafasi](https://github.com/mantikafasi) & [ArjixWasTaken](https://github.com/ArjixWasTaken)) @@ -50,7 +58,7 @@ Visit [1_INSTALLING.md](/docs/1_INSTALLING.md) - iRememberYou (by [zoodogood](https://github.com/zoodogood/vencord-plugins)) - EmojiDownloader (by [woosh](https://github.com/w8y) modified version of ServerDownload by [cheesesamwich](https://github.com/cheesesamwich/ServerDownload)) - GlobalBadges (by [HypedDomi](https://github.com/domi-btnr/Vencord-Plugins)) -- MessageLoggerEnhanced (by [Syncxv](https://github.com/Syncxv/vc-message-logger-enhanced)) +- MessageLoggerEnhanced (by [Syncxv](https://github.com/Syncxv/vc-message-logger-enhanced))/ - CommandPalette (by [Ethan](https://github.com/ethan-davies)) (added from Ethan's [pull request](https://github.com/Vendicated/Vencord/pull/2145) to vencord) - AllCallTimers (by [Max-Herbold](https://github.com/Max-Herbold)) (added from Max's [pull request](https://github.com/Vendicated/Vencord/pull/2132) to vencord) - SoundBoardLogger (by [ImpishMoxxie](https://github.com/ImpishMoxxie/SoundBoardLogger)) @@ -66,6 +74,7 @@ Visit [1_INSTALLING.md](/docs/1_INSTALLING.md) - AmITyping (by [MrDiamondDog](https://github.com/MrDiamondDog)) (added from MrDiamondDog's [pull request](https://github.com/Vendicated/Vencord/pull/2360)) - UserPFP (by [Nexpid](https://github.com/Nexpid)) (added from Nexpid's [pull request](https://github.com/Vendicated/Vencord/pull/1956)) - ShowBadgeInChat (by [KrstlSkll69](https://github.com/KrstlSkll69) (added from KrstlSkll69's [pull request](https://github.com/Vendicated/Vencord/pull/2347))) +- DiscordColorways (by [DaBluLite](https://github.com/DaBluLite/DiscordColorways)) diff --git a/src/suncordplugins/betterShopPreview/index.tsx b/src/suncordplugins/betterShopPreview/index.tsx new file mode 100644 index 00000000..7b0ff166 --- /dev/null +++ b/src/suncordplugins/betterShopPreview/index.tsx @@ -0,0 +1,88 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2022 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import { definePluginSettings } from "@api/Settings"; +import { Devs } from "@utils/constants"; +import definePlugin, { OptionType } from "@utils/types"; +import { UserStore, useState } from "@webpack/common"; + +let avatarUrl = ""; + +const settings = definePluginSettings({ + default: { + type: OptionType.BOOLEAN, + description: "Enable avatar preview by default.", + default: true + } +}); + +function toggle(enabled: boolean) { + const avatars = document.querySelectorAll(".shopCard__3d319 .avatarContainer_e11d35 .wrapper__3ed10 .mask_d5067d foreignObject .avatarStack__789b4"); + + for (const avatar of avatars) { + const img = avatar.querySelector("img"); + + if (img) img.src = enabled ? avatarUrl : "https://canary.discord.com/assets/6d8f0708e196aaad2550.png"; + } +} + +const PreviewToggle = () => { + const [enabled, setEnabled] = useState(settings.store.default); + + toggle(enabled); + + return ( + + ); +}; + +export default definePlugin({ + name: "BetterShopPreview", + description: "Uses your avatar for avatar decoration previews in the Discord Shop.", + authors: [Devs.Tolgchu], + settings, + patches: [ + { + find: "}),(0,l.jsx)(T.default.Title,{className:en.title,children:er.default.Messages.COLLECTIBLES_SHOP})]", + replacement: [{ + match: "{className:en.title,children:er.default.Messages.COLLECTIBLES_SHOP}", + replace: "{className:en.title,children:[er.default.Messages.COLLECTIBLES_SHOP,$self.PreviewToggle()]}" + }] + } + ], + PreviewToggle, + async start() { + const user = UserStore.getCurrentUser(); + const url = `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.gif`; + + await fetch(url).then(response => { + if (response.ok) avatarUrl = url; + else avatarUrl = url.replace(".gif", ".png"); + }); + }, + stop() { } +}); diff --git a/src/suncordplugins/discordColorways/components/ColorPicker.tsx b/src/suncordplugins/discordColorways/components/ColorPicker.tsx new file mode 100644 index 00000000..195eecb9 --- /dev/null +++ b/src/suncordplugins/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/suncordplugins/discordColorways/components/ColorwaysButton.tsx b/src/suncordplugins/discordColorways/components/ColorwaysButton.tsx new file mode 100644 index 00000000..e003ccc1 --- /dev/null +++ b/src/suncordplugins/discordColorways/components/ColorwaysButton.tsx @@ -0,0 +1,94 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import * as DataStore from "@api/DataStore"; +import { openModal } from "@utils/modal"; +import { FluxDispatcher, Text, Tooltip, useEffect, useState } from "@webpack/common"; +import { FluxEvents } from "@webpack/types"; + +import { 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); + } + + useEffect(() => { + 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 }) => 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 }) => visibility ?
+
{ + onMouseEnter(); + setActiveColorway(await DataStore.get("actveColorwayID") || "None"); + }} + onMouseLeave={onMouseLeave} + onClick={() => { + onClick(); + openModal(props => ); + }} + >Colorways
+
: <>} +
+ ); + } +} diff --git a/src/suncordplugins/discordColorways/components/ConflictingColorsModal.tsx b/src/suncordplugins/discordColorways/components/ConflictingColorsModal.tsx new file mode 100644 index 00000000..410f9aee --- /dev/null +++ b/src/suncordplugins/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/suncordplugins/discordColorways/components/CreatorModal.tsx b/src/suncordplugins/discordColorways/components/CreatorModal.tsx new file mode 100644 index 00000000..cd4fcdf9 --- /dev/null +++ b/src/suncordplugins/discordColorways/components/CreatorModal.tsx @@ -0,0 +1,342 @@ +/* + * 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 { colorToHex, getHex, hexToString } from "../utils"; +import ConflictingColorsModal from "./ConflictingColorsModal"; +import InputColorwayIdModal from "./InputColorwayIdModal"; +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"]); + + const colorProps = { + accent: { + get: accentColor, + set: setAccentColor, + name: "Accent" + }, + primary: { + get: primaryColor, + set: setPrimaryColor, + name: "Primary" + }, + secondary: { + get: secondaryColor, + set: setSecondaryColor, + name: "Secondary" + }, + tertiary: { + get: tertiaryColor, + set: setTertiaryColor, + name: "Tertiary" + } + }; + + useEffect(() => { + 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.map(presetColor => { + return {colorProps[presetColor].name}} + color={parseInt(colorProps[presetColor].get, 16)} + onChange={(color: number) => { + let hexColor = color.toString(16); + while (hexColor.length < 6) { + hexColor = "0" + hexColor; + } + colorProps[presetColor].set(hexColor); + }} + {...colorPickerProps} + />; + })} +
+
+
+
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} +
; + })} +
+
+ +
+ + + + + + +
+ ); +} diff --git a/src/suncordplugins/discordColorways/components/Divider.tsx b/src/suncordplugins/discordColorways/components/Divider.tsx new file mode 100644 index 00000000..ec27d0ac --- /dev/null +++ b/src/suncordplugins/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/suncordplugins/discordColorways/components/Icons.tsx b/src/suncordplugins/discordColorways/components/Icons.tsx new file mode 100644 index 00000000..2545c000 --- /dev/null +++ b/src/suncordplugins/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/suncordplugins/discordColorways/components/InfoModal.tsx b/src/suncordplugins/discordColorways/components/InfoModal.tsx new file mode 100644 index 00000000..5544ddef --- /dev/null +++ b/src/suncordplugins/discordColorways/components/InfoModal.tsx @@ -0,0 +1,264 @@ +/* + * 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 { colorToHex } from "../utils"; +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/suncordplugins/discordColorways/components/InputColorwayIdModal.tsx b/src/suncordplugins/discordColorways/components/InputColorwayIdModal.tsx new file mode 100644 index 00000000..6100529c --- /dev/null +++ b/src/suncordplugins/discordColorways/components/InputColorwayIdModal.tsx @@ -0,0 +1,49 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { ModalContent, ModalFooter, ModalProps, ModalRoot } from "@utils/modal"; +import { Button, Forms, TextInput, useState } from "@webpack/common"; + +import { hexToString } from "../utils"; + +export default function ({ modalProps, onColorwayId }: { modalProps: ModalProps, onColorwayId: (colorwayID: string) => void; }) { + const [colorwayID, setColorwayID] = useState(""); + return + + Colorway ID: + setColorwayID(e.currentTarget.value)} /> + + + + + + ; +} diff --git a/src/suncordplugins/discordColorways/components/SelectorModal.tsx b/src/suncordplugins/discordColorways/components/SelectorModal.tsx new file mode 100644 index 00000000..1ede727b --- /dev/null +++ b/src/suncordplugins/discordColorways/components/SelectorModal.tsx @@ -0,0 +1,469 @@ +/* + * 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 { findByPropsLazy } from "@webpack"; +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 { colorToHex } from "../utils"; +import ColorPickerModal from "./ColorPicker"; +import CreatorModal from "./CreatorModal"; +import { CloseIcon } from "./Icons"; +import ColorwayInfoModal from "./InfoModal"; + +const { SelectionCircle } = findByPropsLazy("SelectionCircle"); + +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 ( +
{ + const [ + onDemandWays, + onDemandWaysTintedText, + onDemandWaysDiscordSaturation + ] = await DataStore.getMany([ + "onDemandWays", + "onDemandWaysTintedText", + "onDemandWaysDiscordSaturation" + ]); + if (currentColorway === color.name) { + DataStore.set("actveColorwayID", null); + DataStore.set("actveColorway", null); + ColorwayCSS.remove(); + } else { + DataStore.set("activeColorwayColors", color.colors); + DataStore.set("actveColorwayID", color.name); + if (onDemandWays) { + const demandedColorway = generateCss( + colorToHex(color.primary), + colorToHex(color.secondary), + colorToHex(color.tertiary), + colorToHex(color.accent), + onDemandWaysTintedText, + onDemandWaysDiscordSaturation + ); + DataStore.set("actveColorway", demandedColorway); + ColorwayCSS.set(demandedColorway); + } else { + DataStore.set("actveColorway", color["dc-import"]); + ColorwayCSS.set(color["dc-import"]); + } + } + setCurrentColorway(await DataStore.get("actveColorwayID") as string); + }} + > +
{ + e.stopPropagation(); + openModal((props) => ( + + )); + }} + > + + + +
+
+ {colors.map((colorItm) =>
+ )} +
+ {currentColorway === color.name && } +
+ ); + }} + + ); + })} +
+
+ + ); +} diff --git a/src/suncordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx b/src/suncordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx new file mode 100644 index 00000000..90a42377 --- /dev/null +++ b/src/suncordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx @@ -0,0 +1,305 @@ +/* + * 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 "../.."; +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/suncordplugins/discordColorways/components/Spinner.tsx b/src/suncordplugins/discordColorways/components/Spinner.tsx new file mode 100644 index 00000000..b0e24557 --- /dev/null +++ b/src/suncordplugins/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/suncordplugins/discordColorways/components/ThemePreview.tsx b/src/suncordplugins/discordColorways/components/ThemePreview.tsx new file mode 100644 index 00000000..6c4713c8 --- /dev/null +++ b/src/suncordplugins/discordColorways/components/ThemePreview.tsx @@ -0,0 +1,209 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { ModalProps, ModalRoot, openModal } from "@utils/modal"; +import { + 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); + function ThemePreview({ + accent, + primary, + secondary, + tertiary, + isModal, + modalProps + }: { + accent: string, + primary: string, + secondary: string, + tertiary: string, + isModal?: boolean, + modalProps?: ModalProps; + }) { + return ( +
+
+
+
+
+
e.currentTarget.style.backgroundColor = accent} + onMouseLeave={e => e.currentTarget.style.backgroundColor = primary} + onClick={() => { + if (isModal) { + modalProps?.onClose(); + } else { + openModal((props: ModalProps) => + + + ); + } + }} + > + {isModal ? : } +
+
+
+
+
+
+
{ 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 + +
+
+
+
+
+
+
+
+
+ ); + } + return ( +
+
setCollapsed(!collapsed)} + > + + Preview + + +
+ + +
+ ); +} + diff --git a/src/suncordplugins/discordColorways/constants.ts b/src/suncordplugins/discordColorways/constants.ts new file mode 100644 index 00000000..81cda963 --- /dev/null +++ b/src/suncordplugins/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/suncordplugins/discordColorways/css.ts b/src/suncordplugins/discordColorways/css.ts new file mode 100644 index 00000000..c21e6e13 --- /dev/null +++ b/src/suncordplugins/discordColorways/css.ts @@ -0,0 +1,771 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Plugins } from "Vencord"; + +import { colorToHex, 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) { + primaryColor = colorToHex(primaryColor); + secondaryColor = colorToHex(secondaryColor); + tertiaryColor = colorToHex(tertiaryColor); + accentColor = colorToHex(accentColor); + 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/suncordplugins/discordColorways/index.tsx b/src/suncordplugins/discordColorways/index.tsx new file mode 100644 index 00000000..00379b9e --- /dev/null +++ b/src/suncordplugins/discordColorways/index.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 * 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.3", + creatorVersion: "1.18.1", +}; + +export default definePlugin({ + name: "DiscordColorways", + description: + "A plugin that offers easy access to simple color schemes/themes for Discord, also known as Colorways", + authors: [Devs.DaBluLite, Devs.ImLvna], + dependencies: ["ServerListAPI", "MessageAccessoriesAPI"], + pluginVersion: versionData.pluginVersion, + creatorVersion: versionData.creatorVersion, + toolboxActions: { + "Change Colorway": () => openModal(props => ), + "Open Colorway Creator": () => openModal(props => ), + "Open Color Stealer": () => openModal(props => ), + "Open Settings": () => SettingsRouter.open("ColorwaysSettings"), + "Open On-Demand Settings": () => SettingsRouter.open("ColorwaysOnDemand"), + "Manage Colorways...": () => SettingsRouter.open("ColorwaysManagement"), + }, + 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/suncordplugins/discordColorways/style.css b/src/suncordplugins/discordColorways/style.css new file mode 100644 index 00000000..33c3f9d8 --- /dev/null +++ b/src/suncordplugins/discordColorways/style.css @@ -0,0 +1,1146 @@ +/* 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 1.5px var(--interactive-normal); + box-sizing: border-box; +} + +.discordColorwayPreviewColor { + width: 50%; + height: 50%; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(2)))>.discordColorwayPreviewColor { + height: 100%; + width: 100%; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor { + height: 100%; +} + +.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(4)))>.discordColorwayPreviewColor:nth-child(3) { + width: 100%; +} + +.ColorwaySelectorWrapper { + position: relative; + display: flex; + gap: 16px 23px; + width: 100%; + flex-wrap: wrap; + padding: 2px; + scrollbar-width: none !important; +} + +.ColorwaySelectorWrapper::-webkit-scrollbar { + width: 0; +} + +.colorwaySelectorModal { + width: 100% !important; + min-width: 596px !important; +} + +.colorwaySelectorModalContent { + display: flex; + flex-direction: column; + 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; +} + +.colorwayInfoIconContainer { + height: 22px; + width: 22px; + background-color: var(--brand-500); + position: absolute; + top: -1px; + left: -1px; + border-radius: 50%; + opacity: 0; + z-index: +1; + color: var(--white-500); + padding: 1px; + box-sizing: border-box; +} + +.colorwayInfoIconContainer:hover { + background-color: var(--brand-experiment-560); +} + +.discordColorway:hover .colorwayInfoIconContainer { + opacity: 1; + transition: .15s; +} + +.colorwayCreator-swatch { + display: flex; + align-items: center; + justify-content: center; + height: 50px; + border-radius: 4px; + box-sizing: border-box; + border: none; + width: 100%; + position: relative; + color: #fff; +} + +.colorwayCreator-swatchName { + color: currentcolor; + pointer-events: none; +} + +.colorwayCreator-colorPreviews { + width: 100%; + height: fit-content; + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 8px; + position: relative; + border-radius: 4px; + box-sizing: border-box; +} + +.colorwayCreator-colorInput { + width: 1px; + height: 1px; + opacity: 0; + position: absolute; + pointer-events: none; +} + +.colorwayCreator-menuWrapper { + display: flex; + flex-direction: column; + gap: 8px; + padding: 20px 16px !important; + overflow: visible !important; + min-height: unset; +} + +.colorwayCreator-modal { + width: 620px !important; + max-width: 620px; + max-height: unset !important; +} + +.colorways-creator-module-warning { + color: var(--brand-500); +} + +.colorwayCreator-colorPreviews>[class^="colorSwatch"], +.colorwayCreator-colorPreviews>[class^="colorSwatch"]>[class^="swatch"] { + width: 100%; + border: none; + position: relative; +} + +.colorwaysPicker-colorLabel { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; +} + +.colorwayCreator-colorPreviews>.colorSwatch-2UxEuG:has([fill="var(--primary-530)"])>.colorwaysPicker-colorLabel { + color: var(--primary-530); +} + +.colorwaySelector-noDisplay { + display: none; +} + +.colorwayInfo-wrapper { + display: flex; + flex-direction: column; + color: var(--header-primary); +} + +.colorwayInfo-colorSwatches { + width: 100%; + height: 46px; + display: flex; + flex-direction: row; + 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: 90vw; + height: 90vh; +} + +.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; +} + +.theme-dark .colorwaysSettings-colorwaySource { + background: var(--bg-overlay-3,var(--background-secondary)); +} + +.theme-light .colorwaysSettings-colorwaySource { + background: var(--bg-overlay-2,var(--background-secondary)); +} + +.colorwaysSettings-colorwaySource:hover { + background-color: var(--background-secondary-alt); +} + +.theme-dark .colorwaysSettings-colorwaySource:hover { + background: var(--bg-overlay-1,var(--background-secondary-alt)); +} + +.theme-light .colorwaysSettings-colorwaySource:hover { + background: var(--bg-overlay-3,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; +} + +.dc-warning-card { + padding: 1em; + margin-bottom: 1em; + background-color: var(--info-warning-background); + border-color: var(--info-warning-foreground); + color: var(--info-warning-text); +} diff --git a/src/suncordplugins/discordColorways/types.ts b/src/suncordplugins/discordColorways/types.ts new file mode 100644 index 00000000..15fa776d --- /dev/null +++ b/src/suncordplugins/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/suncordplugins/discordColorways/utils.ts b/src/suncordplugins/discordColorways/utils.ts new file mode 100644 index 00000000..62e3859e --- /dev/null +++ b/src/suncordplugins/discordColorways/utils.ts @@ -0,0 +1,150 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export function HexToHSL(H: string) { + let r: any = 0, g: any = 0, b: any = 0; + if (H.length === 4) r = "0x" + H[1] + H[1], g = "0x" + H[2] + H[2], b = "0x" + H[3] + H[3]; + else if (H.length === 7) { + r = "0x" + H[1] + H[2]; + g = "0x" + H[3] + H[4]; + b = "0x" + H[5] + H[6]; + } + r /= 255, g /= 255, b /= 255; + var cmin = Math.min(r, g, b), + cmax = Math.max(r, g, b), + delta = cmax - cmin, + h = 0, + s = 0, + l = 0; + if (delta === 0) h = 0; + else if (cmax === r) h = ((g - b) / delta) % 6; + else if (cmax === g) h = (b - r) / delta + 2; + else h = (r - g) / delta + 4; + h = Math.round(h * 60); + if (h < 0) h += 360; + l = (cmax + cmin) / 2; + s = delta === 0 + ? 0 + : delta / (1 - Math.abs(2 * l - 1)); + s = +(s * 100).toFixed(1); + l = +(l * 100).toFixed(1); + + return [Math.round(h), Math.round(s), Math.round(l)]; +} + +export const canonicalizeHex = (hex: string) => { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d")!; + + ctx.fillStyle = hex; + hex = ctx.fillStyle; + canvas.remove(); + + return hex; +}; + +export const stringToHex = (str: string) => { + let hex = ""; + for ( + let i = 0; + i < str.length; + i++ + ) { + const charCode = str.charCodeAt(i); + const hexValue = charCode.toString(16); + hex += hexValue.padStart(2, "0"); + } + return hex; +}; + +export const hexToString = (hex: string) => { + let str = ""; + for (let i = 0; i < hex.length; i += 2) { + const hexValue = hex.substr(i, 2); + const decimalValue = parseInt(hexValue, 16); + str += String.fromCharCode(decimalValue); + } + return str; +}; + +export function getHex(str: string): string { + const color = Object.assign( + document.createElement("canvas").getContext("2d") as {}, + { fillStyle: str } + ).fillStyle; + if (color.includes("rgba(")) { + return getHex(String([...color.split(",").slice(0, 3), ")"]).replace(",)", ")").replace("a", "")); + } else { + return color; + } +} + +export function getFontOnBg(bgColor: string) { + var color = (bgColor.charAt(0) === "#") ? bgColor.substring(1, 7) : bgColor; + var r = parseInt(color.substring(0, 2), 16); + var g = parseInt(color.substring(2, 4), 16); + var b = parseInt(color.substring(4, 6), 16); + return (((r * 0.299) + (g * 0.587) + (b * 0.114)) > 186) ? + "#000000" : "#ffffff"; +} + +export function $e(funcArray: Array<(...vars: any) => void>, ...vars: any[]) { + funcArray.forEach(e => e(vars)); +} + +export function hslToHex(h: number, s: number, l: number) { + h /= 360; + s /= 100; + l /= 100; + let r: any, g: any, b: any; + if (s === 0) { + r = g = b = l; // achromatic + } else { + const hue2rgb = (p: number, q: number, t: number) => { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + }; + const q = l < 0.5 ? l * (1 + s) : l + s - l * s; + const p = 2 * l - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + const toHex = (x: number) => { + const hex = Math.round(x * 255).toString(16); + return hex.length === 1 ? "0" + hex : hex; + }; + return `#${toHex(r)}${toHex(g)}${toHex(b)}`; +} + +export function rgbToHex(r: number, g: number, b: number) { + const toHex = (x: number) => { + const hex = Math.round(x * 255).toString(16); + return hex.length === 1 ? "0" + hex : hex; + }; + return `#${toHex(r)}${toHex(g)}${toHex(b)}`; +} + +export function colorToHex(color: string) { + var colorType = "hex"; + if (color.includes("hsl")) { + colorType = "hsl"; + } else if (color.includes("rgb")) { + colorType = "rgb"; + } + color = color.replaceAll(",", "").replace(/.+?\(/, "").replace(")", "").replaceAll(/[ \t]+\/[ \t]+/g, " ").replaceAll("%", "").replaceAll("/", ""); + if (colorType === "hsl") { + color = hslToHex(Number(color.split(" ")[0]), Number(color.split(" ")[1]), Number(color.split(" ")[2])); + } + if (colorType === "rgb") { + color = rgbToHex(Number(color.split(" ")[0]), Number(color.split(" ")[1]), Number(color.split(" ")[2])); + } + return color.replace("#", ""); +} diff --git a/src/suncordplugins/godMode/index.ts b/src/suncordplugins/godMode/index.ts new file mode 100644 index 00000000..163341bd --- /dev/null +++ b/src/suncordplugins/godMode/index.ts @@ -0,0 +1,33 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2022 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import { Devs } from "@utils/constants"; +import definePlugin from "@utils/types"; +import { PermissionStore } from "@webpack/common"; + +export default definePlugin({ + name: "GodMode", + description: "Get all permissions (client-side).", + authors: [Devs.Tolgchu], + + start: () => { + ["can", "canAccessMemberSafetyPage", "canAccessGuildSettings", "canBasicChannel", "canImpersonateRole", "canManageUser", "canWithPartialContext", "getGuildVersion", "getChannelsVersion", "getChannelPermissions", "getHighestRole", "initialize", "constructor", "isRoleHigher"].forEach(a => PermissionStore.__proto__[a] = () => !0); + }, + + stop: () => { } +}); diff --git a/src/suncordplugins/repeatMessage/index.tsx b/src/suncordplugins/repeatMessage/index.tsx new file mode 100644 index 00000000..63330c7f --- /dev/null +++ b/src/suncordplugins/repeatMessage/index.tsx @@ -0,0 +1,127 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2023 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; +import { addButton, removeButton } from "@api/MessagePopover"; +import { classNameFactory } from "@api/Styles"; +import { Devs } from "@utils/constants"; +import { sendMessage } from "@utils/discord"; +import { classes } from "@utils/misc"; +import definePlugin from "@utils/types"; +import { ChannelStore, Menu } from "@webpack/common"; +import { Message } from "discord-types/general"; + +function RepeatMessageIcon({ className }: { className?: string; }) { + return ( + + + + ); +} + +let shift = false; + +function repeatMessage(channelId: string, id: string, content: string, stickers: any[]) { + sendMessage(channelId, { + content + }, true, { + allowedMentions: { + parse: [], + replied_user: false + }, + messageReference: shift ? { + channel_id: channelId, + message_id: id + } : undefined, + stickerIds: stickers.map(s => s.id) + }); +} + +const messageCtxPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => { + if (!message.content && message.stickerItems.length === 0) return; + + const group = findGroupChildrenByChildId("copy-text", children); + if (!group) return; + + group.splice(group.findIndex(c => c?.props?.id === "reply") + 1, 0, ( + repeatMessage(message.channel_id, message.id, message.content, message.stickerItems)} + /> + )); +}; + +function setTitle(title: string) { + const contextMenuOption = document.querySelector("#message-vc-repeat .label__563c3"); + + if (contextMenuOption) contextMenuOption.innerHTML = title; +} + +const keyupListener = (event: KeyboardEvent) => { + if (event.key === "Shift") { + shift = false; + + setTitle("Repeat"); + } +}; + +const keydownListener = (event: KeyboardEvent) => { + if (event.key === "Shift") { + shift = true; + + setTitle("Repeat and Reply"); + } +}; + +export default definePlugin({ + name: "RepeatMessage", + description: "Allows you to repeat messages quickly. If you hold shift while clicking the Repeat option, it will reply to the message.", + authors: [Devs.Tolgchu], + contextMenus: { + "message": messageCtxPatch + }, + start() { + addButton("vc-repeat", message => { + if (!message.content && message.stickerItems.length === 0) return null; + + return { + label: "Repeat (Click) / Repeat and Reply (Shift + Click)", + icon: RepeatMessageIcon, + message, + channel: ChannelStore.getChannel(message.channel_id), + onClick: async () => repeatMessage(message.channel_id, message.id, message.content, message.stickerItems) + }; + }); + + document.addEventListener("keyup", keyupListener); + document.addEventListener("keydown", keydownListener); + }, + stop() { + removeButton("vc-repeat"); + + document.removeEventListener("keyup", keyupListener); + document.removeEventListener("keydown", keydownListener); + }, +}); diff --git a/src/suncordplugins/runInConsole/index.tsx b/src/suncordplugins/runInConsole/index.tsx new file mode 100644 index 00000000..62fbebb7 --- /dev/null +++ b/src/suncordplugins/runInConsole/index.tsx @@ -0,0 +1,158 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2023 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import { classNameFactory, disableStyle, enableStyle } from "@api/Styles"; +import { Devs } from "@utils/constants"; +import { Logger } from "@utils/Logger"; +import { classes } from "@utils/misc"; +import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal"; +import definePlugin from "@utils/types"; +import { Button, Forms, showToast, Toasts, useState } from "@webpack/common"; + +import style from "./style.css?managed"; + +function runCode(code: string) { + try { + const output = Function(`return () => {${code}}`)()(); + + showToast(`${output}`, Toasts.Type.SUCCESS); + } catch (e) { + new Logger("Run in Console").error(e); + + showToast(`${e}`, Toasts.Type.FAILURE); + } +} + +const cl = classNameFactory("vc-ric-"); + +function EditCodeModal({ rootProps, close, value }: { rootProps: ModalProps, close(): void; value: string; }) { + const [code, setCode] = useState(value); + + return ( + + + + Edit Code & Run + + + + + + +