From d18e1b24156dc0c2ce53e392a79d54f8fb430a26 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sat, 1 Jun 2024 15:34:40 -0400 Subject: [PATCH] Fixes --- .../allowedMentions/AllowedMentions.css | 5 - .../allowedMentions/AllowedMentions.tsx | 382 ----- src/equicordplugins/allowedMentions/index.tsx | 274 ---- .../betterShopPreview/index.tsx | 6 +- src/equicordplugins/deadMembers/index.tsx | 62 - .../components/AutoColorwaySelector.tsx | 74 - .../components/ColorPicker.tsx | 91 -- .../ColorwayCreatorSettingsModal.tsx | 70 - .../components/ColorwaysButton.tsx | 64 - .../components/ConflictingColorsModal.tsx | 318 ---- .../components/CreatorModal.tsx | 348 ----- .../discordColorways/components/Icons.tsx | 146 -- .../discordColorways/components/InfoModal.tsx | 301 ---- .../components/InputColorwayIdModal.tsx | 49 - .../components/SaveColorwayModal.tsx | 207 --- .../discordColorways/components/Selector.tsx | 839 ---------- .../components/SettingsTabs/OnDemandPage.tsx | 84 - .../components/SettingsTabs/SettingsPage.tsx | 184 --- .../components/SettingsTabs/SourceManager.tsx | 387 ----- .../components/SettingsTabs/Store.tsx | 149 -- .../discordColorways/components/Spinner.tsx | 19 - .../components/ThemePreview.tsx | 150 -- .../discordColorways/constants.ts | 313 ---- src/equicordplugins/discordColorways/css.ts | 1001 ------------ .../discordColorways/index.tsx | 426 ----- .../discordColorways/style.css | 1379 ----------------- src/equicordplugins/discordColorways/types.ts | 65 - src/equicordplugins/discordColorways/utils.ts | 150 -- src/equicordplugins/encryptcord/index.tsx | 457 ------ src/equicordplugins/encryptcord/rsa-utils.tsx | 121 -- .../gifCollections/CollectionManager.ts | 111 -- .../gifCollections/constants.ts | 21 - src/equicordplugins/gifCollections/index.tsx | 352 ----- src/equicordplugins/gifCollections/types.ts | 44 - .../gifCollections/utils/cleanUrl.ts | 23 - .../gifCollections/utils/getFormat.ts | 27 - .../gifCollections/utils/getGif.ts | 123 -- .../gifCollections/utils/getUrlExtension.ts | 23 - .../gifCollections/utils/isAudio.ts | 27 - .../gifCollections/utils/settingsUtils.ts | 131 -- .../gifCollections/utils/uuidv4.ts | 29 - src/equicordplugins/searchFix/index.tsx | 2 +- src/equicordplugins/themeLibrary/index.ts | 6 +- 43 files changed, 6 insertions(+), 9034 deletions(-) delete mode 100644 src/equicordplugins/allowedMentions/AllowedMentions.css delete mode 100644 src/equicordplugins/allowedMentions/AllowedMentions.tsx delete mode 100644 src/equicordplugins/allowedMentions/index.tsx delete mode 100644 src/equicordplugins/deadMembers/index.tsx delete mode 100644 src/equicordplugins/discordColorways/components/AutoColorwaySelector.tsx delete mode 100644 src/equicordplugins/discordColorways/components/ColorPicker.tsx delete mode 100644 src/equicordplugins/discordColorways/components/ColorwayCreatorSettingsModal.tsx delete mode 100644 src/equicordplugins/discordColorways/components/ColorwaysButton.tsx delete mode 100644 src/equicordplugins/discordColorways/components/ConflictingColorsModal.tsx delete mode 100644 src/equicordplugins/discordColorways/components/CreatorModal.tsx delete mode 100644 src/equicordplugins/discordColorways/components/Icons.tsx delete mode 100644 src/equicordplugins/discordColorways/components/InfoModal.tsx delete mode 100644 src/equicordplugins/discordColorways/components/InputColorwayIdModal.tsx delete mode 100644 src/equicordplugins/discordColorways/components/SaveColorwayModal.tsx delete mode 100644 src/equicordplugins/discordColorways/components/Selector.tsx delete mode 100644 src/equicordplugins/discordColorways/components/SettingsTabs/OnDemandPage.tsx delete mode 100644 src/equicordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx delete mode 100644 src/equicordplugins/discordColorways/components/SettingsTabs/SourceManager.tsx delete mode 100644 src/equicordplugins/discordColorways/components/SettingsTabs/Store.tsx delete mode 100644 src/equicordplugins/discordColorways/components/Spinner.tsx delete mode 100644 src/equicordplugins/discordColorways/components/ThemePreview.tsx delete mode 100644 src/equicordplugins/discordColorways/constants.ts delete mode 100644 src/equicordplugins/discordColorways/css.ts delete mode 100644 src/equicordplugins/discordColorways/index.tsx delete mode 100644 src/equicordplugins/discordColorways/style.css delete mode 100644 src/equicordplugins/discordColorways/types.ts delete mode 100644 src/equicordplugins/discordColorways/utils.ts delete mode 100644 src/equicordplugins/encryptcord/index.tsx delete mode 100644 src/equicordplugins/encryptcord/rsa-utils.tsx delete mode 100644 src/equicordplugins/gifCollections/CollectionManager.ts delete mode 100644 src/equicordplugins/gifCollections/constants.ts delete mode 100644 src/equicordplugins/gifCollections/index.tsx delete mode 100644 src/equicordplugins/gifCollections/types.ts delete mode 100644 src/equicordplugins/gifCollections/utils/cleanUrl.ts delete mode 100644 src/equicordplugins/gifCollections/utils/getFormat.ts delete mode 100644 src/equicordplugins/gifCollections/utils/getGif.ts delete mode 100644 src/equicordplugins/gifCollections/utils/getUrlExtension.ts delete mode 100644 src/equicordplugins/gifCollections/utils/isAudio.ts delete mode 100644 src/equicordplugins/gifCollections/utils/settingsUtils.ts delete mode 100644 src/equicordplugins/gifCollections/utils/uuidv4.ts diff --git a/src/equicordplugins/allowedMentions/AllowedMentions.css b/src/equicordplugins/allowedMentions/AllowedMentions.css deleted file mode 100644 index d835a534f..000000000 --- a/src/equicordplugins/allowedMentions/AllowedMentions.css +++ /dev/null @@ -1,5 +0,0 @@ -.vc-allowed-mentions-popout-menu { - height: 250px; - width: 200px; - text-overflow: ellipsis; -} diff --git a/src/equicordplugins/allowedMentions/AllowedMentions.tsx b/src/equicordplugins/allowedMentions/AllowedMentions.tsx deleted file mode 100644 index 2ce2a4535..000000000 --- a/src/equicordplugins/allowedMentions/AllowedMentions.tsx +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import "./AllowedMentions.css"; - -import { Flex } from "@components/Flex"; -import { isNonNullish } from "@utils/guards"; -import { useForceUpdater } from "@utils/react"; -import { findByPropsLazy } from "@webpack"; -import { Clickable, Forms, GuildMemberStore, GuildStore, Menu, Popout as DiscordPopout, RelationshipStore, TextInput, useEffect, UserStore, useState } from "@webpack/common"; -import { Channel } from "discord-types/general"; -import { CSSProperties, ReactNode } from "react"; - -export type AllowedMentionsParsables = "everyone" | "users" | "roles"; - -export interface AllowedMentions { - parse: Set; - users?: Set; - roles?: Set; - meta: { - hasEveryone: boolean; - userIds: Set; - roleIds: Set; - tooManyUsers: boolean; - tooManyRoles: boolean; - }; -} - -export interface AllowedMentionsProps { - mentions: AllowedMentions, - channel: Channel; - trailingSeparator?: boolean; -} - -const replyClasses = findByPropsLazy("replyBar", "replyLabel", "separator"); -export const AllowedMentionsStore = { - store: new Map(), - callbacks: new Map void>, - get(channelId: string) { - return this.store.get(channelId); - }, - set(channelId: string, mentions: AllowedMentions, dispatch: boolean) { - this.store.set(channelId, mentions); - dispatch && this.callbacks.get(channelId)?.(mentions); - }, - delete(channelId: string) { - return this.store.delete(channelId); - }, - clear() { - return this.store.clear(); - }, - subscribe(channelId: string, callback: (mentions: AllowedMentions) => void) { - return this.callbacks.set(channelId, callback); - }, - unsubscribe(channelId: string) { - return this.callbacks.delete(channelId); - } -}; - -function getDisplayableUserNameParts(userId: string, guildId: string | null) { - // @ts-ignore discord-types doesn't have globalName - const { globalName, username } = UserStore.getUser(userId) ?? {}; - const nickname = guildId ? GuildMemberStore.getNick(guildId, userId) : RelationshipStore.getNickname(userId); - - return [nickname, globalName as string, username]; -} - -function getDisplayableUserName(userId: string, guildId: string | null) { - const [nickname, globalName, username] = getDisplayableUserNameParts(userId, guildId); - - // Displayed name priority - // Guild/Friend Nickname > Global Name > Username - - // User id if not cached in any stores - return nickname ?? globalName ?? username ?? userId; -} - -function getDisplayableRoleName(roleId: string, guildId: string | null) { - // You *can* mention roles in DMs but is it really worth adding the UI for - // it in DMs - const role = guildId ? Object.values(GuildStore.getGuild(guildId).roles).find(r => r.id === roleId)?.name : undefined; - - // Role id if not cached or not from current guild - return role ?? roleId; -} - -function fuzzySearch(searchQuery: string, searchString: string) { - let searchIndex = 0; - let score = 0; - - for (let i = 0; i < searchString.length; i++) { - if (searchString[i] === searchQuery[searchIndex]) { - score++; - searchIndex++; - } else { - score--; - } - - if (searchIndex === searchQuery.length) { - return score; - } - } - - return null; -} - -function AtIcon({ width, height }: { width: number, height: number; }) { - return - - ; -} - -function Title({ children, pointer, style }: { children: ReactNode; pointer?: boolean; style?: CSSProperties; }) { - return {children}; -} - -function TitleSwitch({ state, setState, children }: { state: boolean, setState: (value: boolean) => void; children: ReactNode; }) { - return setState(!state)}> - - {children} - - ; -} - -function Separator() { - return
; -} - -function Popout({ - title, - shouldShow, - setShouldShow, - update, - fuzzy, - ids, - rawIds, - guildId, - getDisplayableName, - all, - setAll, -}: { - title: string, - shouldShow: boolean, - setShouldShow: (value: boolean) => void, - update: () => void, - fuzzy: (search: string, id: string) => number | null, - ids: Set, - rawIds: Set, - guildId: string | null, - getDisplayableName: (userId: string, guildId: string | null) => string | undefined, - all: boolean, - setAll: (value: boolean) => void, -}) { - const [search, setSearch] = useState(undefined as undefined | string); - - return setShouldShow(false)} - renderPopout={() => { - return setShouldShow(false)} - className="vc-allowed-mentions-popout-menu" - > - { - // If all are selected, deselect them, - // otherwise select the remaining ones. - if (ids.size === rawIds.size) { - ids.clear(); - setAll(false); - update(); - } else { - rawIds.forEach(id => ids.add(id)); - setAll(true); - update(); - } - }} - /> - - { - return setSearch(value.trim())} - style={{ margin: "2px 0", padding: "6px 8px" }} - onKeyDown={e => { - if (e.key === "Escape") { - setSearch(undefined); - } else if (e.key === "ArrowLeft" || e.key === "ArrowRight") { - // Some random event listener is blocking - // left & right arrow keys so you can't - // navigate the text with arrow keys unless - // you do e.stopPropogation - e.stopPropagation(); - } else if (e.key === "ArrowUp" || e.key === "ArrowDown") { - // Pressing up/down arrow keys leads to a messy - // UI state, blurring the text input fixes it. - // (kinda) - e.currentTarget.blur(); - } - }} - />; - }} - /> - {(isNonNullish(search) ? - Array.from(rawIds).map(id => ({ - score: fuzzy(search, id), - name: getDisplayableName(id, guildId), - id: id - }) - ).filter(o => isNonNullish(o.score)) - .sort((a, b) => b.score! - a.score!) - : Array.from(rawIds).map(id => ({ - score: 0, - name: getDisplayableName(id, guildId), - id: id - })) - ) - .map(object => { - return { - all || ids.has(object.id) ? ids.delete(object.id) : ids.add(object.id); - setAll(ids.size === rawIds.size); - update(); - }} - />; - })} - ; - }} - > - { - (_, { isShown }) => { - return setShouldShow(!isShown)}> - {title} - ; - } - } - ; -} - -export function AllowedMentionsBar({ mentions, channel, trailingSeparator }: AllowedMentionsProps) { - const [users, setUsers] = useState(new Set(mentions.users)); - const [roles, setRoles] = useState(new Set(mentions.roles)); - const [everyone, setEveryone] = useState(mentions.parse.has("everyone")); - const [allUsers, setAllUsers] = useState(users.size === mentions.meta.userIds.size); - const [allRoles, setAllRoles] = useState(roles.size === mentions.meta.roleIds.size); - - useEffect(() => { - AllowedMentionsStore.subscribe( - channel.id, - mentions => { - allUsers && mentions.users && setUsers(new Set(mentions.users)); - allRoles && mentions.roles && setRoles(new Set(mentions.roles)); - } - ); - - return () => { AllowedMentionsStore.unsubscribe(channel.id); }; - }); - - useEffect(() => { - AllowedMentionsStore.set( - channel.id, - { - parse: new Set( - [ - everyone && "everyone", - allUsers && "users", - allRoles && "roles" - ].filter(v => v) as AllowedMentionsParsables[] - ), - users: allUsers || users.size === 0 ? undefined : users, - roles: allRoles || roles.size === 0 ? undefined : roles, - meta: { - ...mentions.meta, - tooManyUsers: users.size > 100, - tooManyRoles: roles.size > 100, - } - }, - false - ); - }, [ - mentions, - everyone, - allUsers, - allRoles, - users, - roles, - ]); - - const [shouldShowUsersPopout, setShouldShowUsersPopout] = useState(false); - const [shouldShowRolesPopout, setShouldShowRolesPopout] = useState(false); - const update = useForceUpdater(); - - const displayEveryone = mentions.meta.hasEveryone; - const displayUserIds = mentions.meta.userIds.size > 0; - const displayRoleIds = mentions.meta.roleIds.size > 0; - - return - {displayEveryone && <> - - - everyone / - - here - - } - {displayUserIds && <> - {displayEveryone && } - { - const samples = getDisplayableUserNameParts(userId, channel.guild_id) - .filter(isNonNullish) - .map(name => fuzzySearch(search, name)) - .filter(isNonNullish) as number[]; - return samples.length > 0 ? Math.max(...samples) : null; - }} - ids={users} - rawIds={mentions.meta.userIds} - guildId={channel.guild_id} - getDisplayableName={getDisplayableUserName} - all={allUsers} - setAll={setAllUsers} - /> - } - {displayRoleIds && <> - {(displayEveryone || displayUserIds) && } - fuzzySearch(search, getDisplayableRoleName(roleId, channel.guild_id).toLowerCase())} - ids={roles} - rawIds={mentions.meta.roleIds} - guildId={channel.guild_id} - getDisplayableName={getDisplayableRoleName} - all={allRoles} - setAll={setAllRoles} - /> - } - {trailingSeparator && (displayEveryone || displayUserIds || displayRoleIds) && } - ; -} diff --git a/src/equicordplugins/allowedMentions/index.tsx b/src/equicordplugins/allowedMentions/index.tsx deleted file mode 100644 index 95a616dd2..000000000 --- a/src/equicordplugins/allowedMentions/index.tsx +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { addPreSendListener, MessageExtra, removePreSendListener } from "@api/MessageEvents"; -import { definePluginSettings } from "@api/Settings"; -import { Flex } from "@components/Flex"; -import { Devs } from "@utils/constants"; -import { isNonNullish } from "@utils/guards"; -import definePlugin, { OptionType } from "@utils/types"; -import { Alerts, GuildStore, PermissionsBits, PermissionStore } from "@webpack/common"; -import { Channel } from "discord-types/general"; - -import { AllowedMentions, AllowedMentionsBar, AllowedMentionsProps, AllowedMentionsStore as store } from "./AllowedMentions"; - -export default definePlugin({ - name: "AllowedMentions", - authors: [Devs.arHSM, Devs.amia], - description: "Fine grained control over whom to ping when sending a message.", - dependencies: ["MessageEventsAPI"], - settings: definePluginSettings({ - pingEveryone: { - type: OptionType.BOOLEAN, - description: "Mention everyone by default", - default: false, - }, - pingAllUsers: { - type: OptionType.BOOLEAN, - description: "Mention all users by default", - default: true, - }, - pingAllRoles: { - type: OptionType.BOOLEAN, - description: "Mention all roles by default", - default: true, - } - }), - patches: [ - { - find: ".AnalyticEvents.APPLICATION_COMMAND_VALIDATION_FAILED,", - replacement: [ - // Pass type prop to slate wrapper - { - match: /className:\i\(\i,\i.slateContainer\),children:\(0,\i.jsx\)\(\i.\i,{/, - replace: "$& type: arguments[0].type," - } - ] - }, - { - find: '"chat input type must be set");', - replacement: [ - // Set allowedMentions & populate attachments store - { - match: /"chat input type must be set"\);/, - replace: "$& $self.allowedSlateTypes.includes(arguments[0].type?.analyticsName) && $self.setAllowedMentions(arguments[0]);" - }, - // Add the hasConnectedBar class when AllowedMentionsBar is visible - { - match: /.hasConnectedBar]:\i/, - replace: '$& || $self.getAllowedMentions(arguments[0].channel.id, arguments[0].type?.analyticsName === "edit"),' - }, - // Pass mentions to attached bars component - // Would do a simple isEdit but the component is memo'd - { - match: /activeCommand:\i,pendingReply:\i/, - replace: '$&, mentions: $self.getAllowedMentions(arguments[0].channel.id, arguments[0].type?.analyticsName === "edit"),' - }, - ] - }, - { - find: ".stackedAttachedBar]:!", - replacement: [ - // Add AllowedMentionsBar when not replying - // Will never render if above patch fails - { - match: /(?<=pendingReply:\i}=(\i),.+?)null!=(\i)&&(\i).push\(\(0,\i.jsx\)\(\i.\i,{reply:\i,/, - replace: "null == $2 && null != $1.mentions && $3.push($self.AllowedMentionsBar({ mentions: $1.mentions, channel: $1.channel })), $&" - } - ] - }, - { - find: ".Messages.REPLYING_TO.format({", - replacement: [ - // Add AllowedMentionsBar to reply bar when replying - { - match: /(?<="div",\{className:\i.actions,children:\[)(?=\i&&)/, - replace: "null != $self.getAllowedMentions(arguments[0].reply.channel.id, false) && $self.AllowedMentionsBarInner({ mentions: $self.getAllowedMentions(arguments[0].reply.channel.id, false), channel: arguments[0].reply.channel, trailingSeparator: true }),", - } - ] - }, - { - find: ".Messages.EVERYONE_POPOUT_BODY", - replacement: [ - // Remove the warning popout for large server when @everyone mention is off - { - match: /(?<=shouldShowEveryoneGuard\(\i,(\i)\))/, - replace: "|| $self.skipEveryoneContentWarningPopout($1.id)" - } - ] - }, - { - find: '"?use_nested_fields=true"', - replacement: [ - // Patch sending allowed_mentions for forum creation - { - match: /(?<=.Endpoints.CHANNEL_THREADS\((\i.id)\)\+"\?use_nested_fields=true".+?message:\{)/, - replace: "allowed_mentions: $self.patchForumAllowedMentions($1)," - } - ] - }, - { - find: ".ComponentActions.FOCUS_COMPOSER_TITLE,", - replacement: [ - // Clear entry on cancelling new forum post - { - match: /.trackForumNewPostCleared\)\(\{guildId:\i.guild_id,channelId:(\i.id)\}\)/, - replace: "$&; $self.onForumCancel($1);" - }, - // Fail creating forum if tooManyUsers or tooManyRoles - { - match: /applyChatRestrictions\)\(\{.+?channel:(\i)\}\);if\(!\i/, - replace: "$& && !$self.validateForum($1.id)" - } - ] - } - ], - allowedSlateTypes: ["normal", "sidebar", "thread_creation", "create_forum_post"], - getAllowedMentions(channelId: string, shouldDelete?: boolean) { - const mentions = store.get(channelId); - - if (shouldDelete) { store.delete(channelId); } - - return mentions; - }, - setAllowedMentions({ richValue, channel: { id: channelId, guild_id: guildId } }: { richValue: any, channel: Channel; }) { - const previous = store.get(channelId); - - const canMentionEveryone = isNonNullish(guildId) ? PermissionStore.can(PermissionsBits.MENTION_EVERYONE, GuildStore.getGuild(guildId)) as boolean : true; - - const mentions: AllowedMentions = { - parse: new Set(), - users: previous?.users ?? new Set(), - roles: previous?.roles ?? new Set(), - meta: { - hasEveryone: false, - userIds: new Set(), - roleIds: new Set(), - tooManyUsers: false, - tooManyRoles: false, - } - }; - - if (!isNonNullish(richValue[0]?.children)) { - return undefined; - } - - // Discord renders the slate wrapper twice - // 1. unparsed raw text - // 2. parsed text (we need this) - // We skip setting allowed mentions for unparsed text cause there can be potential unparsed mentions - if (richValue[0]?.children.length === 1 && typeof richValue[0]?.children[0].text === "string") { - // This is the case where the input is empty (no potential unparsed mentions) - if (richValue[0]?.children[0].text === "") { store.delete(channelId); } - - return; - } - - for (const node of richValue[0].children) { - switch (node.type) { - case "userMention": - mentions.meta.userIds.add(node.userId); - break; - case "roleMention": - mentions.meta.roleIds.add(node.roleId); - break; - case "textMention": - if (node.name === "@everyone" || node.name === "@here") { - mentions.meta.hasEveryone = canMentionEveryone; - - if (canMentionEveryone && (previous?.parse.has?.("everyone") ?? this.settings.store.pingEveryone)) { - mentions.parse.add("everyone"); - } - } - break; - } - } - - if (this.settings.store.pingAllUsers) { mentions.users = mentions.meta.userIds; } - if (this.settings.store.pingAllRoles) { mentions.roles = mentions.meta.roleIds; } - - if ( - !mentions.meta.hasEveryone - && mentions.meta.userIds.size === 0 - && mentions.meta.roleIds.size === 0 - ) { - store.delete(channelId); - } else { - store.set(channelId, mentions, true); - } - }, - skipEveryoneContentWarningPopout(channelId: string) { - const mentions = store.get(channelId); - return isNonNullish(mentions) && !mentions.parse.has("everyone"); - }, - tooManyAlert(tooManyUsers: boolean, tooManyRoles: boolean) { - const type = [ - tooManyUsers && "users", - tooManyRoles && "roles" - ].filter(x => x).join(" and "); - - Alerts.show({ - title: "Uh oh!", - body: `You've selected too many individual ${type} to mention!\nYou may only select all or up to 100 items in each category.` - }); - }, - validateForum(channelId: string) { - const mentions = this.getAllowedMentions(channelId, true); - if (!isNonNullish(mentions)) return true; - - if (mentions.meta.tooManyUsers || mentions.meta.tooManyRoles) { - this.tooManyAlert(mentions.meta.tooManyUsers, mentions.meta.tooManyRoles); - return false; - } - - return true; - }, - patchSendAllowedMentions(channelId: string, extra: MessageExtra) { - const mentions = this.getAllowedMentions(channelId, true); - if (!isNonNullish(mentions)) return; - - if (mentions.meta.tooManyUsers || mentions.meta.tooManyRoles) { - this.tooManyAlert(mentions.meta.tooManyUsers, mentions.meta.tooManyRoles); - return { cancel: true }; - } - - extra.replyOptions.allowedMentions = { - parse: Array.from(mentions.parse), - users: mentions.users ? Array.from(mentions.users) : undefined, - roles: mentions.roles ? Array.from(mentions.roles) : undefined, - // Don't override this for send! Discord already has a UI for this - repliedUser: extra.replyOptions.allowedMentions?.repliedUser ?? false, - }; - }, - patchForumAllowedMentions(channelId: string) { - const mentions = this.getAllowedMentions(channelId, true); - if (!isNonNullish(mentions)) return; - - return { - parse: Array.from(mentions.parse), - users: mentions.users ? Array.from(mentions.users) : undefined, - roles: mentions.roles ? Array.from(mentions.roles) : undefined, - }; - }, - onForumCancel(channelId: string) { - store.delete(channelId); - }, - AllowedMentionsBar(props: AllowedMentionsProps) { - return - {} - ; - }, - AllowedMentionsBarInner(props: AllowedMentionsProps) { - return ; - }, - start() { - this.preSend = addPreSendListener((channelId, _, extra) => this.patchSendAllowedMentions(channelId, extra)); - }, - stop() { - removePreSendListener(this.preSend); - store.clear(); - }, -}); diff --git a/src/equicordplugins/betterShopPreview/index.tsx b/src/equicordplugins/betterShopPreview/index.tsx index 57ca121b3..08b19e942 100644 --- a/src/equicordplugins/betterShopPreview/index.tsx +++ b/src/equicordplugins/betterShopPreview/index.tsx @@ -67,10 +67,10 @@ export default definePlugin({ settings, patches: [ { - find: "default.Messages.COLLECTIBLES_SHOP})]})", + find: "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()]}" + match: /(children:\i.default.Messages.COLLECTIBLES_SHOP)}/, + replace: "$&,$self.PreviewToggle()" }] } ], diff --git a/src/equicordplugins/deadMembers/index.tsx b/src/equicordplugins/deadMembers/index.tsx deleted file mode 100644 index 01e7bd7b4..000000000 --- a/src/equicordplugins/deadMembers/index.tsx +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { Devs } from "@utils/constants"; -import definePlugin from "@utils/types"; -import { ChannelStore, GuildMemberStore, useStateFromStores } from "@webpack/common"; - -export default definePlugin({ - name: "DeadMembers", - description: "Shows when the sender of a message has left the guild", - authors: [Devs.Kyuuhachi], - - patches: [ - { - find: "UsernameDecorationTypes:function()", - replacement: { - match: /(\i)=\{className:\i.username,style:.*?onContextMenu:\i,children:.*?\};/, - replace: "$&$1.children=$self.wrapMessageAuthor(arguments[0],$1.children);" - } - }, - { - find: "Messages.FORUM_POST_AUTHOR_A11Y_LABEL", - replacement: { - match: /(?<=\}=(\i),\{(user:\i,author:\i)\}=.{0,400}?\(\i\.Fragment,{children:)\i(?=}\),)/, - replace: "$self.wrapForumAuthor({...$1,$2},$&)" - } - }, - ], - - wrapMessageAuthor({ message }, text) { - const channel = ChannelStore.getChannel(message.channel_id); - return message.webhookId - ? text - : ; - }, - - wrapForumAuthor({ channel, user }, text) { - return !user - ? text - : ; - }, -}); - - -function DeadIndicator({ channel, userId, text }) { - const isMember = useStateFromStores( - [GuildMemberStore], - () => GuildMemberStore.isMember(channel?.guild_id, userId), - ); - return channel?.guild_id && !isMember ? {text} : text; -} diff --git a/src/equicordplugins/discordColorways/components/AutoColorwaySelector.tsx b/src/equicordplugins/discordColorways/components/AutoColorwaySelector.tsx deleted file mode 100644 index 6ebbdace0..000000000 --- a/src/equicordplugins/discordColorways/components/AutoColorwaySelector.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { DataStore } from "@api/index"; -import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot } from "@utils/modal"; -import { findByProps } from "@webpack"; -import { Button, Forms, Text, useState } from "@webpack/common"; - -import { getAutoPresets } from "../css"; - -export default function ({ modalProps, onChange, autoColorwayId = "" }: { modalProps: ModalProps, onChange: (autoPresetId: string) => void, autoColorwayId: string; }) { - const [autoId, setAutoId] = useState(autoColorwayId); - const { radioBar, item: radioBarItem, itemFilled: radioBarItemFilled, radioPositionLeft } = findByProps("radioBar"); - return - - - Auto Preset Settings - - - -
- About the Auto Colorway - The auto colorway allows you to use your system's accent color in combination with a selection of presets that will fully utilize it. -
-
- Presets: - {Object.values(getAutoPresets()).map(autoPreset => { - return
-
{ - setAutoId(autoPreset.id); - }}> - - {autoPreset.name} -
-
; - })} -
-
- - - - -
; -} diff --git a/src/equicordplugins/discordColorways/components/ColorPicker.tsx b/src/equicordplugins/discordColorways/components/ColorPicker.tsx deleted file mode 100644 index d4ae6adc9..000000000 --- a/src/equicordplugins/discordColorways/components/ColorPicker.tsx +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { Flex } from "@components/Flex"; -import { CopyIcon } from "@components/Icons"; -import { - ModalProps, - ModalRoot, -} from "@utils/modal"; -import { - Button, - Clipboard, - ScrollerThin, - TextInput, - Toasts, - useState, -} from "@webpack/common"; - -import { mainColors } from "../constants"; -import { colorVariables } from "../css"; -import { getHex } from "../utils"; - -export default function ({ modalProps }: { modalProps: ModalProps; }) { - const [ColorVars, setColorVars] = useState(colorVariables); - const [collapsedSettings, setCollapsedSettings] = useState(true); - let results: string[]; - function searchToolboxItems(e: string) { - results = []; - colorVariables.find((colorVariable: string) => { - if (colorVariable.toLowerCase().includes(e.toLowerCase())) { - results.push(colorVariable); - } - }); - setColorVars(results); - } - - return - - { - searchToolboxItems(e); - if (e) { - setCollapsedSettings(false); - } else { - setCollapsedSettings(true); - } - }} - /> - - - - {ColorVars.map((colorVariable: string) =>
{ - Clipboard.copy(getHex(getComputedStyle(document.body).getPropertyValue("--" + colorVariable))); - Toasts.show({ message: "Color " + colorVariable + " copied to clipboard", id: "toolbox-color-var-copied", type: 1 }); - }} style={{ "--brand-experiment": `var(--${colorVariable})` } as React.CSSProperties}> - {`Copy ${colorVariable}`} -
)} -
- - {mainColors.map(mainColor =>
- { - Clipboard.copy(getHex(getComputedStyle(document.body).getPropertyValue(mainColor.var))); - Toasts.show({ message: `${mainColor.title} color copied to clipboard`, id: `toolbox-${mainColor.name}-color-copied`, type: 1 }); - }} width={20} height={20} className="colorwayToolbox-listItemSVG" /> - {`Copy ${mainColor.title} Color`} -
- )} -
-
; -} diff --git a/src/equicordplugins/discordColorways/components/ColorwayCreatorSettingsModal.tsx b/src/equicordplugins/discordColorways/components/ColorwayCreatorSettingsModal.tsx deleted file mode 100644 index c969b01c2..000000000 --- a/src/equicordplugins/discordColorways/components/ColorwayCreatorSettingsModal.tsx +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot } from "@utils/modal"; -import { findByProps } from "@webpack"; -import { Button, Forms, ScrollerThin, Switch, Text, useState } from "@webpack/common"; - -import { getPreset } from "../css"; - -export default function ({ modalProps, onSettings, presetId, hasTintedText, hasDiscordSaturation }: { modalProps: ModalProps, presetId: string, hasTintedText: boolean, hasDiscordSaturation: boolean, onSettings: ({ presetId, tintedText, discordSaturation }: { presetId: string, tintedText: boolean, discordSaturation: boolean; }) => void; }) { - const [tintedText, setTintedText] = useState(hasTintedText); - const [discordSaturation, setDiscordSaturation] = useState(hasDiscordSaturation); - const [preset, setPreset] = useState(presetId); - const { radioBar, item: radioBarItem, itemFilled: radioBarItemFilled, radioPositionLeft } = findByProps("radioBar"); - return - Creator Settings - - - Presets: - - - {Object.values(getPreset()).map(pre => { - return
-
{ - setPreset(pre.id); - }}> - - {pre.name} -
-
; - })} -
- Use colored text - Use Discord's saturation -
- - - - -
; -} diff --git a/src/equicordplugins/discordColorways/components/ColorwaysButton.tsx b/src/equicordplugins/discordColorways/components/ColorwaysButton.tsx deleted file mode 100644 index cc8923f8d..000000000 --- a/src/equicordplugins/discordColorways/components/ColorwaysButton.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import * as DataStore from "@api/DataStore"; -import { openModal } from "@utils/modal"; -import { FluxDispatcher, Text, Tooltip, useEffect, useState } from "@webpack/common"; -import { FluxEvents } from "@webpack/types"; - -import { getAutoPresets } from "../css"; -import { ColorwayObject } from "../types"; -import { PalleteIcon } from "./Icons"; -import Selector from "./Selector"; - -export default function () { - const [activeColorway, setActiveColorway] = useState("None"); - const [visibility, setVisibility] = useState(true); - const [isThin, setIsThin] = useState(false); - const [autoPreset, setAutoPreset] = useState("hueRotation"); - useEffect(() => { - (async function () { - setVisibility(await DataStore.get("showColorwaysButton") as boolean); - setIsThin(await DataStore.get("useThinMenuButton") as boolean); - setAutoPreset(await DataStore.get("activeAutoPreset") as string); - })(); - }); - - FluxDispatcher.subscribe("COLORWAYS_UPDATE_BUTTON_HEIGHT" as FluxEvents, ({ isTall }) => { - setIsThin(isTall); - }); - - FluxDispatcher.subscribe("COLORWAYS_UPDATE_BUTTON_VISIBILITY" as FluxEvents, ({ isVisible }) => { - setVisibility(isVisible); - }); - - return - {!isThin ? <> - Colorways - {"Active Colorway: " + activeColorway} - : {"Active Colorway: " + activeColorway}} - {activeColorway === "Auto" ? {"Auto Preset: " + (getAutoPresets()[autoPreset].name || "None")} : <>} - - } position="right" tooltipContentClassName="colorwaysBtn-tooltipContent" - > - {({ onMouseEnter, onMouseLeave, onClick }) => visibility ?
-
{ - onMouseEnter(); - setActiveColorway((await DataStore.get("activeColorwayObject") as ColorwayObject).id || "None"); - setAutoPreset(await DataStore.get("activeAutoPreset") as string); - }} - onMouseLeave={onMouseLeave} - onClick={() => { - onClick(); - openModal((props: any) => ); - }} - >{isThin ? Colorways : }
-
: <>} -
; -} diff --git a/src/equicordplugins/discordColorways/components/ConflictingColorsModal.tsx b/src/equicordplugins/discordColorways/components/ConflictingColorsModal.tsx deleted file mode 100644 index 410f9aee2..000000000 --- a/src/equicordplugins/discordColorways/components/ConflictingColorsModal.tsx +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot } from "@utils/modal"; -import { Button, Forms, ScrollerThin, Text, useState } from "@webpack/common"; - -import { knownThemeVars } from "../constants"; -import { getFontOnBg, getHex } from "../utils"; - -export default function ({ - modalProps, - onFinished -}: { - modalProps: ModalProps; - onFinished: ({ accent, primary, secondary, tertiary }: { accent: string, primary: string, secondary: string, tertiary: string; }) => void; -}) { - const [accentColor, setAccentColor] = useState(getHex( - getComputedStyle( - document.body - ).getPropertyValue("--brand-experiment") - )); - const [primaryColor, setPrimaryColor] = useState(getHex( - getComputedStyle( - document.body - ).getPropertyValue("--background-primary") - )); - const [secondaryColor, setSecondaryColor] = useState(getHex( - getComputedStyle( - document.body - ).getPropertyValue("--background-secondary") - )); - const [tertiaryColor, setTertiaryColor] = useState(getHex( - getComputedStyle( - document.body - ).getPropertyValue("--background-tertiary") - )); - return - - - Conflicting Colors Found - - - - Multiple known themes have been found, select the colors you want to copy from below: - Colors to copy: -
-
Primary
-
Secondary
-
Tertiary
-
Accent
-
-
- -
- Discord -
-
setPrimaryColor( - getHex( - getComputedStyle( - document.body - ).getPropertyValue("--background-primary") - ) - )} - >Primary
-
setSecondaryColor( - getHex( - getComputedStyle( - document.body - ).getPropertyValue("--background-secondary") - ) - )} - >Secondary
-
setTertiaryColor( - getHex( - getComputedStyle( - document.body - ).getPropertyValue("--background-tertiary") - ) - )} - >Tertiary
-
setAccentColor( - getHex( - getComputedStyle( - document.body - ).getPropertyValue("--brand-experiment") - ) - )} - >Accent
-
-
- {Object.values(knownThemeVars).map((theme: any, i) => { - if (getComputedStyle(document.body).getPropertyValue(theme.variable)) { - return ( -
- {Object.keys(knownThemeVars)[i] + (theme.alt ? " (Main)" : "")} -
- {theme.primary && getComputedStyle(document.body).getPropertyValue(theme.primary).match(/^\d.*%$/) - ?
{ - setPrimaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.primary)})`)); - }} - >Primary
- : ( - theme.primary - ?
{ - setPrimaryColor(getHex(getComputedStyle(document.body).getPropertyValue(theme.primary))); - }} - >Primary
- : (theme.primaryVariables - &&
{ - setPrimaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.h)} ${!getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.s).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.s) + "%") : getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.s)} ${!getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.l).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.l) + "%") : getComputedStyle(document.body).getPropertyValue(theme.primaryVariables.l)})`)); - }} - >Primary
)) - } - {theme.secondary && getComputedStyle(document.body).getPropertyValue(theme.secondary).match(/^\d.*%$/) - ?
{ - setSecondaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.secondary)})`)); - }} - >Secondary
- : (theme.secondary - ?
{ - setSecondaryColor(getHex(getComputedStyle(document.body).getPropertyValue(theme.secondary))); - }} - >Secondary
- : (theme.secondaryVariables - &&
{ - setSecondaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.h)} ${!getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.s).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.s) + "%") : getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.s)} ${!getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.l).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.l) + "%") : getComputedStyle(document.body).getPropertyValue(theme.secondaryVariables.l)})`)); - }} - >Secondary
)) - } - {theme.tertiary && getComputedStyle(document.body).getPropertyValue(theme.tertiary).match(/^\d.*%$/) - ?
{ - setTertiaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.tertiary)})`)); - }} - >Tertiary
- : (theme.tertiary - ?
{ - setTertiaryColor(getHex(getComputedStyle(document.body).getPropertyValue(theme.tertiary))); - }} - >Tertiary
- : (theme.tertiaryVariables - &&
{ - setTertiaryColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.h)} ${!getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.s).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.s) + "%") : getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.s)} ${!getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.l).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.l) + "%") : getComputedStyle(document.body).getPropertyValue(theme.tertiaryVariables.l)})`)); - }} - >Tertiary
))} - {theme.accent && getComputedStyle(document.body).getPropertyValue(theme.accent).match(/^\d.*%$/) - ?
{ - setAccentColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.accent)})`)); - }} - >Accent
- : (theme.accent - ?
{ - setAccentColor(getHex(getComputedStyle(document.body).getPropertyValue(theme.accent))); - }} - >Accent
- : (theme.accentVariables - &&
{ - setAccentColor(getHex(`hsl(${getComputedStyle(document.body).getPropertyValue(theme.accentVariables.h)} ${!getComputedStyle(document.body).getPropertyValue(theme.accentVariables.s).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.accentVariables.s) + "%") : getComputedStyle(document.body).getPropertyValue(theme.accentVariables.s)} ${!getComputedStyle(document.body).getPropertyValue(theme.accentVariables.l).includes("%") ? (getComputedStyle(document.body).getPropertyValue(theme.accentVariables.l) + "%") : getComputedStyle(document.body).getPropertyValue(theme.accentVariables.l)})`)); - }} - >Accent
))} -
-
- ); - } - })} -
-
-
- - - -
; -} diff --git a/src/equicordplugins/discordColorways/components/CreatorModal.tsx b/src/equicordplugins/discordColorways/components/CreatorModal.tsx deleted file mode 100644 index 66de954d8..000000000 --- a/src/equicordplugins/discordColorways/components/CreatorModal.tsx +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { - ModalContent, - ModalFooter, - ModalHeader, - ModalProps, - ModalRoot, - openModal, -} from "@utils/modal"; -import { - Button, - Forms, - Slider, - Text, - TextInput, - useEffect, - UserStore, - useState, -} from "@webpack/common"; - -import { ColorPicker, versionData } from ".."; -import { knownThemeVars } from "../constants"; -import { generateCss, getPreset, gradientPresetIds, PrimarySatDiffs, pureGradientBase } from "../css"; -import { Colorway } from "../types"; -import { colorToHex, getHex, HexToHSL, hexToString } from "../utils"; -import ColorwayCreatorSettingsModal from "./ColorwayCreatorSettingsModal"; -import ConflictingColorsModal from "./ConflictingColorsModal"; -import InputColorwayIdModal from "./InputColorwayIdModal"; -import SaveColorwayModal from "./SaveColorwayModal"; -import ThemePreviewCategory from "./ThemePreview"; -export default function ({ - modalProps, - loadUIProps, - colorwayID -}: { - modalProps: ModalProps; - loadUIProps?: () => Promise; - colorwayID?: string; -}) { - const [accentColor, setAccentColor] = useState("5865f2"); - const [primaryColor, setPrimaryColor] = useState("313338"); - const [secondaryColor, setSecondaryColor] = useState("2b2d31"); - const [tertiaryColor, setTertiaryColor] = useState("1e1f22"); - const [colorwayName, setColorwayName] = useState(""); - const [tintedText, setTintedText] = useState(true); - const [discordSaturation, setDiscordSaturation] = useState(true); - const [preset, setPreset] = useState("default"); - const [presetColorArray, setPresetColorArray] = useState(["accent", "primary", "secondary", "tertiary"]); - const [mutedTextBrightness, setMutedTextBrightness] = useState(Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)); - - const colorProps = { - accent: { - get: accentColor, - set: setAccentColor, - name: "Accent" - }, - primary: { - get: primaryColor, - set: setPrimaryColor, - name: "Primary" - }, - secondary: { - get: secondaryColor, - set: setSecondaryColor, - name: "Secondary" - }, - tertiary: { - get: tertiaryColor, - set: setTertiaryColor, - name: "Tertiary" - } - }; - - useEffect(() => { - if (colorwayID) { - if (!colorwayID.includes(",")) { - throw new Error("Invalid Colorway ID"); - } else { - const setColor = [ - setAccentColor, - setPrimaryColor, - setSecondaryColor, - setTertiaryColor - ]; - colorwayID.split("|").forEach((prop: string) => { - if (prop.includes(",#")) { - prop.split(/,#/).forEach((color: string, i: number) => setColor[i](colorToHex(color))); - } - if (prop.includes("n:")) { - setColorwayName(prop.split("n:")[1]); - } - if (prop.includes("p:")) { - if (Object.values(getPreset()).map(preset => preset.id).includes(prop.split("p:")[1])) { - setPreset(prop.split("p:")[1]); - setPresetColorArray(getPreset()[prop.split("p:")[1]].colors); - } - } - }); - } - } - }); - const colorPickerProps = { - suggestedColors: [ - "#313338", - "#2b2d31", - "#1e1f22", - "#5865f2", - ], - showEyeDropper: true - }; - - return ( - - - - Create Colorway - - - - - Name: - - -
- - Colors & Values: - -
- {presetColorArray.map(presetColor => { - return {colorProps[presetColor].name}} - color={parseInt(colorProps[presetColor].get, 16)} - onChange={(color: number) => { - let hexColor = color.toString(16); - while (hexColor.length < 6) { - hexColor = "0" + hexColor; - } - colorProps[presetColor].set(hexColor); - }} - {...colorPickerProps} - />; - })} -
- - Muted Text Brightness: - -
-
openModal((props: ModalProps) => { - setPreset(presetId); - setPresetColorArray(getPreset()[presetId].colors); - setDiscordSaturation(discordSaturation); - setTintedText(tintedText); - }} />)}> - Settings & Presets - -
- -
- - - - - - -
- ); -} diff --git a/src/equicordplugins/discordColorways/components/Icons.tsx b/src/equicordplugins/discordColorways/components/Icons.tsx deleted file mode 100644 index 62acf0f5e..000000000 --- a/src/equicordplugins/discordColorways/components/Icons.tsx +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { classes } from "@utils/misc"; -import type { PropsWithChildren, SVGProps } from "react"; - -interface BaseIconProps extends IconProps { - viewBox: string; -} - -interface IconProps extends SVGProps { - className?: string; - height?: string | number; - width?: string | number; -} - -function Icon({ height = 24, width = 24, className, children, viewBox, ...svgProps }: PropsWithChildren) { - return ( - - {children} - - ); -} - -export function PalleteIcon(props: IconProps) { - return ( - - - - ); -} - -export function CloseIcon(props: IconProps) { - return ( - - - - ); -} - -export function DownloadIcon(props: IconProps) { - return ( - - - - ); -} - -export function ImportIcon(props: IconProps) { - return ( - - - - ); -} - -export function IDIcon(props: IconProps) { - return ( - - - - - ); -} - -export function CodeIcon(props: IconProps) { - return ( - - - - ); -} - -export function MoreIcon(props: IconProps) { - return ( - - - - ); -} diff --git a/src/equicordplugins/discordColorways/components/InfoModal.tsx b/src/equicordplugins/discordColorways/components/InfoModal.tsx deleted file mode 100644 index 100bfb04c..000000000 --- a/src/equicordplugins/discordColorways/components/InfoModal.tsx +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import * as DataStore from "@api/DataStore"; -import { CodeBlock } from "@components/CodeBlock"; -import { Flex } from "@components/Flex"; -import { - ModalCloseButton, - ModalContent, - ModalFooter, - ModalHeader, - ModalProps, - ModalRoot, - openModal, -} from "@utils/modal"; -import { saveFile } from "@utils/web"; -import { findComponentByCodeLazy } from "@webpack"; -import { Button, Clipboard, Forms, Text, TextInput, Toasts, UserStore, useState, useStateFromStores } from "@webpack/common"; - -import { ColorwayCSS, versionData } from ".."; -import { generateCss, pureGradientBase } from "../css"; -import { Colorway } from "../types"; -import { colorToHex, stringToHex } from "../utils"; -import SaveColorwayModal from "./SaveColorwayModal"; -import ThemePreview from "./ThemePreview"; - -const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers"); - -function RenameColorwayModal({ modalProps, ogName, onFinish, colorwayList }: { modalProps: ModalProps, ogName: string, onFinish: (name: string) => void, colorwayList: Colorway[]; }) { - const [error, setError] = useState(""); - const [newName, setNewName] = useState(ogName); - return - - - Rename Colorway... - - modalProps.onClose()} /> - - - - - - - - - ; -} - -export default function ({ - modalProps, - colorway, - loadUIProps -}: { - modalProps: ModalProps; - colorway: Colorway; - loadUIProps: () => Promise; -}) { - const colors: string[] = colorway.colors || [ - "accent", - "primary", - "secondary", - "tertiary", - ]; - const profile = useStateFromStores([UserStore], () => UserStore.getUser(colorway.authorID)); - return - - - Colorway: {colorway.name} - - modalProps.onClose()} /> - - - - Creator: - - - {colorway.author} - - Colors: - - {colors.map(color =>
)} - - Actions: - - - - - {colorway.sourceType === "offline" && } - - - - {colorway.sourceType === "offline" && } - - -
- - ; -} diff --git a/src/equicordplugins/discordColorways/components/InputColorwayIdModal.tsx b/src/equicordplugins/discordColorways/components/InputColorwayIdModal.tsx deleted file mode 100644 index 6100529c6..000000000 --- a/src/equicordplugins/discordColorways/components/InputColorwayIdModal.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { ModalContent, ModalFooter, ModalProps, ModalRoot } from "@utils/modal"; -import { Button, Forms, TextInput, useState } from "@webpack/common"; - -import { hexToString } from "../utils"; - -export default function ({ modalProps, onColorwayId }: { modalProps: ModalProps, onColorwayId: (colorwayID: string) => void; }) { - const [colorwayID, setColorwayID] = useState(""); - return - - Colorway ID: - setColorwayID(e.currentTarget.value)} /> - - - - - - ; -} diff --git a/src/equicordplugins/discordColorways/components/SaveColorwayModal.tsx b/src/equicordplugins/discordColorways/components/SaveColorwayModal.tsx deleted file mode 100644 index 8a034edbc..000000000 --- a/src/equicordplugins/discordColorways/components/SaveColorwayModal.tsx +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { DataStore } from "@api/index"; -import { PlusIcon } from "@components/Icons"; -import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal"; -import { findByProps } from "@webpack"; -import { Button, Text, TextInput, useEffect, useState } from "@webpack/common"; - -import { Colorway } from "../types"; -import { StoreNameModal } from "./SettingsTabs/SourceManager"; - -export default function ({ modalProps, colorways, onFinish }: { modalProps: ModalProps, colorways: Colorway[], onFinish: () => void; }) { - const [offlineColorwayStores, setOfflineColorwayStores] = useState<{ name: string, colorways: Colorway[], id?: string; }[]>([]); - const [storename, setStorename] = useState(); - const [noStoreError, setNoStoreError] = useState(false); - const { radioBar, item: radioBarItem, itemFilled: radioBarItemFilled, radioPositionLeft } = findByProps("radioBar"); - useEffect(() => { - (async () => { - setOfflineColorwayStores(await DataStore.get("customColorways") as { name: string, colorways: Colorway[], id?: string; }[]); - })(); - }); - return - - Select Offline Colorway Source - - - {noStoreError ? Error: No store selected : <>} - {offlineColorwayStores.map(store => { - return
-
{ - setStorename(store.name); - }}> - - {store.name} -
-
; - })} -
-
{ - openModal(props => { - await DataStore.set("customColorways", [...await DataStore.get("customColorways"), { name: e, colorways: [] }]); - setOfflineColorwayStores(await DataStore.get("customColorways") as { name: string, colorways: Colorway[]; }[]); - }} />); - }}> - - Create new store... -
-
-
- - - - - -
; - } - openModal(propss => { - const newStore = { name: storeToModify.name, colorways: [...storeToModify.colorways, { ...colorway, name: e }] }; - DataStore.set("customColorways", [...oldStores!.filter(source => source.name !== storename), newStore]); - props.onClose(); - if (i + 1 === colorways.length) { - modalProps.onClose(); - onFinish!(); - } - }} />); - }} - > - Rename - - - - ); - } else { - const newStore = { name: storeToModify.name, colorways: [...storeToModify.colorways, colorway] }; - DataStore.set("customColorways", [...oldStores!.filter(source => source.name !== storename), newStore]); - if (i + 1 === colorways.length) { - modalProps.onClose(); - onFinish(); - } - } - }); - } - }} - > - Finish - - - - ; -} diff --git a/src/equicordplugins/discordColorways/components/Selector.tsx b/src/equicordplugins/discordColorways/components/Selector.tsx deleted file mode 100644 index d30b64050..000000000 --- a/src/equicordplugins/discordColorways/components/Selector.tsx +++ /dev/null @@ -1,839 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -/* eslint-disable arrow-parens */ - -import * as DataStore from "@api/DataStore"; -import { Flex } from "@components/Flex"; -import { DeleteIcon, PlusIcon } from "@components/Icons"; -import { SettingsTab } from "@components/VencordSettings/shared"; -import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal"; -import { findByProps, findByPropsLazy } from "@webpack"; -import { - Button, - ButtonLooks, - Clipboard, - Forms, - Menu, - Popout, - ScrollerThin, - Select, - SettingsRouter, - Text, - TextInput, - Toasts, - Tooltip, - useEffect, - useState -} from "@webpack/common"; -import { ReactNode } from "react"; - -import { ColorwayCSS } from ".."; -import { generateCss, getAutoPresets, gradientBase } from "../css"; -import { Colorway, ColorwayObject, SortOptions, SourceObject } from "../types"; -import { colorToHex, getHex, stringToHex } from "../utils"; -import AutoColorwaySelector from "./AutoColorwaySelector"; -import ColorPickerModal from "./ColorPicker"; -import CreatorModal from "./CreatorModal"; -import { CodeIcon, IDIcon, MoreIcon, PalleteIcon } from "./Icons"; -import ColorwayInfoModal from "./InfoModal"; - -const { SelectionCircle } = findByPropsLazy("SelectionCircle"); - -function SelectorContainer({ children, isSettings, modalProps }: { children: ReactNode, isSettings?: boolean, modalProps: ModalProps; }) { - if (!isSettings) { - return - {children} - ; - } else { - return -
- {children} -
-
; - } -} - -function SelectorHeader({ children, isSettings }: { children: ReactNode, isSettings?: boolean; }) { - if (!isSettings) { - return - {children} - ; - } else { - return - {children} - ; - } -} - -function SelectorContent({ children, isSettings }: { children: ReactNode, isSettings?: boolean; }) { - if (!isSettings) { - return {children}; - } else { - return <>{children}; - } -} - -export default function ({ - modalProps, - isSettings, - settings = { selectorType: "normal" } -}: { - modalProps: ModalProps, - isSettings?: boolean, - settings?: { selectorType: "preview" | "multiple-selection" | "normal", previewSource?: string, onSelected?: (colorways: Colorway[]) => void; }; -}): JSX.Element | any { - const [colorwayData, setColorwayData] = useState([]); - const [searchValue, setSearchValue] = useState(""); - const [sortBy, setSortBy] = useState(SortOptions.NAME_AZ); - const [activeColorwayObject, setActiveColorwayObject] = useState({ id: null, css: null, sourceType: null, source: null }); - const [customColorwayData, setCustomColorwayData] = useState([]); - const [loaderHeight, setLoaderHeight] = useState<"2px" | "0px">("2px"); - const [visibleSources, setVisibleSources] = useState("all"); - const [showReloadMenu, setShowReloadMenu] = useState(false); - const [viewMode, setViewMode] = useState<"list" | "grid">("grid"); - const [showLabelsInSelectorGridView, setShowLabelsInSelectorGridView] = useState(false); - const [showSortingMenu, setShowSotringMenu] = useState(false); - const [selectedColorways, setSelectedColorways] = useState([]); - const [errorCode, setErrorCode] = useState(0); - - const { item: radioBarItem, itemFilled: radioBarItemFilled } = findByProps("radioBar"); - - const filters = [ - { - name: "All", - id: "all", - sources: [...colorwayData, ...customColorwayData] - }, - ...colorwayData.map((source) => ({ - name: source.source, - id: source.source.toLowerCase().replaceAll(" ", "-"), - sources: [source] - })), - ...customColorwayData.map((source) => ({ - name: source.source, - id: source.source.toLowerCase().replaceAll(" ", "-"), - sources: [source] - })) - ]; - - async function loadUI(force?: boolean) { - setActiveColorwayObject(await DataStore.get("activeColorwayObject") as ColorwayObject); - setViewMode(await DataStore.get("selectorViewMode") as "list" | "grid"); - setShowLabelsInSelectorGridView(await DataStore.get("showLabelsInSelectorGridView") as boolean); - setLoaderHeight("0px"); - - if (settings.previewSource) { - - const res: Response = await fetch(settings.previewSource); - - const dataPromise = res.json().then(data => data).catch(() => ({ colorways: [], errorCode: 1, errorMsg: "Colorway Source format is invalid" })); - - const data = await dataPromise; - - if (data.errorCode) { - setErrorCode(data.errorCode); - } - - const colorwayList: Colorway[] = data.css ? data.css.map(customStore => customStore.colorways).flat() : data.colorways; - - setColorwayData([{ colorways: colorwayList || [], source: res.url, type: "online" }] as { type: "online" | "offline" | "temporary", source: string, colorways: Colorway[]; }[]); - - } else { - setCustomColorwayData((await DataStore.get("customColorways") as { name: string, colorways: Colorway[], id?: string; }[]).map((colorSrc: { name: string, colorways: Colorway[], id?: string; }) => ({ type: "offline", source: colorSrc.name, colorways: colorSrc.colorways }))); - - const onlineSources: { name: string, url: string; }[] = await DataStore.get("colorwaySourceFiles") as { name: string, url: string; }[]; - - const responses: Response[] = await Promise.all( - onlineSources.map((source) => - fetch(source.url, force ? { cache: "no-store" } : {}) - ) - ); - - setColorwayData(await Promise.all( - responses - .map((res, i) => ({ response: res, name: onlineSources[i].name })) - .map((res: { response: Response, name: string; }) => - res.response.json().then(dt => ({ colorways: dt.colorways as Colorway[], source: res.name, type: "online" })).catch(() => ({ colorways: [] as Colorway[], source: res.name, type: "online" })) - )) as { type: "online" | "offline" | "temporary", source: string, colorways: Colorway[]; }[]); - } - } - - useEffect(() => { loadUI(); }, [searchValue]); - - function ReloadPopout(onClose: () => void) { - return ( - - loadUI(true)} - /> - - ); - } - - function SortingPopout(onClose: () => void) { - return ( - - - { - setViewMode("grid"); - DataStore.set("selectorViewMode", "grid"); - }} - /> - { - setViewMode("list"); - DataStore.set("selectorViewMode", "list"); - }} - /> - - - setSortBy(SortOptions.NAME_AZ)} - /> - setSortBy(SortOptions.NAME_ZA)} - /> - setSortBy(SortOptions.SOURCE_AZ)} - /> - setSortBy(SortOptions.SOURCE_ZA)} - /> - - - ); - } - - return ( - - - {settings.selectorType !== "preview" ? <> - - - {({ onMouseEnter, onMouseLeave }) => setShowReloadMenu(false)} - renderPopout={() => ReloadPopout(() => setShowReloadMenu(false))} - > - {(_, { isShown }) => } - } - - - {({ onMouseEnter, onMouseLeave }) => } - - - {({ onMouseEnter, onMouseLeave }) => setShowSotringMenu(false)} - renderPopout={() => SortingPopout(() => setShowSotringMenu(false))} - > - {(_, { isShown }) => } - } - - - {({ onMouseEnter, onMouseLeave }) => } - - {isSettings ? { return { label: filter.name, value: (filter.id as string) }; })} - select={value => setVisibleSources(value)} - isSelected={value => visibleSources === value} - serialize={String} - popoutPosition="top" /> - : <>} - - ); -} diff --git a/src/equicordplugins/discordColorways/components/SettingsTabs/OnDemandPage.tsx b/src/equicordplugins/discordColorways/components/SettingsTabs/OnDemandPage.tsx deleted file mode 100644 index b3fe98100..000000000 --- a/src/equicordplugins/discordColorways/components/SettingsTabs/OnDemandPage.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { DataStore } from "@api/index"; -import { SettingsTab } from "@components/VencordSettings/shared"; -import { Switch, useCallback, useEffect, useState } from "@webpack/common"; - -export default function () { - const [onDemand, setOnDemand] = useState(false); - const [onDemandTinted, setOnDemandTinted] = useState(false); - const [onDemandDiscordSat, setOnDemandDiscordSat] = useState(false); - const [onDemandOsAccent, setOnDemandOsAccent] = useState(false); - async function loadUI() { - const [ - onDemandWays, - onDemandWaysTintedText, - onDemandWaysDiscordSaturation, - onDemandWaysOsAccentColor - ] = await DataStore.getMany([ - "onDemandWays", - "onDemandWaysTintedText", - "onDemandWaysDiscordSaturation", - "onDemandWaysOsAccentColor" - ]); - setOnDemand(onDemandWays); - setOnDemandTinted(onDemandWaysTintedText); - setOnDemandDiscordSat(onDemandWaysDiscordSaturation); - if (getComputedStyle(document.body).getPropertyValue("--os-accent-color") !== "") { - setOnDemandOsAccent(onDemandWaysOsAccentColor); - } - } - - const cached_loadUI = useCallback(loadUI, []); - - useEffect(() => { - cached_loadUI(); - }, []); - return - { - setOnDemand(v); - DataStore.set("onDemandWays", v); - }} - note="Always utilise the latest of what DiscordColorways has to offer. CSS is being directly generated on the device and gets applied in the place of the normal import/CSS given by the colorway." - > - Enable Colorways On Demand - - { - setOnDemandTinted(v); - DataStore.set("onDemandWaysTintedText", v); - }} - disabled={!onDemand} - > - Use tinted text - - { - setOnDemandDiscordSat(v); - DataStore.set("onDemandWaysDiscordSaturation", v); - }} - disabled={!onDemand} - > - Use Discord's saturation - - { - setOnDemandOsAccent(v); - DataStore.set("onDemandWaysOsAccentColor", v); - }} - disabled={!onDemand || !getComputedStyle(document.body).getPropertyValue("--os-accent-color")} - > - Use Operating System's Accent Color - - ; -} diff --git a/src/equicordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx b/src/equicordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx deleted file mode 100644 index 50a8050b7..000000000 --- a/src/equicordplugins/discordColorways/components/SettingsTabs/SettingsPage.tsx +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { DataStore } from "@api/index"; -import { Flex } from "@components/Flex"; -import { Link } from "@components/Link"; -import { SettingsTab } from "@components/VencordSettings/shared"; -import { - FluxDispatcher, - Forms, - Switch, - Text, - useEffect, - useState -} from "@webpack/common"; -import { FluxEvents } from "@webpack/types"; - -import { versionData } from "../../"; -import { fallbackColorways } from "../../constants"; -import { Colorway } from "../../types"; - -export default function () { - const [colorways, setColorways] = useState([]); - const [customColorways, setCustomColorways] = useState([]); - const [colorsButtonVisibility, setColorsButtonVisibility] = useState(false); - const [isButtonThin, setIsButtonThin] = useState(false); - const [showLabelsInSelectorGridView, setShowLabelsInSelectorGridView] = useState(false); - - useEffect(() => { - (async function () { - const [ - customColorways, - colorwaySourceFiles, - showColorwaysButton, - useThinMenuButton, - showLabelsInSelectorGridView - ] = await DataStore.getMany([ - "customColorways", - "colorwaySourceFiles", - "showColorwaysButton", - "useThinMenuButton", - "showLabelsInSelectorGridView" - ]); - const responses: Response[] = await Promise.all( - colorwaySourceFiles.map((url: string) => - fetch(url) - ) - ); - const data = await Promise.all( - responses.map((res: Response) => - res.json().catch(() => { return { colorways: [] }; }) - )); - const colorways = data.flatMap(json => json.colorways); - setColorways(colorways || fallbackColorways); - setCustomColorways(customColorways.map(source => source.colorways).flat(2)); - setColorsButtonVisibility(showColorwaysButton); - setIsButtonThin(useThinMenuButton); - setShowLabelsInSelectorGridView(showLabelsInSelectorGridView); - })(); - }, []); - - return -
- Quick Switch - { - setColorsButtonVisibility(v); - DataStore.set("showColorwaysButton", v); - FluxDispatcher.dispatch({ - type: "COLORWAYS_UPDATE_BUTTON_VISIBILITY" as FluxEvents, - isVisible: v - }); - }} - note="Shows a button on the top of the servers list that opens a colorway selector modal." - > - Enable Quick Switch - - { - setIsButtonThin(v); - DataStore.set("useThinMenuButton", v); - FluxDispatcher.dispatch({ - type: "COLORWAYS_UPDATE_BUTTON_HEIGHT" as FluxEvents, - isTall: v - }); - }} - note="Replaces the icon on the colorways launcher button with text, making it more compact." - > - Use thin Quick Switch button - - Selector - { - setShowLabelsInSelectorGridView(v); - DataStore.set("showLabelsInSelectorGridView", v); - }} - > - Show labels in Grid View - - -

- Discord Colorways -

- by Project Colorway - - Plugin Version: - - - {versionData.pluginVersion} - - - Creator Version: - - - {versionData.creatorVersion}{" (Stable)"} - - - Loaded Colorways: - - - {[...colorways, ...customColorways].length + 1} - - - Project Repositories: - - - DiscordColorways -
- Project Colorway -
-
-
-
; -} diff --git a/src/equicordplugins/discordColorways/components/SettingsTabs/SourceManager.tsx b/src/equicordplugins/discordColorways/components/SettingsTabs/SourceManager.tsx deleted file mode 100644 index 2cc3eeb9c..000000000 --- a/src/equicordplugins/discordColorways/components/SettingsTabs/SourceManager.tsx +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { DataStore } from "@api/index"; -import { Flex } from "@components/Flex"; -import { CopyIcon, DeleteIcon, PlusIcon } from "@components/Icons"; -import { SettingsTab } from "@components/VencordSettings/shared"; -import { Logger } from "@utils/Logger"; -import { closeModal, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal"; -import { chooseFile, saveFile } from "@utils/web"; -import { findByProps } from "@webpack"; -import { Button, Clipboard, Forms, ScrollerThin, Text, TextInput, useEffect, useState } from "@webpack/common"; - -import { defaultColorwaySource } from "../../constants"; -import { Colorway } from "../../types"; -import { DownloadIcon, ImportIcon } from "../Icons"; -import Spinner from "../Spinner"; - -export function StoreNameModal({ modalProps, originalName, onFinish, conflicting }: { modalProps: ModalProps, originalName: string, onFinish: (newName: string) => Promise, conflicting: boolean; }) { - const [error, setError] = useState(""); - const [newStoreName, setNewStoreName] = useState(originalName); - return - - {conflicting ? "Duplicate Store Name" : "Give this store a name"} - - - {conflicting ? A store with the same name already exists. Please give a different name to the imported store: : <>} - Name: - setNewStoreName(e)} style={{ marginBottom: "16px" }} /> - - - - - - ; -} - -function AddOnlineStoreModal({ modalProps, onFinish }: { modalProps: ModalProps, onFinish: (name: string, url: string) => void; }) { - const [colorwaySourceName, setColorwaySourceName] = useState(""); - const [colorwaySourceURL, setColorwaySourceURL] = useState(""); - const [nameError, setNameError] = useState(""); - const [URLError, setURLError] = useState(""); - const [nameReadOnly, setNameReadOnly] = useState(false); - return - - - Add a source: - - - - Name: - - URL: - { - setColorwaySourceURL(value); - if (value === defaultColorwaySource) { - setNameReadOnly(true); - setColorwaySourceName("Project Colorway"); - } - }} - value={colorwaySourceURL} - error={URLError} - style={{ marginBottom: "16px" }} - /> - - - - - - ; -} - -export default function () { - const [colorwaySourceFiles, setColorwaySourceFiles] = useState<{ name: string, url: string; }[]>([]); - const [customColorwayStores, setCustomColorwayStores] = useState<{ name: string, colorways: Colorway[]; }[]>([]); - - const { item: radioBarItem, itemFilled: radioBarItemFilled } = findByProps("radioBar"); - - useEffect(() => { - (async function () { - setColorwaySourceFiles(await DataStore.get("colorwaySourceFiles") as { name: string, url: string; }[]); - setCustomColorwayStores(await DataStore.get("customColorways") as { name: string, colorways: Colorway[]; }[]); - })(); - }, []); - return - - Online - - - - {!colorwaySourceFiles.length &&
{ - DataStore.set("colorwaySourceFiles", [{ name: "Project Colorway", url: defaultColorwaySource }]); - setColorwaySourceFiles([{ name: "Project Colorway", url: defaultColorwaySource }]); - }}> - - - Add Project Colorway Source - -
} - {colorwaySourceFiles.map((colorwaySourceFile: { name: string, url: string; }, i: number) =>
-
- - {colorwaySourceFile.name} {colorwaySourceFile.url === defaultColorwaySource &&
Built-In
} -
- - {colorwaySourceFile.url} - -
- - - {colorwaySourceFile.url !== defaultColorwaySource - && <> - - - } - -
- )} -
- - Offline - - - - - {getComputedStyle(document.body).getPropertyValue("--os-accent-color") ?
- - OS Accent Color{" "} -
Built-In
-
-
-
: <>} - {customColorwayStores.map(({ name: customColorwaySourceName, colorways: offlineStoreColorways }) =>
- - {customColorwaySourceName} - - - - - -
- )} -
-
; -} diff --git a/src/equicordplugins/discordColorways/components/SettingsTabs/Store.tsx b/src/equicordplugins/discordColorways/components/SettingsTabs/Store.tsx deleted file mode 100644 index c3e141cdc..000000000 --- a/src/equicordplugins/discordColorways/components/SettingsTabs/Store.tsx +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { DataStore } from "@api/index"; -import { Flex } from "@components/Flex"; -import { DeleteIcon } from "@components/Icons"; -import { Link } from "@components/Link"; -import { SettingsTab } from "@components/VencordSettings/shared"; -import { getTheme, Theme } from "@utils/discord"; -import { openModal } from "@utils/modal"; -import { findByProps } from "@webpack"; -import { Button, ScrollerThin, Text, TextInput, Tooltip, useEffect, useState } from "@webpack/common"; - -import { StoreItem } from "../../types"; -import { DownloadIcon, PalleteIcon } from "../Icons"; -import Selector from "../Selector"; - -const GithubIconLight = "/assets/3ff98ad75ac94fa883af5ed62d17c459.svg"; -const GithubIconDark = "/assets/6a853b4c87fce386cbfef4a2efbacb09.svg"; - -function GithubIcon() { - const src = getTheme() === Theme.Light ? GithubIconLight : GithubIconDark; - return GitHub; -} - -export default function () { - const [storeObject, setStoreObject] = useState([]); - const [colorwaySourceFiles, setColorwaySourceFiles] = useState<{ name: string, url: string; }[]>([]); - const [searchValue, setSearchValue] = useState(""); - - useEffect(() => { - if (!searchValue) { - (async function () { - const res: Response = await fetch("https://dablulite.vercel.app/"); - const data = await res.json(); - setStoreObject(data.sources); - setColorwaySourceFiles(await DataStore.get("colorwaySourceFiles") as { name: string, url: string; }[]); - })(); - } - }, []); - - const { item: radioBarItem, itemFilled: radioBarItemFilled } = findByProps("radioBar"); - - return - - - - {({ onMouseEnter, onMouseLeave }) => } - - - - {storeObject.map((item: StoreItem) => - item.name.toLowerCase().includes(searchValue.toLowerCase()) ?
- - - {item.name} - - - {item.description} - - - by {item.authorGh} - - - - - - - -
: <> - )} -
-
; -} diff --git a/src/equicordplugins/discordColorways/components/Spinner.tsx b/src/equicordplugins/discordColorways/components/Spinner.tsx deleted file mode 100644 index 650db5121..000000000 --- a/src/equicordplugins/discordColorways/components/Spinner.tsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { CSSProperties } from "react"; - -export default function ({ className, style }: { className?: string, style?: CSSProperties; }) { - return
-
- - - - - -
-
; -} diff --git a/src/equicordplugins/discordColorways/components/ThemePreview.tsx b/src/equicordplugins/discordColorways/components/ThemePreview.tsx deleted file mode 100644 index 593c0b164..000000000 --- a/src/equicordplugins/discordColorways/components/ThemePreview.tsx +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { ModalProps, ModalRoot, openModal } from "@utils/modal"; -import { Text } from "@webpack/common"; - -import { HexToHSL } from "../utils"; -import { CloseIcon } from "./Icons"; - -export default function ThemePreview({ - accent, - primary, - secondary, - tertiary, - previewCSS, - modalProps, - isModal -}: { - accent: string, - primary: string, - secondary: string, - tertiary: string, - previewCSS?: string, - modalProps?: ModalProps, - isModal?: boolean; -}) { - return <> - -
-
-
-
-
-
e.currentTarget.style.background = accent} - onMouseLeave={e => e.currentTarget.style.background = `var(--dc-guild-button, ${primary})`} - onClick={() => { - if (isModal) { - modalProps?.onClose(); - } else { - openModal((props: ModalProps) => - - - ); - } - }} - > - {isModal ? : } -
-
-
-
-
-
-
e.currentTarget.style.background = accent} - onMouseLeave={e => e.currentTarget.style.background = `var(--dc-guild-button, ${primary})`} - /> -
-
-
e.currentTarget.style.background = accent} - onMouseLeave={e => e.currentTarget.style.background = `var(--dc-guild-button, ${primary})`} - /> -
-
-
-
-
-
-
-
-
-
- - Preview - -
-
-
-
-
-
-
-
-
- ; -} diff --git a/src/equicordplugins/discordColorways/constants.ts b/src/equicordplugins/discordColorways/constants.ts deleted file mode 100644 index fdcdf90c1..000000000 --- a/src/equicordplugins/discordColorways/constants.ts +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -export const defaultColorwaySource = "https://raw.githubusercontent.com/DaBluLite/ProjectColorway/master/index.json"; - -export const fallbackColorways = [ - { - name: "Keyboard Purple", - original: false, - accent: "hsl(235 85.6% 64.7%)", - primary: "#222456", - secondary: "#1c1f48", - tertiary: "#080d1d", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/KeyboardPurple/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Eclipse", - original: false, - accent: "hsl(87 85.6% 64.7%)", - primary: "#000000", - secondary: "#181818", - tertiary: "#0a0a0a", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Eclipse/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Cyan", - original: false, - accent: "#009f88", - primary: "#202226", - secondary: "#1c1e21", - tertiary: "#141517", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Cyan/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Spotify", - original: false, - accent: "hsl(141 76% 48%)", - primary: "#121212", - secondary: "#090909", - tertiary: "#090909", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Spotify/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Bright n' Blue", - original: true, - accent: "hsl(234, 68%, 33%)", - primary: "#394aae", - secondary: "#29379d", - tertiary: "#1b278d", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/BrightBlue/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Still Young", - original: true, - accent: "hsl(58 85.6% 89%)", - primary: "#443a31", - secondary: "#7c3d3e", - tertiary: "#207578", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/StillYoung/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Sea", - original: true, - accent: "hsl(184, 100%, 50%)", - primary: "#07353b", - secondary: "#0b5e60", - tertiary: "#08201d", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Sea/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Lava", - original: true, - accent: "hsl(4, 80.4%, 32%)", - primary: "#401b17", - secondary: "#351917", - tertiary: "#230b0b", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Lava/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Solid Pink", - original: true, - accent: "hsl(340, 55.2%, 56.3%)", - primary: "#1e151c", - secondary: "#21181f", - tertiary: "#291e27", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/SolidPink/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Sand", - original: true, - accent: "hsl(41, 31%, 45%)", - primary: "#7f6c43", - secondary: "#665b33", - tertiary: "#5c5733", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Sand/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "AMOLED", - original: true, - accent: "hsl(235 85.6% 64.7%)", - primary: "#000000", - secondary: "#000000", - tertiary: "#000000", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Amoled/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Zorin", - original: false, - accent: "hsl(200, 89%, 86%)", - primary: "#171d20", - secondary: "#171d20", - tertiary: "#1e2529", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Zorin/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Desaturated", - original: false, - accent: "hsl(227, 58%, 65%)", - primary: "#35383d", - secondary: "#2c2f34", - tertiary: "#1e1f24", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Desaturated/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Crimson", - original: false, - accent: "hsl(0, 100%, 50%)", - primary: "#050000", - secondary: "#0a0000", - tertiary: "#0f0000", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Crimson/import.css);", - author: "Riddim_GLiTCH", - authorID: "801089753038061669", - }, - { - name: "Jupiter", - original: true, - accent: "#ffd89b", - primary: "#ffd89b", - secondary: "#19547b", - tertiary: "#1e1f22", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Jupiter/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - isGradient: true, - colors: ["accent", "primary", "secondary"], - }, - { - name: "Neon Candy", - original: true, - accent: "#FC00FF", - primary: "#00DBDE", - secondary: "#00DBDE", - tertiary: "#00DBDE", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/NeonCandy/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - isGradient: true, - colors: ["accent", "primary"], - }, - { - name: "Wildberry", - original: false, - accent: "#f40172", - primary: "#180029", - secondary: "#340057", - tertiary: "#4b007a", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Wildberry/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Facebook", - original: false, - accent: "#2375e1", - primary: "#18191a", - secondary: "#242526", - tertiary: "#3a3b3c", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Facebook/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Material You", - original: false, - accent: "#004977", - primary: "#1f1f1f", - secondary: "#28292a", - tertiary: "#2d2f31", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/MaterialYou/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "Discord Teal", - original: false, - accent: "#175f6d", - primary: "#313338", - secondary: "#2b2d31", - tertiary: "#1e1f22", - "dc-import": "@import url(//dablulite.github.io/css-snippets/DiscordTeal/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - colors: ["accent"], - }, - { - name: "黄昏の花 (Twilight Blossom)", - original: true, - accent: "#e100ff", - primary: "#04000a", - secondary: "#0b0024", - tertiary: "#210042", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/TwilightBlossom/import.css);", - author: "Riddim_GLiTCH", - authorID: "801089753038061669", - }, - { - name: "Chai", - original: true, - accent: "#59cd51", - primary: "#1c1e15", - secondary: "#1e2118", - tertiary: "#24291e", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/Chai/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, - { - name: "CS1.6", - original: false, - accent: "#929a8d", - primary: "#3f4738", - secondary: "#5b6c51", - tertiary: "#4d5945", - "dc-import": "@import url(//dablulite.github.io/DiscordColorways/CS16/import.css);", - author: "DaBluLite", - authorID: "582170007505731594", - }, -]; - - -export const knownThemeVars = { - "Cyan": { - variable: "--cyan-accent-color", - accent: "--cyan-accent-color", - primary: "--cyan-background-primary", - secondary: "--cyan-background-secondary" - }, - "Virtual Boy": { - variable: "--VBaccent", - tertiary: "--VBaccent-muted", - alt: { - tertiary: "--VBaccent-dimmest" - } - }, - "Modular": { - variable: "--modular-hue", - accentVariables: { - h: "--modular-hue", - s: "--modular-saturation", - l: "--modular-lightness" - } - }, - "Solana": { - variable: "--accent-hue", - accentVariables: { - h: "--accent-hue", - s: "--accent-saturation", - l: "--accent-brightness" - }, - primaryVariables: { - h: "--background-accent-hue", - s: "--background-accent-saturation", - l: "--background-accent-brightness" - } - } -}; - -export const mainColors = [ - { name: "accent", title: "Accent", var: "--brand-experiment" }, - { name: "primary", title: "Primary", var: "--background-primary" }, - { name: "secondary", title: "Secondary", var: "--background-secondary" }, - { name: "tertiary", title: "Tertiary", var: "--background-tertiary" } -]; diff --git a/src/equicordplugins/discordColorways/css.ts b/src/equicordplugins/discordColorways/css.ts deleted file mode 100644 index 565b808e7..000000000 --- a/src/equicordplugins/discordColorways/css.ts +++ /dev/null @@ -1,1001 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { UserStore } from "@webpack/common"; -import { Plugins } from "Vencord"; - -import { HexToHSL } from "./utils"; - -export const colorVariables: string[] = [ - "brand-100", - "brand-130", - "brand-160", - "brand-200", - "brand-230", - "brand-260", - "brand-300", - "brand-330", - "brand-345", - "brand-360", - "brand-400", - "brand-430", - "brand-460", - "brand-500", - "brand-530", - "brand-560", - "brand-600", - "brand-630", - "brand-660", - "brand-700", - "brand-730", - "brand-760", - "brand-800", - "brand-830", - "brand-860", - "brand-900", - "primary-900", - "primary-860", - "primary-830", - "primary-800", - "primary-760", - "primary-730", - "primary-700", - "primary-660", - "primary-645", - "primary-630", - "primary-600", - "primary-560", - "primary-530", - "primary-500", - "primary-460", - "primary-430", - "primary-400", - "primary-360", - "primary-330", - "primary-300", - "primary-260", - "primary-230", - "primary-200", - "primary-160", - "primary-130", - "primary-100", - "white-900", - "white-860", - "white-830", - "white-800", - "white-760", - "white-730", - "white-700", - "white-660", - "white-630", - "white-600", - "white-560", - "white-530", - "white-500", - "white-460", - "white-430", - "white-400", - "white-360", - "white-330", - "white-300", - "white-260", - "white-230", - "white-200", - "white-160", - "white-130", - "white-100", - "teal-900", - "teal-860", - "teal-830", - "teal-800", - "teal-760", - "teal-730", - "teal-700", - "teal-660", - "teal-630", - "teal-600", - "teal-560", - "teal-530", - "teal-500", - "teal-460", - "teal-430", - "teal-400", - "teal-360", - "teal-330", - "teal-300", - "teal-260", - "teal-230", - "teal-200", - "teal-160", - "teal-130", - "teal-100", - "black-900", - "black-860", - "black-830", - "black-800", - "black-760", - "black-730", - "black-700", - "black-660", - "black-630", - "black-600", - "black-560", - "black-530", - "black-500", - "black-460", - "black-430", - "black-400", - "black-360", - "black-330", - "black-300", - "black-260", - "black-230", - "black-200", - "black-160", - "black-130", - "black-100", - "red-900", - "red-860", - "red-830", - "red-800", - "red-760", - "red-730", - "red-700", - "red-660", - "red-630", - "red-600", - "red-560", - "red-530", - "red-500", - "red-460", - "red-430", - "red-400", - "red-360", - "red-330", - "red-300", - "red-260", - "red-230", - "red-200", - "red-160", - "red-130", - "red-100", - "yellow-900", - "yellow-860", - "yellow-830", - "yellow-800", - "yellow-760", - "yellow-730", - "yellow-700", - "yellow-660", - "yellow-630", - "yellow-600", - "yellow-560", - "yellow-530", - "yellow-500", - "yellow-460", - "yellow-430", - "yellow-400", - "yellow-360", - "yellow-330", - "yellow-300", - "yellow-260", - "yellow-230", - "yellow-200", - "yellow-160", - "yellow-130", - "yellow-100", - "green-900", - "green-860", - "green-830", - "green-800", - "green-760", - "green-730", - "green-700", - "green-660", - "green-630", - "green-600", - "green-560", - "green-530", - "green-500", - "green-460", - "green-430", - "green-400", - "green-360", - "green-330", - "green-300", - "green-260", - "green-230", - "green-200", - "green-160", - "green-130", - "green-100", -]; - -export const PrimarySatDiffs = { - 130: 63.9594, - 160: 49.4382, - 200: 37.5758, - 230: 30.3797, - 260: 22.5166, - 300: 32.5, - 330: 27.0968, - 345: 22.5166, - 360: 18.9189, - 400: -14.4, - 430: -33.0435, - 460: 25.2101, - 500: -11.0236, - 530: -3.0303, - 645: 7.40741, - 660: 3.0303, - 730: 11.9403, - 800: 25, -}; - -export const BrandSatDiffs = { - 100: -9.54712, - 130: 2.19526, - 160: -1.17509, - 200: -2.72351, - 230: 1.62225, - 260: 0.698487, - 300: 0.582411, - 330: -0.585823, - 345: -0.468384, - 360: 0.582411, - 400: 0.582411, - 430: 0.116754, - 460: -0.116891, - 530: -24.8194, - 560: -49.927, - 600: -58.8057, - 630: -58.8057, - 660: -58.0256, - 700: -58.2202, - 730: -58.6103, - 760: -58.4151, - 800: -57.2502, - 830: -57.4436, - 860: -58.4151, - 900: -52.5074 -}; - -export const BrandLightDiffs = { - 100: 33.5, - 130: 32.2, - 160: 30.2, - 200: 28.2, - 230: 26.2999, - 260: 23.8999, - 300: 21.2, - 330: 16.8999, - 345: 14.0999, - 360: 12.7999, - 400: 7.0999, - 430: 5.0999, - 460: 2.7999, - 530: -5.9, - 560: -12.3, - 600: -20.6, - 630: -26.5, - 660: -31.4, - 700: -38.8, - 730: -40.4, - 760: -42.5, - 800: -45.3, - 830: -49.8, - 860: -55.1, - 900: -61.6 -}; - -export const pureGradientBase = ` -.theme-dark :is(.colorwaysPreview-modal, .colorwaysPreview-wrapper) { - --dc-overlay-color: 0 0 0; - --dc-overlay-color-inverse: 255 255 255; - --dc-overlay-opacity-1: 0.85; - --dc-overlay-opacity-2: 0.8; - --dc-overlay-opacity-3: 0.7; - --dc-overlay-opacity-4: 0.5; - --dc-overlay-opacity-5: 0.4; - --dc-overlay-opacity-6: 0.1; - --dc-overlay-opacity-hover: 0.5; - --dc-overlay-opacity-hover-inverse: 0.08; - --dc-overlay-opacity-active: 0.45; - --dc-overlay-opacity-active-inverse: 0.1; - --dc-overlay-opacity-selected: 0.4; - --dc-overlay-opacity-selected-inverse: 0.15; - --dc-overlay-opacity-chat: 0.8; - --dc-overlay-opacity-home: 0.85; - --dc-overlay-opacity-home-card: 0.8; - --dc-overlay-opacity-app-frame: var(--dc-overlay-opacity-4); - --dc-guild-button: rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-6)); - --dc-secondary-alt: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-chat-header: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-2)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-2))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; -} -.theme-light :is(.colorwaysPreview-modal, .colorwaysPreview-wrapper) { - --dc-overlay-color: 255 255 255; - --dc-overlay-color-inverse: 0 0 0; - --dc-overlay-opacity-1: 0.9; - --dc-overlay-opacity-2: 0.8; - --dc-overlay-opacity-3: 0.7; - --dc-overlay-opacity-4: 0.6; - --dc-overlay-opacity-5: 0.3; - --dc-overlay-opacity-6: 0.15; - --dc-overlay-opacity-hover: 0.7; - --dc-overlay-opacity-hover-inverse: 0.02; - --dc-overlay-opacity-active: 0.65; - --dc-overlay-opacity-active-inverse: 0.03; - --dc-overlay-opacity-selected: 0.6; - --dc-overlay-opacity-selected-inverse: 0.04; - --dc-overlay-opacity-chat: 0.9; - --dc-overlay-opacity-home: 0.7; - --dc-overlay-opacity-home-card: 0.9; - --dc-overlay-opacity-app-frame: var(--dc-overlay-opacity-5); - --dc-guild-button: rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3)); - --dc-secondary-alt: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-chat-header: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; -} -.colorwaysPreview-modal, -.colorwaysPreview-wrapper { - --dc-overlay-1: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-1))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-2: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-2)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-2))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-3: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-3))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-4: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-4)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-4))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-5: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-5)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-5))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-6: linear-gradient(rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-6)),rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-6))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-hover: linear-gradient(rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-hover-inverse)),rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-hover-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-hover)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-hover))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-active: linear-gradient(rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-active-inverse)),rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-active-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-active)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-active))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-selected: linear-gradient(rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-selected-inverse)),rgb(var(--dc-overlay-color-inverse)/var(--dc-overlay-opacity-selected-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-selected)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-selected))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-chat: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-chat)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-chat))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-home: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-home)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-home))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-home-card: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-home-card)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-home-card))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; - --dc-overlay-app-frame: linear-gradient(rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-app-frame)),rgb(var(--dc-overlay-color)/var(--dc-overlay-opacity-app-frame))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover; -}`; - - -export function gradientBase(accentColor?: string, discordSaturation = false) { - return `@import url(//dablulite.github.io/css-snippets/NitroThemesFix/import.css); -.theme-dark { - --bg-overlay-color: 0 0 0; - --bg-overlay-color-inverse: 255 255 255; - --bg-overlay-opacity-1: 0.85; - --bg-overlay-opacity-2: 0.8; - --bg-overlay-opacity-3: 0.7; - --bg-overlay-opacity-4: 0.5; - --bg-overlay-opacity-5: 0.4; - --bg-overlay-opacity-6: 0.1; - --bg-overlay-opacity-hover: 0.5; - --bg-overlay-opacity-hover-inverse: 0.08; - --bg-overlay-opacity-active: 0.45; - --bg-overlay-opacity-active-inverse: 0.1; - --bg-overlay-opacity-selected: 0.4; - --bg-overlay-opacity-selected-inverse: 0.15; - --bg-overlay-opacity-chat: 0.8; - --bg-overlay-opacity-home: 0.85; - --bg-overlay-opacity-home-card: 0.8; - --bg-overlay-opacity-app-frame: var(--bg-overlay-opacity-4); -} -.theme-light { - --bg-overlay-color: 255 255 255; - --bg-overlay-color-inverse: 0 0 0; - --bg-overlay-opacity-1: 0.9; - --bg-overlay-opacity-2: 0.8; - --bg-overlay-opacity-3: 0.7; - --bg-overlay-opacity-4: 0.6; - --bg-overlay-opacity-5: 0.3; - --bg-overlay-opacity-6: 0.15; - --bg-overlay-opacity-hover: 0.7; - --bg-overlay-opacity-hover-inverse: 0.02; - --bg-overlay-opacity-active: 0.65; - --bg-overlay-opacity-active-inverse: 0.03; - --bg-overlay-opacity-selected: 0.6; - --bg-overlay-opacity-selected-inverse: 0.04; - --bg-overlay-opacity-chat: 0.9; - --bg-overlay-opacity-home: 0.7; - --bg-overlay-opacity-home-card: 0.9; - --bg-overlay-opacity-app-frame: var(--bg-overlay-opacity-5); -} -.children_cde9af:after, .form_d8a4a1:before { - content: none; -} -.scroller_de945b { - background: var(--bg-overlay-app-frame,var(--background-tertiary)); -} -.expandedFolderBackground_b1385f { - background: rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6)); -} -.wrapper__8436d:not(:hover):not(.selected_ae80f7) .childWrapper_a6ce15 { - background: rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6)); -} -.folder__17546:has(.expandedFolderIconWrapper__324c1) { - background: var(--bg-overlay-6,var(--background-secondary)); -} -.circleIconButton__05cf2:not(.selected_aded59) { - background: rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6)); -} -.auto_a3c0bd::-webkit-scrollbar-thumb, -.thin_b1c063::-webkit-scrollbar-thumb { - background-size: 200vh; - background-image: -webkit-gradient(linear,left top,left bottom,from(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-4))),to(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-4)))),var(--custom-theme-background); - background-image: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-4)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-4))),var(--custom-theme-background); -} -.auto_a3c0bd::-webkit-scrollbar-track { - background-size: 200vh; - background-image: -webkit-gradient(linear,left top,left bottom,from(rgb(var(--bg-overlay-color)/.4)),to(rgb(var(--bg-overlay-color)/.4))),var(--custom-theme-background); - background-image: linear-gradient(rgb(var(--bg-overlay-color)/.4),rgb(var(--bg-overlay-color)/.4)),var(--custom-theme-background); -} -:root:root { - --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[100])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)}; - --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[130])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[130]) * 10) / 10, 0)}%; - --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[160])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[160]) * 10) / 10, 0)}%; - --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[200])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[200]) * 10) / 10, 0)}%; - --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[230])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[230]) * 10) / 10, 0)}%; - --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[260])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[260]) * 10) / 10, 0)}%; - --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[300])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[300]) * 10) / 10, 0)}%; - --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[330])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[330]) * 10) / 10, 0)}%; - --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[345])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[345]) * 10) / 10, 0)}%; - --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[360])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[360]) * 10) / 10, 0)}%; - --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[400])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[400]) * 10) / 10, 0)}%; - --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[430])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[430]) * 10) / 10, 0)}%; - --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[460])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[460]) * 10) / 10, 0)}%; - --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; - --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[530])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[530]) * 10) / 10, 100)}%; - --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[560])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[560]) * 10) / 10, 100)}%; - --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[600])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[600]) * 10) / 10, 100)}%; - --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[630])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[630]) * 10) / 10, 100)}%; - --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[660])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[660]) * 10) / 10, 100)}%; - --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[700])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[700]) * 10) / 10, 100)}%; - --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[730])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[730]) * 10) / 10, 100)}%; - --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[760])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[760]) * 10) / 10, 100)}%; - --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[800])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[800]) * 10) / 10, 100)}%; - --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[830])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[830]) * 10) / 10, 100)}%; - --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[860])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[860]) * 10) / 10, 100)}%; - --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[900])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[900]) * 10) / 10, 100)}%; - --bg-overlay-1: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-2: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-2)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-2))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-3: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-3)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-3))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-4: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-4)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-4))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-5: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-5)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-5))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-6: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-hover: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-hover-inverse)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-hover-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-hover)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-hover))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-active: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-active-inverse)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-active-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-active)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-active))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-selected: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-selected-inverse)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-selected-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-selected)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-selected))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-chat: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-home: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-home-card: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; - --bg-overlay-app-frame: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover; -}`; -} - -export function generateCss(primaryColor: string, secondaryColor: string, tertiaryColor: string, accentColor: string, tintedText: boolean, discordSaturation: boolean, mutedTextBrightness?: number, name?: string) { - return `/** - * @name ${name} - * @version ${(Plugins.plugins.DiscordColorways as any).creatorVersion} - * @description Automatically generated Colorway. - * @author ${UserStore.getCurrentUser().username} - * @authorId ${UserStore.getCurrentUser().id} - */ -:root:root { - --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[100])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)}; - --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[130])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[130]) * 10) / 10, 0)}%; - --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[160])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[160]) * 10) / 10, 0)}%; - --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[200])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[200]) * 10) / 10, 0)}%; - --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[230])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[230]) * 10) / 10, 0)}%; - --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[260])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[260]) * 10) / 10, 0)}%; - --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[300])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[300]) * 10) / 10, 0)}%; - --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[330])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[330]) * 10) / 10, 0)}%; - --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[345])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[345]) * 10) / 10, 0)}%; - --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[360])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[360]) * 10) / 10, 0)}%; - --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[400])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[400]) * 10) / 10, 0)}%; - --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[430])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[430]) * 10) / 10, 0)}%; - --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[460])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[460]) * 10) / 10, 0)}%; - --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; - --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[530])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[530]) * 10) / 10, 100)}%; - --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[560])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[560]) * 10) / 10, 100)}%; - --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[600])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[600]) * 10) / 10, 100)}%; - --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[630])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[630]) * 10) / 10, 100)}%; - --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[660])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[660]) * 10) / 10, 100)}%; - --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[700])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[700]) * 10) / 10, 100)}%; - --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[730])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[730]) * 10) / 10, 100)}%; - --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[760])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[760]) * 10) / 10, 100)}%; - --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[800])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[800]) * 10) / 10, 100)}%; - --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[830])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[830]) * 10) / 10, 100)}%; - --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[860])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[860]) * 10) / 10, 100)}%; - --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[900])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[900]) * 10) / 10, 100)}%; -} -.theme-dark { - --primary-800-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%; - --primary-730-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[730])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - 3.6, 0)}%; - --primary-700-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%; - --primary-660-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[660])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 3.6, 0)}%; - --primary-645-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[645])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 1.1, 0)}%; - --primary-630-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${HexToHSL("#" + secondaryColor)[2]}%; - --primary-600-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%; - --primary-560-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 3.6, 100)}%; - --primary-530-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[530])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 2), 100)}%; - --primary-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[500])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${mutedTextBrightness || Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)}%; - --interactive-muted: hsl(${HexToHSL("#" + primaryColor)[0]} ${HexToHSL("#" + primaryColor)[1] / 2}% ${Math.max(Math.min(HexToHSL("#" + primaryColor)[2] - 5, 100), 45)}%); - ${tintedText ? `--primary-460-hsl: 0 calc(var(--saturation-factor, 1)*0%) 50%; - --primary-430: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL(`#${primaryColor}`)[1] / 100) * (100 + PrimarySatDiffs[430])) * 10) / 10 : HexToHSL(`#${primaryColor}`)[1]}%), 90%)` : `hsl(${HexToHSL(`#${secondaryColor}`)[0]}, calc(var(--saturation-factor, 1)*100%), 20%)`)}; - --primary-400: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL(`#${primaryColor}`)[1] / 100) * (100 + PrimarySatDiffs[400])) * 10) / 10 : HexToHSL(`#${primaryColor}`)[1]}%), 90%)` : `hsl(${HexToHSL(`#${secondaryColor}`)[0]}, calc(var(--saturation-factor, 1)*100%), 20%)`)}; - --primary-360: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL(`#${primaryColor}`)[1] / 100) * (100 + PrimarySatDiffs[360])) * 10) / 10 : HexToHSL(`#${primaryColor}`)[1]}%), 90%)` : `hsl(${HexToHSL(`#${secondaryColor}`)[0]}, calc(var(--saturation-factor, 1)*100%), 20%)`)};` : ""} -} -.theme-light { - --white-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 80, 90)}%; - --primary-130-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 80, 85)}%; - --primary-160-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[660])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 76.4, 82.5)}%; - --primary-200-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.min(HexToHSL("#" + tertiaryColor)[2] + 80, 80)}%; -} -.emptyPage_feb902, -.scrollerContainer_dda72c, -.container__03ec9, -.header__71942 { - background-color: unset !important; -} -.container__6b2e5, -.container__03ec9, -.header__71942 { - background: transparent !important; -}${(Math.round(HexToHSL("#" + primaryColor)[2]) > 80) ? `\n\n/*Primary*/ -.theme-dark .container_bd15da, -.theme-dark .body__616e6, -.theme-dark .toolbar__62fb5, -.theme-dark .container_e1387b, -.theme-dark .messageContent_abea64, -.theme-dark .attachButtonPlus_fd0021, -.theme-dark .username__0b0e7:not([style]), -.theme-dark .children_cde9af, -.theme-dark .buttonContainer__6de7e, -.theme-dark .listItem__48528, -.theme-dark .body__616e6 .caret__33d19, -.theme-dark .body__616e6 .titleWrapper_d6133e > h1, -.theme-dark .body__616e6 .icon_ae0b42 { - --white-500: black !important; - --interactive-normal: black !important; - --text-normal: black !important; - --text-muted: black !important; - --header-primary: black !important; - --header-secondary: black !important; -} - -.theme-dark .contentRegionScroller__9ae20 :not(.mtk1,.mtk2,.mtk3,.mtk4,.mtk5,.mtk6,.mtk7,.mtk8,.mtk9,.monaco-editor .line-numbers) { - --white-500: black !important; -} - -.theme-dark .container__26baa { - --channel-icon: black; -} - -.theme-dark .callContainer__1477d { - --white-500: ${(HexToHSL("#" + tertiaryColor)[2] > 80) ? "black" : "white"} !important; -} - -.theme-dark .channelTextArea_c2094b { - --text-normal: ${(HexToHSL("#" + primaryColor)[2] + 3.6 > 80) ? "black" : "white"}; -} - -.theme-dark .placeholder_dec8c7 { - --channel-text-area-placeholder: ${(HexToHSL("#" + primaryColor)[2] + 3.6 > 80) ? "black" : "white"}; - opacity: .6; -} - -.theme-dark .colorwaySelectorIcon { - background-color: black; -} - -.theme-dark .root_a28985 > .header__5e5a6 > h1 { - color: black; -} -/*End Primary*/`: ""}${(HexToHSL("#" + secondaryColor)[2] > 80) ? `\n\n/*Secondary*/ -.theme-dark .wrapper__3c6d5 *, -.theme-dark .sidebar_e031be *:not(.hasBanner__04337 *), -.theme-dark .members__573eb *:not([style]), -.theme-dark .sidebarRegionScroller__8113e *, -.theme-dark .header__8e271, -.theme-dark .lookFilled__950dd.colorPrimary_ebe632 { - --white-500: black !important; - --channels-default: black !important; - --channel-icon: black !important; - --interactive-normal: var(--white-500); - --interactive-hover: var(--white-500); - --interactive-active: var(--white-500); -} - -.theme-dark .channelRow__538ef { - background-color: var(--background-secondary); -} - -.theme-dark .channelRow__538ef * { - --channel-icon: black; -} - -.theme-dark #app-mount .activity_bafb94 { - --channels-default: var(--white-500) !important; -} - -.theme-dark .nameTag__77ab2 { - --header-primary: black !important; - --header-secondary: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 90%)" : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")} !important; -} - -.theme-dark .bannerVisible_ef30fe .headerContent__6fcc7 { - color: #fff; -} - -.theme-dark .embedFull__14919 { - --text-normal: black; -} -/*End Secondary*/`: ""}${HexToHSL("#" + tertiaryColor)[2] > 80 ? `\n\n/*Tertiary*/ -.theme-dark .winButton_f17fb6, -.theme-dark .searchBar__310d8 *, -.theme-dark .wordmarkWindows_ffbc5e, -.theme-dark .searchBar__5a20a *, -.theme-dark .searchBarComponent__8f95f { - --white-500: black !important; -} - -.theme-dark [style="background-color: var(--background-secondary);"] { - color: ${HexToHSL("#" + secondaryColor)[2] > 80 ? "black" : "white"}; -} - -.theme-dark .popout__24e32 > * { - --interactive-normal: black !important; - --header-secondary: black !important; -} - -.theme-dark .tooltip__7b090 { - --text-normal: black !important; -} -.theme-dark .children_cde9af .icon_ae0b42 { - color: var(--interactive-active) !important; -} -/*End Tertiary*/`: ""}${HexToHSL("#" + accentColor)[2] > 80 ? `\n\n/*Accent*/ -.selected_aded59 *, -.selected_ae80f7 *, -#app-mount .lookFilled__950dd.colorBrand__27d57:not(.buttonColor__7bad9), -.colorDefault_e361cf.focused_dcafb9, -.row__9e25f:hover, -.colorwayInfoIcon, -.checkmarkCircle_b1b1cc > circle { - --white-500: black !important; -} - -.ColorwaySelectorBtn:hover .vc-pallete-icon { - color: #000 !important; -} - -:root:root { - --mention-foreground: black !important; -} -/*End Accent*/`: ""}`; -} - -export function getAutoPresets(accentColor?: string) { - function hueRotation() { - return `:root:root { - --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)}; - --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[130]) * 10) / 10, 0)}%; - --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[160]) * 10) / 10, 0)}%; - --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[200]) * 10) / 10, 0)}%; - --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[230]) * 10) / 10, 0)}%; - --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[260]) * 10) / 10, 0)}%; - --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[300]) * 10) / 10, 0)}%; - --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[330]) * 10) / 10, 0)}%; - --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[345]) * 10) / 10, 0)}%; - --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[360]) * 10) / 10, 0)}%; - --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[400]) * 10) / 10, 0)}%; - --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[430]) * 10) / 10, 0)}%; - --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[460]) * 10) / 10, 0)}%; - --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; - --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[530]) * 10) / 10, 100)}%; - --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[560]) * 10) / 10, 100)}%; - --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[600]) * 10) / 10, 100)}%; - --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[630]) * 10) / 10, 100)}%; - --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[660]) * 10) / 10, 100)}%; - --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[700]) * 10) / 10, 100)}%; - --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[730]) * 10) / 10, 100)}%; - --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[760]) * 10) / 10, 100)}%; - --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[800]) * 10) / 10, 100)}%; - --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[830]) * 10) / 10, 100)}%; - --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[860]) * 10) / 10, 100)}%; - --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[900]) * 10) / 10, 100)}%; - --primary-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 7%; - --primary-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*10%) 13%; - --primary-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*10%) 13%; - --primary-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 15%; - --primary-645-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 16%; - --primary-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 18%; - --primary-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 21%; - --primary-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 24%; - --primary-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 24%; - --primary-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*11%) 24%; -}`; - } - - function accentSwap() { - return `:root:root { - --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)}; - --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[130]) * 10) / 10, 0)}%; - --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[160]) * 10) / 10, 0)}%; - --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[200]) * 10) / 10, 0)}%; - --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[230]) * 10) / 10, 0)}%; - --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[260]) * 10) / 10, 0)}%; - --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[300]) * 10) / 10, 0)}%; - --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[330]) * 10) / 10, 0)}%; - --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[345]) * 10) / 10, 0)}%; - --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[360]) * 10) / 10, 0)}%; - --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[400]) * 10) / 10, 0)}%; - --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[430]) * 10) / 10, 0)}%; - --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[460]) * 10) / 10, 0)}%; - --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; - --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[530]) * 10) / 10, 100)}%; - --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[560]) * 10) / 10, 100)}%; - --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[600]) * 10) / 10, 100)}%; - --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[630]) * 10) / 10, 100)}%; - --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[660]) * 10) / 10, 100)}%; - --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[700]) * 10) / 10, 100)}%; - --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[730]) * 10) / 10, 100)}%; - --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[760]) * 10) / 10, 100)}%; - --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[800]) * 10) / 10, 100)}%; - --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[830]) * 10) / 10, 100)}%; - --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[860]) * 10) / 10, 100)}%; - --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${Math.min(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[900]) * 10) / 10, 100)}%; -}`; - } - - function materialYou() { - return `:root:root { - --brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*90.5%) 56.5; - --brand-130-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*102.2%) 55.2%; - --brand-160-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*98.8%) 53.2%; - --brand-200-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*97.3%) 51.2%; - --brand-230-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*101.6%) 49.3%; - --brand-260-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.7%) 46.9%; - --brand-300-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.6%) 44.2%; - --brand-330-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*99.4%) 39.9%; - --brand-345-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*99.5%) 37.1%; - --brand-360-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.6%) 35.8%; - --brand-400-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.6%) 30.1%; - --brand-430-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100.1%) 28.1%; - --brand-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*99.9%) 25.8%; - --brand-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*100%) 23%; - --brand-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*75.2%) 17.1%; - --brand-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*50.1%) 10.7%; - --brand-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.2%) 2.4%; - --brand-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.2%) -3.5%; - --brand-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*42%) -8.4%; - --brand-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.8%) -15.8%; - --brand-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.4%) -17.4%; - --brand-760-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.6%) -19.5%; - --brand-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*42.7%) -22.3%; - --brand-830-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*42.6%) -26.8%; - --brand-860-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*41.6%) -32.1%; - --brand-900-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*47.5%) -38.6%; - --primary-800-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*10%) 10.8%; - --primary-730-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*8%) 14.4%; - --primary-700-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*16%) 18%; - --primary-660-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*14%) 12.4%; - --primary-645-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*14%) 14.9%; - --primary-630-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 16%; - --primary-600-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 12%; - --primary-560-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 15.6%; - --primary-530-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 19.2%; - --primary-500-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 22.8%; - --primary-460-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*12%) 50%; - --primary-430: hsl(${HexToHSL("#" + accentColor)[0]}, calc(var(--saturation-factor, 1)*12%), 90%); - --primary-400: hsl(${HexToHSL("#" + accentColor)[0]}, calc(var(--saturation-factor, 1)*12%), 90%); - --primary-360: hsl(${HexToHSL("#" + accentColor)[0]}, calc(var(--saturation-factor, 1)*12%), 90%); -} -.emptyPage_feb902, -.scrollerContainer_dda72c, -.container__03ec9, -.header__71942 { - background-color: unset !important; -}`; - } - - return { - hueRotation: { - name: "Hue Rotation", - id: "hueRotation", - preset: hueRotation - }, - accentSwap: { - name: "Accent Swap", - id: "accentSwap", - preset: accentSwap - }, - materialYou: { - name: "Material You", - id: "materialYou", - preset: materialYou - } - } as { [key: string]: { name: string, id: string, preset: () => string; }; }; -} - -export function getPreset(primaryColor?: string, secondaryColor?: string, tertiaryColor?: string, accentColor?: string): { [preset: string]: { name: string, preset: (...args: any) => string | { full: string, base: string; }, id: string, colors: string[]; }; } { - function cyanLegacy(discordSaturation = false) { - return `:root:root { - --cyan-accent-color: #${accentColor}; - --cyan-background-primary: hsl(${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%/40%); - --cyan-background-secondary: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.min(HexToHSL("#" + tertiaryColor)[2] + (3.6 * 2), 100)}%); -}`; - } - - function cyan(discordSaturation = false) { - return `:root:root { - --cyan-accent-color: #${accentColor}; - --cyan-background-primary: hsl(${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%/60%); - --cyan-second-layer: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.min(HexToHSL("#" + tertiaryColor)[2] + (3.6 * 2), 100)}%/60%); -}`; - } - - function nexusRemastered(discordSaturation = false) { - return `:root:root { - --nexus-accent-color: #${accentColor}; - --nexus-background-secondary: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%); - --nexus-background-elevated: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%); - --nexus-background-floating: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%); - --nexus-background-tertiary: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%); - --home-background: hsl(${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%); - --nexus-background-primary: hsl(${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%); - --primary-800-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%; - --primary-730-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[730])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - 3.6, 0)}%; - --primary-700-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%; - --primary-660-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[660])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 3.6, 0)}%; - --primary-645-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[645])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 1.1, 0)}%; - --primary-630-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${HexToHSL("#" + secondaryColor)[2]}%; - --primary-600-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%; - --primary-560-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 3.6, 100)}%; - --primary-530-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[530])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 2), 100)}%; - --primary-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[500])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)}%; - --primary-200: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[200])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")} -} -.theme-dark { - --background-tertiary: var(--primary-700) !important; -} -.theme-light { - --background-tertiary: var(--primary-200) !important; -}`; - } - - function modular(discordSaturation = false) { - return `:root:root { - --brand-experiment: #${accentColor}; - --primary-800-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[800])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - (3.6 * 2), 0)}%; - --primary-730-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + tertiaryColor)[1] / 100) * (100 + PrimarySatDiffs[730])) * 10) / 10 : HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(HexToHSL("#" + tertiaryColor)[2] - 3.6, 0)}%; - --primary-700-hsl: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${HexToHSL("#" + tertiaryColor)[2]}%; - --primary-660-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[660])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 3.6, 0)}%; - --primary-645-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + secondaryColor)[1] / 100) * (100 + PrimarySatDiffs[645])) * 10) / 10 : HexToHSL("#" + secondaryColor)[1]}%) ${Math.max(HexToHSL("#" + secondaryColor)[2] - 1.1, 0)}%; - --primary-630-hsl: ${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${HexToHSL("#" + secondaryColor)[2]}%; - --primary-600-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%; - --primary-560-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 3.6, 100)}%; - --primary-530-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[530])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 2), 100)}% !important; - --primary-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[500])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)}% !important; - --primary-330: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[330])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")}; - --primary-360: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[360])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")}; - --primary-400: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[400])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")} -}`; - } - - function virtualBoy(discordSaturation = false) { - return `:root:root { - --VBaccent: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + accentColor)[1]}%) ${HexToHSL("#" + accentColor)[2]}%; - --VBaccent-muted: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.max(((HexToHSL("#" + tertiaryColor)[2]) - 10), 0)}%; - --VBaccent-dimmest: ${HexToHSL("#" + tertiaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + tertiaryColor)[1]}%) ${Math.min((HexToHSL("#" + tertiaryColor)[2] + (3.6 * 5) - 3), 100)}%; -}`; - } - - function solana(discordSaturation = false) { - return `:root:root { - --accent-hue: ${HexToHSL("#" + accentColor)[0]}; - --accent-saturation: calc(var(--saturation-factor, 1)${HexToHSL("#" + accentColor)[1]}%); - --accent-brightness: ${HexToHSL("#" + accentColor)[2]}%; - --background-accent-hue: ${HexToHSL("#" + primaryColor)[0]}; - --background-accent-saturation: calc(var(--saturation-factor, 1)${HexToHSL("#" + primaryColor)[1]}%); - --background-accent-brightness: ${HexToHSL("#" + primaryColor)[2]}%; - --background-overlay-opacity: 0%; -}`; - } - - function gradientType1(discordSaturation = false) { - return { - full: `${gradientBase(accentColor, discordSaturation)} - :root:root { - --custom-theme-background: linear-gradient(239.16deg, #${primaryColor} 10.39%, #${secondaryColor} 26.87%, #${tertiaryColor} 48.31%, hsl(${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 3.6, 100)}%) 64.98%, #${primaryColor} 92.5%); - }`, - base: `239.16deg, #${primaryColor} 10.39%, #${secondaryColor} 26.87%, #${tertiaryColor} 48.31%, hsl(${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 3.6, 100)}%) 64.98%, #${primaryColor} 92.5%` - }; - } - - function gradientType2(discordSaturation = false) { - return { - full: `${gradientBase(accentColor, discordSaturation)} - :root:root { - --custom-theme-background: linear-gradient(48.17deg, #${primaryColor} 11.21%, #${secondaryColor} 61.92%); - }`, base: `48.17deg, #${primaryColor} 11.21%, #${secondaryColor} 61.92%` - }; - } - - return { - default: { - name: "Default", - preset: generateCss, - id: "default", - colors: ["accent", "primary", "secondary", "tertiary"] - }, - cyan: { - name: "Cyan", - preset: cyan, - id: "cyan", - colors: ["accent", "primary", "secondary"] - }, - cyanLegacy: { - name: "Cyan 1 (Legacy)", - preset: cyanLegacy, - id: "cyanLegacy", - colors: ["accent", "primary", "secondary"] - }, - nexusRemastered: { - name: "Nexus Remastered", - preset: nexusRemastered, - id: "nexusRemastered", - colors: ["accent", "primary", "secondary", "tertiary"] - }, - virtualBoy: { - name: "Virtual Boy", - preset: virtualBoy, - id: "virtualBoy", - colors: ["accent", "tertiary"] - }, - modular: { - name: "Modular", - preset: modular, - id: "modular", - colors: ["accent", "primary", "secondary", "tertiary"] - }, - solana: { - name: "Solana", - preset: solana, - id: "solana", - colors: ["accent", "primary"] - }, - gradientType1: { - name: "Gradient Type 1", - preset: gradientType1, - id: "gradientType1", - colors: ["accent", "primary", "secondary", "tertiary"] - }, - gradientType2: { - name: "Gradient Type 2", - preset: gradientType2, - id: "gradientType2", - colors: ["accent", "primary", "secondary"] - }, - hueRotation: { - name: "Hue Rotation", - preset: getAutoPresets(accentColor).hueRotation.preset, - id: "hueRotation", - colors: ["accent"] - }, - accentSwap: { - name: "Accent Swap", - preset: getAutoPresets(accentColor).accentSwap.preset, - id: "accentSwap", - colors: ["accent"] - }, - materialYou: { - name: "Material You", - preset: getAutoPresets(accentColor).materialYou.preset, - id: "materialYou", - colors: ["accent"] - } - }; -} -export const gradientPresetIds = [ - "gradientType1", - "gradientType2" -]; diff --git a/src/equicordplugins/discordColorways/index.tsx b/src/equicordplugins/discordColorways/index.tsx deleted file mode 100644 index 3c344c876..000000000 --- a/src/equicordplugins/discordColorways/index.tsx +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import * as DataStore from "@api/DataStore"; -import { addAccessory, removeAccessory } from "@api/MessageAccessories"; -import { addServerListElement, removeServerListElement, ServerListRenderPosition } from "@api/ServerList"; -import { disableStyle, enableStyle } from "@api/Styles"; -import { Flex } from "@components/Flex"; -import { Devs } from "@utils/constants"; -import { ModalProps, openModal } from "@utils/modal"; -import definePlugin from "@utils/types"; -import { findByProps } from "@webpack"; -import { - Button, - Clipboard, - Forms, - Heading, - i18n, - SettingsRouter, - Toasts -} from "@webpack/common"; -import { CSSProperties } from "react"; -import { Plugins } from "Vencord"; - -import AutoColorwaySelector from "./components/AutoColorwaySelector"; -import ColorPickerModal from "./components/ColorPicker"; -import ColorwaysButton from "./components/ColorwaysButton"; -import CreatorModal from "./components/CreatorModal"; -import Selector from "./components/Selector"; -import OnDemandWaysPage from "./components/SettingsTabs/OnDemandPage"; -import SettingsPage from "./components/SettingsTabs/SettingsPage"; -import SourceManager from "./components/SettingsTabs/SourceManager"; -import Store from "./components/SettingsTabs/Store"; -import Spinner from "./components/Spinner"; -import { defaultColorwaySource } from "./constants"; -import { generateCss, getAutoPresets } from "./css"; -import style from "./style.css?managed"; -import { ColorPickerProps, ColorwayObject } from "./types"; -import { colorToHex, hexToString } from "./utils"; - -export let ColorPicker: React.FunctionComponent = () => { - return ; -}; - -(async function () { - const [ - customColorways, - colorwaySourceFiles, - showColorwaysButton, - onDemandWays, - onDemandWaysTintedText, - useThinMenuButton, - onDemandWaysDiscordSaturation, - onDemandWaysOsAccentColor, - activeColorwayObject, - selectorViewMode, - showLabelsInSelectorGridView - ] = await DataStore.getMany([ - "customColorways", - "colorwaySourceFiles", - "showColorwaysButton", - "onDemandWays", - "onDemandWaysTintedText", - "useThinMenuButton", - "onDemandWaysDiscordSaturation", - "onDemandWaysOsAccentColor", - "activeColorwayObject", - "selectorViewMode", - "showLabelsInSelectorGridView" - ]); - - const defaults = [ - { name: "showColorwaysButton", value: showColorwaysButton, default: false }, - { name: "onDemandWays", value: onDemandWays, default: false }, - { name: "onDemandWaysTintedText", value: onDemandWaysTintedText, default: true }, - { name: "useThinMenuButton", value: useThinMenuButton, default: false }, - { name: "onDemandWaysDiscordSaturation", value: onDemandWaysDiscordSaturation, default: false }, - { name: "onDemandWaysOsAccentColor", value: onDemandWaysOsAccentColor, default: false }, - { name: "activeColorwayObject", value: activeColorwayObject, default: { id: null, css: null, sourceType: null, source: null } }, - { name: "selectorViewMode", value: selectorViewMode, default: "grid" }, - { name: "showLabelsInSelectorGridView", value: showLabelsInSelectorGridView, default: false } - ]; - - defaults.forEach(({ name, value, default: def }) => { - if (!value) DataStore.set(name, def); - }); - - if (customColorways) { - if (!customColorways[0].colorways) { - DataStore.set("customColorways", [{ name: "Custom", colorways: customColorways }]); - } - } else { - DataStore.set("customColorways", []); - } - - if (colorwaySourceFiles) { - if (typeof colorwaySourceFiles[0] === "string") { - DataStore.set("colorwaySourceFiles", colorwaySourceFiles.map((sourceURL: string, i: number) => { - return { name: sourceURL === defaultColorwaySource ? "Project Colorway" : `Source #${i}`, url: sourceURL }; - })); - } - } else { - DataStore.set("colorwaySourceFiles", [{ - name: "Project Colorway", - url: defaultColorwaySource - }]); - } - -})(); - -export const ColorwayCSS = { - get: () => document.getElementById("activeColorwayCSS")!.textContent || "", - set: (e: string) => { - if (!document.getElementById("activeColorwayCSS")) { - document.head.append(Object.assign(document.createElement("style"), { - id: "activeColorwayCSS", - textContent: e - })); - } else document.getElementById("activeColorwayCSS")!.textContent = e; - }, - remove: () => document.getElementById("activeColorwayCSS")!.remove(), -}; - -export const versionData = { - pluginVersion: "5.7.0", - creatorVersion: "1.20", -}; - -export default definePlugin({ - name: "DiscordColorways", - description: "A plugin that offers easy access to simple color schemes/themes for Discord, also known as Colorways", - authors: [{ - name: "DaBluLite", - id: 582170007505731594n - }, Devs.ImLvna], - dependencies: ["ServerListAPI", "MessageAccessoriesAPI"], - pluginVersion: versionData.pluginVersion, - creatorVersion: versionData.creatorVersion, - toolboxActions: { - "Change Colorway": () => openModal(props => ), - "Open Colorway Creator": () => openModal(props => ), - "Open Color Stealer": () => openModal(props => ), - "Open Settings": () => SettingsRouter.open("ColorwaysSettings"), - "Open On-Demand Settings": () => SettingsRouter.open("ColorwaysOnDemand"), - "Manage Colorways...": () => SettingsRouter.open("ColorwaysManagement"), - "Change Auto Colorway Preset": async () => { - const [ - activeAutoPreset, - activeColorwayObject - ] = await DataStore.getMany([ - "activeAutoPreset", - "activeColorwayObject" - ]); - openModal((props: ModalProps) => { - if (activeColorwayObject.id === "Auto") { - const demandedColorway = getAutoPresets(colorToHex(getComputedStyle(document.body).getPropertyValue("--os-accent-color")))[autoPresetId].preset(); - DataStore.set("activeColorwayObject", { id: "Auto", css: demandedColorway, sourceType: "online", source: null }); - ColorwayCSS.set(demandedColorway); - } - }} />); - } - }, - patches: [ - // Credits to Kyuuhachi for the BetterSettings plugin patches - { - find: "this.renderArtisanalHack()", - replacement: { - match: /createPromise:\(\)=>([^:}]*?),webpackId:"\d+",name:(?!="CollectiblesShop")"[^"]+"/g, - replace: "$&,_:$1", - predicate: () => true - } - - }, - { - find: "Messages.USER_SETTINGS_WITH_BUILD_OVERRIDE.format", - replacement: { - match: /(?<=(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?openContextMenuLazy.{0,100}?(await Promise\.all[^};]*?\)\)).*?,)(?=\1\(this)/, - replace: "(async ()=>$2)()," - }, - predicate: () => true - }, - { - find: "colorPickerFooter:", - replacement: { - match: /function (\i).{0,200}colorPickerFooter:/, - replace: "$self.ColorPicker=$1;$&", - }, - }, - { - find: "Messages.ACTIVITY_SETTINGS", - replacement: { - match: /\{section:(\i\.\i)\.HEADER,\s*label:(\i)\.\i\.Messages\.APP_SETTINGS/, - replace: "...$self.makeSettingsCategories($1),$&" - } - }, - { - find: "Messages.ACTIVITY_SETTINGS", - replacement: { - match: /(?<=section:(.{0,50})\.DIVIDER\}\))([,;])(?=.{0,200}(\i)\.push.{0,100}label:(\i)\.header)/, - replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}` - } - }, - { - find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL", - replacement: { - match: /(?<=function\((\i),\i\)\{)(?=let \i=Object.values\(\i.UserSettingsSections\).*?(\i)\.default\.open\()/, - replace: "$2.default.open($1);return;" - } - } - ], - - set ColorPicker(e) { - ColorPicker = e; - }, - - isRightSpot({ header, settings }: { header?: string; settings?: string[]; }) { - const firstChild = settings?.[0]; - // lowest two elements... sanity backup - if (firstChild === "LOGOUT" || firstChild === "SOCIAL_LINKS") return true; - - const settingsLocation = "belowNitro"; - - if (!header) return; - - const names = { - top: i18n.Messages.USER_SETTINGS, - aboveNitro: i18n.Messages.BILLING_SETTINGS, - belowNitro: i18n.Messages.APP_SETTINGS, - aboveActivity: i18n.Messages.ACTIVITY_SETTINGS - }; - return header === names[settingsLocation]; - }, - - patchedSettings: new WeakSet(), - - addSettings(elements: any[], element: { header?: string; settings: string[]; }, sectionTypes: Record) { - if (this.patchedSettings.has(elements) || !this.isRightSpot(element)) return; - - this.patchedSettings.add(elements); - - elements.push(...this.makeSettingsCategories(sectionTypes)); - }, - - makeSettingsCategories(SectionTypes: Record) { - const { headerText, header } = findByProps("headerText", "header", "separator"); - return [ - { - section: SectionTypes.CUSTOM, - label: "Discord Colorways", - className: "vc-settings-header", - element: () =>
- - Discord Colorways - - - v{(Plugins.plugins.DiscordColorways as any).pluginVersion} - -
- }, - { - section: "ColorwaysSelector", - label: "Colorways", - element: () => new Promise(() => true), transitionState: 1 }} />, - className: "dc-colorway-selector" - }, - { - section: "ColorwaysSettings", - label: "Settings", - element: SettingsPage, - className: "dc-colorway-settings" - }, - { - section: "ColorwaysSourceManager", - label: "Sources", - element: SourceManager, - className: "dc-colorway-sources-manager" - }, - { - section: "ColorwaysOnDemand", - label: "On-Demand", - element: OnDemandWaysPage, - className: "dc-colorway-ondemand" - }, - { - section: "ColorwaysStore", - label: "Store", - element: Store, - className: "dc-colorway-store" - }, - { - section: SectionTypes.DIVIDER - } - ].filter(Boolean); - }, - - ColorwaysButton: () => , - - async start() { - addServerListElement(ServerListRenderPosition.In, this.ColorwaysButton); - - enableStyle(style); - ColorwayCSS.set((await DataStore.get("activeColorwayObject") as ColorwayObject).css || ""); - - addAccessory("colorways-btn", props => { - if (String(props.message.content).match(/colorway:[0-9a-f]{0,100}/)) { - return - {String(props.message.content).match(/colorway:[0-9a-f]{0,100}/g)?.map((colorID: string) => { - colorID = hexToString(colorID.split("colorway:")[1]); - return
-
- {(() => { - if (colorID) { - if (!colorID.includes(",")) { - throw new Error("Invalid Colorway ID"); - } else { - return colorID.split("|").filter(string => string.includes(",#"))[0].split(/,#/).map((color: string) =>
); - } - } else return null; - })()} -
-
- Colorway{/n:([A-Za-z0-9]+( [A-Za-z0-9]+)+)/i.exec(colorID) ? `: ${/n:([A-Za-z0-9]+( [A-Za-z0-9]+)+)/i.exec(colorID)![1]}` : ""} - - - - - -
-
; - })} - ; - } else { - return null; - } - }); - }, - stop() { - removeServerListElement(ServerListRenderPosition.In, this.ColorwaysButton); - disableStyle(style); - ColorwayCSS.remove(); - removeAccessory("colorways-btn"); - }, -}); diff --git a/src/equicordplugins/discordColorways/style.css b/src/equicordplugins/discordColorways/style.css deleted file mode 100644 index 03092ab49..000000000 --- a/src/equicordplugins/discordColorways/style.css +++ /dev/null @@ -1,1379 +0,0 @@ -/* 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 { - width: 56px; - cursor: pointer; - display: flex; - flex-direction: column; - position: relative; - align-items: center; - transition: 170ms ease; -} - -.discordColorway:hover { - filter: brightness(.8); -} - -.discordColorwayPreviewColorContainer { - display: flex; - flex-flow: wrap; - flex-direction: row; - overflow: hidden; - border-radius: 50%; - width: 56px; - height: 56px; - box-shadow: 0 0 0 1.5px var(--interactive-normal); - box-sizing: border-box; -} - -.discordColorwayPreviewColor { - width: 50%; - height: 50%; -} - -.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(2)))>.discordColorwayPreviewColor { - height: 100%; - width: 100%; -} - -.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor { - height: 100%; -} - -.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(4)))>.discordColorwayPreviewColor:nth-child(3) { - width: 100%; -} - -.ColorwaySelectorWrapper { - position: relative; - display: flex; - gap: 16px 28px; - width: 100%; - flex-wrap: wrap; - padding: 2px; - scrollbar-width: none !important; -} - -.ColorwaySelectorWrapper::-webkit-scrollbar { - width: 0; -} - -.colorwaySelectorModal { - width: 100% !important; - min-width: 596px !important; -} - -.colorwaySelectorModalContent { - display: flex; - flex-direction: column; - width: 100%; - max-width: 596px; - overflow: visible !important; - padding: 0 16px !important; -} - -.ColorwaySelectorBtnContainer { - position: relative; - margin: 0 0 8px; - display: flex; - -webkit-box-pack: center; - -ms-flex-pack: center; - justify-content: center; - width: 72px; -} - -.colorwayInfoIconContainer { - height: 22px; - width: 22px; - background-color: var(--brand-500); - position: absolute; - top: -1px; - left: -1px; - border-radius: 50%; - opacity: 0; - z-index: +1; - color: var(--white-500); - padding: 1px; - box-sizing: border-box; -} - -.colorwayInfoIconContainer:hover { - background-color: var(--brand-experiment-560); -} - -.discordColorway:hover .colorwayInfoIconContainer { - opacity: 1; - transition: .15s; -} - -.colorwayCreator-swatch { - display: flex; - align-items: center; - justify-content: center; - height: 50px; - border-radius: 4px; - box-sizing: border-box; - border: none; - width: 100%; - position: relative; - color: #fff; -} - -.colorwayCreator-swatchName { - color: currentcolor; - pointer-events: none; -} - -.colorwayCreator-colorPreviews { - width: 100%; - height: fit-content; - display: flex; - flex-direction: row; - justify-content: space-between; - gap: 8px; - position: relative; - box-sizing: border-box; -} - -.colorwayCreator-colorInput { - width: 1px; - height: 1px; - opacity: 0; - position: absolute; - pointer-events: none; -} - -.colorwayCreator-menuWrapper { - display: flex; - flex-direction: column; - gap: 8px; - padding: 20px 16px !important; - overflow: visible !important; - min-height: unset; -} - -.colorwayCreator-modal { - width: 620px !important; - max-width: 620px; - max-height: unset !important; -} - -.colorways-creator-module-warning { - color: var(--brand-500); -} - -.colorwayCreator-colorPreviews>[class^="colorSwatch"], -.colorwayCreator-colorPreviews>[class^="colorSwatch"]>[class^="swatch"] { - width: 100%; - border: none; - position: relative; -} - -.colorwaysPicker-colorLabel { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - pointer-events: none; -} - -.colorwayCreator-colorPreviews>.colorSwatch-2UxEuG:has([fill="var(--primary-530)"])>.colorwaysPicker-colorLabel { - color: var(--primary-530); -} - -.colorwaySelector-noDisplay { - display: none; -} - -.colorwayInfo-wrapper { - display: flex; - flex-direction: column; - color: var(--header-primary); -} - -.colorwayInfo-colorSwatches { - width: 100%; - height: 46px; - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - margin: 12px 0; - gap: 8px; -} - -.colorwayInfo-colorSwatch { - display: flex; - width: 100%; - height: 38px; - border-radius: 3px; - cursor: pointer; - position: relative; - transition: .15s; -} - -.colorwayInfo-colorSwatch:hover { - filter: brightness(.8); -} - -.colorwayInfo-row { - font-weight: 400; - font-size: 20px; - color: var(--header-secondary); - margin-bottom: 4px; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - gap: 8px; - border-radius: 4px; - background-color: var(--background-secondary); - padding: 8px 12px; -} - -.colorwayInfo-css { - flex-direction: column; - align-items: start; -} - -.colorwayInfo-cssCodeblock { - border-radius: 4px; - border: 1px solid var(--background-accent); - padding: 3px 6px; - white-space: pre; - max-height: 400px; - overflow: auto; - font-size: 0.875rem; - line-height: 1.125rem; - width: 100%; - box-sizing: border-box; -} - -.colorwayInfo-cssCodeblock::-webkit-scrollbar { - width: 8px; - height: 8px; -} - -.colorwayInfo-cssCodeblock::-webkit-scrollbar-corner { - background-color: transparent; -} - -.colorwayInfo-cssCodeblock::-webkit-scrollbar-thumb { - background-color: var(--scrollbar-auto-thumb); - min-height: 40px; -} - -.colorwayInfo-cssCodeblock::-webkit-scrollbar-thumb, -.colorwayInfo-cssCodeblock::-webkit-scrollbar-track { - border: 2px solid transparent; - background-clip: padding-box; - border-radius: 8px; -} - -.colorwayInfo-cssCodeblock::-webkit-scrollbar-track { - margin-bottom: 8px; -} - -.colorwaysCreator-settingCat { - display: flex; - flex-direction: column; - padding: 10px; - border-radius: 4px; - background-color: var(--background-secondary); - box-sizing: border-box; - color: var(--header-secondary); - max-height: 250px; - overflow: hidden overlay; -} - -.colorwaysColorpicker-settingCat { - padding: 0; - background-color: transparent; - border-radius: 0; -} - -.colorwaysColorpicker-search { - width: 100%; -} - -.colorwaysCreator-settingItm { - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - border-radius: 4px; - cursor: pointer; - box-sizing: border-box; - padding: 8px; - justify-content: space-between; -} - -.colorwaysCreator-settingItm:hover { - background-color: var(--background-modifier-hover); -} - -.colorwaysCreator-settingsList .colorwaysCreator-preset { - justify-content: start; - gap: 8px; -} - -.colorwaysCreator-settingsList { - overflow: auto; - max-height: 185px; -} - -.colorwaysCreator-settingCat-collapsed>:is(.colorwaysCreator-settingsList, .colorwayInfo-cssCodeblock), -.colorwaysColorpicker-collapsed { - display: none !important; -} - -.colorwayColorpicker { - display: flex; - flex-direction: column; - padding: 20px 16px !important; - width: 620px !important; - min-height: unset; -} - -.colorwaysCreator-noHeader { - margin-top: 12px; - margin-bottom: 12px; -} - -.colorwaysCreator-noMinHeight { - min-height: unset; - height: fit-content; -} - -.colorwaysPreview-wrapper { - display: flex; - flex-direction: column; - width: 100%; - height: 270px; - flex: 1 0 auto; - border-radius: 4px; - overflow: hidden; -} - -.colorwaysPreview-modal { - max-width: unset !important; - max-height: unset !important; - width: fit-content; - height: fit-content; -} - -.colorwaysPreview-titlebar { - height: 22px; - width: 100%; - display: flex; - flex: 1 0 auto; -} - -.colorwaysPreview-body { - height: 100%; - width: 100%; - display: flex; -} - -.colorwayPreview-guilds { - width: 72px; - height: 100%; - display: flex; - flex: 1 0 auto; - padding-top: 4px; - flex-direction: column; -} - -.colorwayPreview-channels { - width: 140px; - height: 100%; - display: flex; - flex-direction: column-reverse; - border-top-left-radius: 8px; - flex: 1 0 auto; -} - -.colorwaysPreview-wrapper:fullscreen .colorwayPreview-channels { - width: 240px; -} - -.colorwayPreview-chat { - width: 100%; - height: 100%; - display: flex; - position: relative; - flex-direction: column-reverse; -} - -.colorwayPreview-userArea { - width: 100%; - height: 40px; - display: flex; - flex: 1 0 auto; -} - -.colorwaysPreview-wrapper:fullscreen .colorwayPreview-userArea { - height: 52px; -} - -.colorwaysPreview { - display: flex; - flex-direction: column; - padding: 10px; - gap: 5px; - border-radius: 4px; - background-color: var(--background-secondary); - box-sizing: border-box; - color: var(--header-secondary); - overflow: hidden overlay; - margin-bottom: 4px; -} - -.colorwaysPreview-collapsed .colorwaysPreview-wrapper { - display: none; -} - -.colorwayInfo-lastCat, -.colorwaysCreator-lastCat { - margin-bottom: 12px; -} - -.colorwayPreview-guild { - width: 100%; - margin-bottom: 8px; - display: flex; - justify-content: center; -} - -.colorwayPreview-guildItem { - cursor: pointer; - width: 48px; - height: 48px; - border-radius: 50px; - transition: .2s ease; - display: flex; - justify-content: center; - align-items: center; -} - -.colorwayPreview-guildItem:hover { - border-radius: 16px; -} - -.colorwayPreview-guildSeparator { - width: 32px; - height: 2px; - opacity: .48; - border-radius: 1px; -} - -.colorwayToolbox-listItem { - align-items: center; - border-radius: 4px; - color: var(--interactive-normal); - display: flex; - flex-direction: column; - gap: 12px; - background-color: transparent !important; - width: calc(564px / 4); - cursor: default; - float: left; - box-sizing: border-box; - margin: 0; - padding: 0; -} - -.colorwayToolbox-listItemSVG { - padding: 19px; - overflow: visible; - border-radius: 50%; - background-color: var(--background-tertiary); - border: 1px solid transparent; - display: flex; - justify-content: center; - align-items: center; - transition: .15s ease; - cursor: pointer; - color: var(--interactive-normal); -} - -.colorwayToolbox-listItem:hover { - color: var(--interactive-normal) !important; -} - -.colorwayToolbox-listItemSVG:hover { - border-color: var(--brand-500); - background-color: var(--brand-experiment-15a); - color: var(--interactive-hover) !important; -} - -.colorwayToolbox-title { - align-items: center; - display: flex; - text-transform: uppercase; - margin-top: 2px; - padding-bottom: 8px; - margin-bottom: 0; -} - -.colorwayToolbox-list { - box-sizing: border-box; - height: 100%; - display: flex; - flex-direction: column; - gap: 12px; - overflow: hidden; -} - -.colorwayPreview-chatBox { - height: 32px; - border-radius: 6px; - margin: 8px; - margin-bottom: 12px; - margin-top: 0; - flex: 1 1 auto; -} - -.colorwayPreview-filler { - width: 100%; - height: 100%; - flex: 0 1 auto; -} - -.colorwayPreview-topShadow { - box-shadow: 0 1px 0 hsl(var(--primary-900-hsl)/20%), 0 1.5px 0 hsl(var(--primary-860-hsl)/5%), 0 2px 0 hsl(var(--primary-900-hsl)/5%); - width: 100%; - height: 32px; - font-family: var(--font-display); - font-weight: 500; - padding: 12px 16px; - box-sizing: border-box; - align-items: center; - display: flex; - flex: 1 0 auto; -} - -.colorwayPreview-channels>.colorwayPreview-topShadow { - border-top-left-radius: 8px; -} - -.colorwayPreview-channels>.colorwayPreview-topShadow:hover { - background-color: hsl(var(--primary-500-hsl)/30%); -} - -.colorwaysPreview-wrapper:fullscreen .colorwayPreview-topShadow { - height: 48px; -} - -.colorwaysPreview-wrapper:fullscreen .colorwayPreview-chatBox { - height: 44px; - border-radius: 8px; - margin: 16px; - margin-bottom: 24px; -} - -.colorwaysBtn-tooltipContent { - font-weight: 600; - font-size: 16px; - line-height: 20px; -} - -.colorwaySelector-headerIcon { - box-sizing: border-box; - width: 100%; - height: 100%; - transition: transform .1s ease-out, opacity .1s ease-out; - color: var(--interactive-normal); -} - -.colorwaySelector-header { - align-items: center; - justify-content: center; - padding-bottom: 0; - box-shadow: none !important; -} - -.colorwaySelector-search { - width: 100%; -} - -.colorwaySelector-sources { - flex: 0 0 auto; - margin-right: auto; - color: var(--button-outline-primary-text); - border-color: var(--button-outline-primary-border); -} - -.colorwaySelector-sources:hover { - background-color: var(--button-outline-primary-background-hover); - border-color: var(--button-outline-primary-border-hover); - color: var(--button-outline-primary-text-hover); -} - -.colorwaySelector-headerBtn { - position: absolute; - top: 64px; - right: 20px; -} - -.theme-light .colorwaySelector-pill_selected { - border-color: var(--brand-500) !important; - background-color: var(--brand-experiment-160) !important; -} - -.theme-dark .colorwaySelector-pill_selected { - border-color: var(--brand-500) !important; - background-color: var(--brand-experiment-15a) !important; -} - -.colorwaysTooltip-tooltipPreviewRow { - display: flex; - align-items: center; - margin-top: 8px; -} - -.colorwayCreator-colorPreview { - width: 100%; - border-radius: 4px; - height: 50px; - display: flex; - justify-content: center; - align-items: center; -} - -.colorwaysCreator-colorPreviewItm .colorwayCreator-colorPreviews { - padding: 0; - background-color: transparent; - border-radius: 0; -} - -.colorwaysCreator-colorPreviewItm { - flex-direction: column; - align-items: start; -} - -.colorwaysTooltip-header { - background-color: var(--background-primary); - padding: 2px 8px; - border-radius: 16px; - height: min-content; - color: var(--header-primary); - margin-bottom: 2px; - display: inline-flex; - margin-left: -4px; -} - -.colorwaySelector-pillSeparator { - height: 24px; - width: 1px; - background-color: var(--primary-400); -} - -.colorwaysSelector-changelog { - font-weight: 400; - font-size: 20px; - color: var(--header-secondary); - border-radius: 4px; - background-color: var(--background-secondary); - padding: 8px 12px; -} - -.colorwaysChangelog-li { - position: relative; - font-size: 16px; - line-height: 20px; -} - -.colorwaysChangelog-li::before { - content: ""; - position: absolute; - top: 10px; - left: -15px; - width: 6px; - height: 6px; - margin-top: -4px; - margin-left: -3px; - border-radius: 50%; - opacity: .3; -} - -.theme-dark .colorwaysChangelog-li::before { - background-color: hsl(216deg calc(var(--saturation-factor, 1)*9.8%) 90%); -} - -.theme-light .colorwaysChangelog-li::before { - background-color: hsl(223deg calc(var(--saturation-factor, 1)*5.8%) 52.9%); -} - -.ColorwaySelectorWrapper .colorwayToolbox-list { - width: 100%; -} - -.colorwaysToolbox-label { - border-radius: 20px; - box-sizing: border-box; - color: var(--text-normal); - transition: .15s ease; - width: 100%; - margin-left: 0; - height: fit-content; - text-align: center; - overflow: hidden; - text-overflow: ellipsis; - white-space: wrap; - cursor: default; - max-height: 2rem; - padding: 0 8px; -} - -.colorwaysSelector-changelogHeader { - font-weight: 700; - font-size: 16px; - line-height: 20px; - text-transform: uppercase; - position: relative; - display: flex; - align-items: center; -} - -.colorwaysSelector-changelogHeader::after { - content: ""; - height: 1px; - flex: 1 1 auto; - margin-left: 4px; - opacity: .6; - background-color: currentcolor; -} - -.colorwaysSelector-changelogHeader_added { - color: var(--text-positive); -} - -.colorwaysSelector-changelogHeader_fixed { - color: hsl(359deg calc(var(--saturation-factor, 1)*87.3%) 59.8%); -} - -.colorwaysSelector-changelogHeader_changed { - color: var(--text-warning); -} - -.is-mobile .colorwaySelectorModal, -.is-mobile .colorwayCreator-modal { - width: 100vw !important; - box-sizing: border-box; - min-width: unset; - border-radius: 0; - height: 100vh; - max-height: unset; - border: none; -} - -.is-mobile .colorwaySelectorModalContent { - box-sizing: border-box; - width: 100vw; -} - -.is-mobile .colorwaySelector-doublePillBar { - flex-direction: column-reverse; - align-items: end; -} - -.is-mobile .colorwaySelector-doublePillBar>.colorwaySelector-pillWrapper:first-child { - width: 100%; - gap: 4px; - overflow-x: auto; - justify-content: space-between; -} - -.is-mobile .colorwaySelector-doublePillBar>.colorwaySelector-pillWrapper:first-child>.colorwaySelector-pill { - border-radius: 0; - border-top: none; - border-left: none; - border-right: none; - background-color: transparent; - width: 100%; - justify-content: center; - flex: 0 0 min-content; -} - -.is-mobile .colorwaySelector-doublePillBar>.colorwaySelector-pillWrapper:first-child>.colorwaySelector-pillSeparator { - display: none; -} - -.is-mobile .layer-fP3xEz:has(.colorwaySelectorModal, .colorwayCreator-modal) { - padding: 0; -} - -.is-mobile .ColorwaySelectorWrapper { - justify-content: space-around; - gap: 10px; -} - -#colorwaySelector-pill_closeSelector { - display: none !important; -} - -.is-mobile #colorwaySelector-pill_closeSelector { - display: flex !important; -} - -.colorwaysBtn-spinner { - display: flex; - justify-content: center; - align-items: center; - width: 100%; -} - -.colorwaysBtn-spinnerInner { - transform: rotate(280deg); - position: relative; - display: inline-block; - width: 32px; - height: 32px; - contain: paint; -} - -@keyframes spinner-spinning-circle-rotate { - 100% { - transform: rotate(1turn); - } -} - -@keyframes spinner-spinning-circle-dash { - 0% { - stroke-dasharray: 1, 200; - stroke-dashoffset: 0; - } - - 50% { - stroke-dasharray: 130, 200; - } - - 100% { - stroke-dasharray: 130, 200; - stroke-dashoffset: -124; - } -} - -.colorwaysBtn-spinnerCircular { - animation: spinner-spinning-circle-rotate 2s linear infinite; - height: 100%; - width: 100%; -} - -.colorwaysBtn-spinnerBeam { - animation: spinner-spinning-circle-dash 2s ease-in-out infinite; - stroke-dasharray: 1, 200; - stroke-dashoffset: 0; - fill: none; - stroke-width: 6; - stroke-miterlimit: 10; - stroke-linecap: round; - stroke: currentcolor; -} - -.colorwaysBtn-spinnerBeam2 { - stroke: currentcolor; - opacity: 0.6; - animation-delay: .15s; -} - -.colorwaysBtn-spinnerBeam3 { - stroke: currentcolor; - opacity: 0.3; - animation-delay: .23s; -} - -.colorwaysSettings-colorwaySource { - display: flex; - flex-direction: row; - justify-content: space-between; - padding: 8px; - gap: 5px; - border-radius: 4px; - box-sizing: border-box; - align-items: center; -} - -.discordColorway-listItem { - display: flex; - flex-direction: row; - justify-content: start; - padding: 0 8px; - gap: 5px; - border-radius: 4px; - box-sizing: border-box; - min-height: 44px; - align-items: center; -} - -.colorwaysSettings-modalRoot { - min-width: 520px; -} - -.colorwaysSettings-colorwaySourceLabel { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - flex-grow: 1; - line-height: 30px; -} - -.colorwaysSettings-colorwaySourceLabelHeader { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - flex-grow: 1; - font-weight: 700; - font-size: 16px; -} - -.colorwaysSettings-colorwaySourceDesc { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - flex-grow: 1; -} - -.colorwaysSettings-iconButton { - background-color: transparent !important; - border-radius: 0; -} - -.colorwaysSettings-iconButtonInner { - display: flex; - gap: 4px; - align-items: center; -} - -.colorwaysSettings-modalContent { - margin: 8px 0; -} - -@keyframes loading-bar { - 0% { - left: 0; - right: 100%; - width: 0; - } - - 10% { - left: 0; - right: 75%; - width: 25%; - } - - 90% { - right: 0; - left: 75%; - width: 25%; - } - - 100% { - left: 100%; - right: 0; - width: 0; - } -} - -.colorwaysLoader-barContainer { - width: 100%; - border-radius: var(--radius-round); - border: 0; - position: relative; - padding: 0; -} - -.colorwaysLoader-bar { - position: absolute; - border-radius: var(--radius-round); - top: 0; - right: 100%; - bottom: 0; - left: 0; - background: var(--brand-500); - width: 0; - animation: loading-bar 2s linear infinite; - transition: .2s ease; -} - -.colorwaysSettingsSelector-wrapper { - display: flex; - flex-direction: column; - gap: 8px; -} - -.colorwaysSettingsPage-wrapper .colorwayToolbox-listItem { - gap: 8px; - border-radius: 50px; - padding: 12px 16px; - background-color: var(--background-tertiary); - transition: .15s ease; - border: 1px solid transparent; - color: var(--interactive-normal); -} - -.colorwaysSettingsPage-wrapper .colorwayToolbox-listItem:hover { - border-color: var(--brand-500); - background-color: var(--brand-experiment-15a); - color: var(--interactive-hover); -} - -.colorwaysSettingsSelector-wrapper .colorwaySelector-doublePillBar { - justify-content: start; -} - -.colorwaysCreator-toolboxItm:hover { - background-color: var(--brand-experiment) !important; -} - -.colorwayCreator-colorPreview_primary+.colorwayCreator-colorPreview_primary, -.colorwayCreator-colorPreview_secondary+.colorwayCreator-colorPreview_secondary, -.colorwayCreator-colorPreview_tertiary+.colorwayCreator-colorPreview_tertiary, -.colorwayCreator-colorPreview_accent+.colorwayCreator-colorPreview_accent { - display: none; -} - -.colorwaysConflictingColors-warning { - width: 100%; - text-align: center; - justify-content: center; -} - -.ColorwaySelectorBtn_thin { - height: 21px !important; - width: 56px !important; -} - -.ColorwaySelectorBtn_thin:hover { - border-radius: 8px; -} - -.colorwaySelector-searchPopout { - display: none !important; -} - -.colorways-badge { - font-size: .625rem; - text-transform: uppercase; - vertical-align: top; - display: inline-flex; - align-items: center; - text-indent: 0; - background: var(--brand-experiment); - color: var(--white-500); - flex: 0 0 auto; - height: 15px; - padding: 0 4px; - margin-top: 7.5px; - border-radius: 4px; -} - -.hoverRoll { - display: inline-block; - vertical-align: top; - cursor: default; - text-align: left; - box-sizing: border-box; - position: relative; - width: 100%; - contain: paint; -} - -.hoverRoll_hovered { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - display: block; - transition: all.22s ease; - transform-style: preserve-3d; - pointer-events: none; - width: 100%; - opacity: 0; - transform: translate3d(0, 107%, 0); - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; -} - -.hoverRoll:hover .hoverRoll_hovered, -.colorwaysSettings-colorwaySource:hover .hoverRoll_hovered { - transform: translateZ(0); - opacity: 1; -} - -.hoverRoll_normal { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - display: block; - transition: all .22s ease; - transform-style: preserve-3d; - pointer-events: none; - width: 100%; -} - -.hoverRoll:hover .hoverRoll_normal, -.colorwaysSettings-colorwaySource:hover .hoverRoll_normal { - transform: translate3d(0,-107%,0); - opacity: 0; - user-select: none; -} - -.dc-warning-card { - padding: 1em; - margin-bottom: 1em; - background-color: var(--info-warning-background); - border-color: var(--info-warning-foreground); - color: var(--info-warning-text); -} - -/* stylelint-disable-next-line no-duplicate-selectors */ -.colorwaysPreview-modal { - width: 90vw !important; - height: 90vh !important; - max-height: unset !important; -} - -.colorwaysPresetPicker-content { - padding: 16px; -} - -.colorwaysPresetPicker { - width: 600px; -} - -.colorwaysCreator-setting { - display: flex; - flex-direction: row; - justify-content: space-between; - border-radius: 4px; - background-color: var(--background-secondary); - box-sizing: border-box; - color: var(--header-secondary); - padding: 10px 18px; - padding-right: 10px; - cursor: pointer; - align-items: center; -} - -.colorwaysCreator-setting:hover { - background-color: var(--background-modifier-hover); -} - -.dc-colorway-selector::before { - /* stylelint-disable-next-line property-no-vendor-prefix */ - -webkit-mask: var(--si-appearance) center/contain no-repeat !important; - mask: var(--si-appearance) center/contain no-repeat !important -} - -.dc-colorway-settings::before { - /* stylelint-disable-next-line property-no-vendor-prefix */ - -webkit-mask: var(--si-vencordsettings) center/contain no-repeat !important; - mask: var(--si-vencordsettings) center/contain no-repeat !important -} - -.dc-colorway-ondemand::before { - /* stylelint-disable-next-line property-no-vendor-prefix */ - -webkit-mask: var(--si-vencordupdater) center/contain no-repeat !important; - mask: var(--si-vencordupdater) center/contain no-repeat !important -} - -.dc-colorway-sources-manager::before { - /* stylelint-disable-next-line property-no-vendor-prefix */ - -webkit-mask: var(--si-instantinvites) center/contain no-repeat !important; - mask: var(--si-instantinvites) center/contain no-repeat !important -} - -.colorwaySourceModal { - min-height: unset; -} - -.colorwaySelector-sourceSelect { - width: fit-content !important; -} - -.dc-info-card { - border-radius: 5px; - border: 1px solid var(--blue-345); - padding: 1em; - margin-bottom: 1em; - display: flex; - gap: 1em; - flex-direction: column; -} - -.theme-dark .dc-info-card { - color: var(--white-500); -} - -.theme-light .dc-info-card { - color: var(--black-500); -} - -.colorwaysSettings-sourceScroller { - scrollbar-width: none; -} - -.colorwaysSettings-sourceScroller::-webkit-scrollbar { - width: 0; -} - -.colorwayMessage { - padding: 20px; - border: 1px solid; - border-radius: 5px; - display: flex; -} - -.colorwayMessage-contents { - display: flex; - flex-direction: column; -} - -.theme-dark .colorwayMessage { - background: hsl(var(--primary-630-hsl)/60%); - border-color: hsl(var(--primary-630-hsl)/90%); -} - -.theme-light .colorwayMessage { - background: hsl(var(--primary-100-hsl)/60%); - border-color: hsl(var(--primary-200-hsl)/30%); -} - -.colorwaySelector-sources_settings { - margin-left: 8px; -} - -.colorwaysLoadingModal, -.colorwayInfo-cssModal { - width: fit-content; - height: fit-content; - min-width: unset; - min-height: unset; - background: none; - box-shadow: none !important; - border: none; -} - -.ColorwaySelectorWrapper-list { - display: flex; - flex-direction: column; - gap: 0; - flex-wrap: nowrap; - padding-bottom: 0; -} - -.discordColorway-listItem .discordColorwayPreviewColorContainer { - width: 30px; - height: 30px; -} - -.colorwayLabel.labelInGrid { - max-height: 2rem; - overflow: hidden; - text-overflow: ellipsis; - margin-top: 4px; - text-align: center; -} - -.discordColorway-listItem .colorwayInfoIconContainer { - height: 28px; - width: 28px; - border-radius: 3px; - position: static; - opacity: 1; - justify-content: center; - display: flex; - align-items: center; - background: transparent; - border: 1px solid var(--button-outline-primary-border); - color: var(--button-outline-primary-text); - transition: .15s; -} - -.discordColorway-listItem .colorwayInfoIconContainer:hover { - background-color: var(--button-outline-primary-background-hover); - border-color: var(--button-outline-primary-border-hover); - color: var(--button-outline-primary-text-hover); -} - -.colorwayLabel:not(.labelInGrid) { - margin-right: auto; - margin-top: 0 !important; - margin-left: .5rem; -} - -.colorwaySelectionCircle { - position: absolute; - width: 56px; - height: 56px; - top: 0; - left: 0; -} - -.ColorwaySelectorWrapper-grid { - margin-bottom: 16px; -} - -.colorwaySelector-sorter { - height: 50px; - width: 100%; - box-shadow: var(--elevation-low); - margin-bottom: 8px; - display: flex; -} - -.colorwaySelector-sorter_selectedSpacer { - width: 80px; - height: 50px; -} - -.colorwaySelector-sorter_text { - line-height: 50px; - margin: 0; -} - -.colorwaySelector-sorter_name { - margin-right: auto; - cursor: pointer; -} - -.colorwayPresetLabel { - margin-right: 1rem; -} - -.colorwayPreview-channel { - margin: 10px; - width: calc(100% - 20px); - height: 8px; - border-radius: 16px; -} diff --git a/src/equicordplugins/discordColorways/types.ts b/src/equicordplugins/discordColorways/types.ts deleted file mode 100644 index dbc09aa4c..000000000 --- a/src/equicordplugins/discordColorways/types.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -export interface Colorway { - [key: string]: any, - name: string, - "dc-import": string, - accent: string, - primary: string, - secondary: string, - tertiary: string, - original?: boolean, - author: string, - authorID: string, - colors?: string[], - isGradient?: boolean, - sourceType?: "online" | "offline" | "temporary" | null, - source?: string, - linearGradient?: string, - preset?: string, - creatorVersion: string; -} - -export interface ColorPickerProps { - color: number; - showEyeDropper: boolean; - suggestedColors: string[]; - label: any; - onChange(color: number): void; -} - -export interface ColorwayObject { - id: string | null, - css: string | null, - sourceType: "online" | "offline" | "temporary" | null, - source: string | null | undefined; -} - -export interface SourceObject { - type: "online" | "offline" | "temporary", - source: string, - colorways: Colorway[]; -} - -export enum SortOptions { - NAME_AZ = 1, - NAME_ZA = 2, - SOURCE_AZ = 3, - SOURCE_ZA = 4 -} - -export interface StoreObject { - sources: StoreItem[]; -} - -export interface StoreItem { - name: string, - id: string, - description: string, - url: string, - authorGh: string; -} diff --git a/src/equicordplugins/discordColorways/utils.ts b/src/equicordplugins/discordColorways/utils.ts deleted file mode 100644 index 62e3859e7..000000000 --- a/src/equicordplugins/discordColorways/utils.ts +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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/equicordplugins/encryptcord/index.tsx b/src/equicordplugins/encryptcord/index.tsx deleted file mode 100644 index a40d3cb42..000000000 --- a/src/equicordplugins/encryptcord/index.tsx +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { addChatBarButton, ChatBarButton } from "@api/ChatButtons"; -import { - ApplicationCommandInputType, - ApplicationCommandOptionType, - sendBotMessage, -} from "@api/Commands"; -import * as DataStore from "@api/DataStore"; -import { addPreSendListener, removePreSendListener, SendListener } from "@api/MessageEvents"; -import { removeButton } from "@api/MessagePopover"; -import { Devs } from "@utils/constants"; -import { sleep } from "@utils/misc"; -import definePlugin from "@utils/types"; -import { findByPropsLazy } from "@webpack"; -import { - FluxDispatcher, MessageActions, - PrivateChannelsStore, RestAPI, - SnowflakeUtils, - useEffect, UserStore, - UserUtils, useState, -} from "@webpack/common"; -import { Message } from "discord-types/general"; - -import { decryptData, encryptData, formatPemKey, generateKeys } from "./rsa-utils"; -const MessageCreator = findByPropsLazy("createBotMessage"); -const CloudUtils = findByPropsLazy("CloudUpload"); -import { getCurrentChannel } from "@utils/discord"; - -let enabled; -let setEnabled; - -// Interface for Message Create -interface IMessageCreate { - type: "MESSAGE_CREATE"; - optimistic: boolean; - isPushNotification: boolean; - channelId: string; - message: Message; -} - -// Chat Bar Icon Component -const ChatBarIcon: ChatBarButton = ({ isMainChat }) => { - [enabled, setEnabled] = useState(false); - const [buttonDisabled, setButtonDisabled] = useState(false); - - useEffect(() => { - const listener: SendListener = async (_, message) => { - if (enabled) { - const groupChannel = await DataStore.get("encryptcordChannelId"); - if (getCurrentChannel().id !== groupChannel) { - sendBotMessage(getCurrentChannel().id, { content: `You must be in <#${groupChannel}> to send an encrypted message!\n> If you wish to send an unencrypted message, please click the button in the chatbar.` }); - message.content = ""; - return; - } - const trimmedMessage = message.content.trim(); - await MessageActions.receiveMessage(groupChannel, await createMessage(trimmedMessage, UserStore.getCurrentUser().id, groupChannel, 0)); - const encryptcordGroupMembers = await DataStore.get("encryptcordGroupMembers"); - const dmPromises = Object.keys(encryptcordGroupMembers).map(async memberId => { - const groupMember = await UserUtils.getUser(memberId).catch(() => null); - if (!groupMember) return; - const encryptedMessage = await encryptData(encryptcordGroupMembers[memberId].key, trimmedMessage); - const encryptedMessageString = JSON.stringify(encryptedMessage); - await sendTempMessage(groupMember.id, encryptedMessageString, "message"); - }); - - await Promise.all(dmPromises); - message.content = ""; - } - }; - - addPreSendListener(listener); - return () => void removePreSendListener(listener); - }, [enabled]); - - if (!isMainChat) return null; - - return ( - { - if (await DataStore.get("encryptcordGroup") === false || (await DataStore.get("encryptcordChannelId") !== getCurrentChannel().id)) { - setButtonDisabled(true); - await sendTempMessage(getCurrentChannel().id, "", `join\`\`\`\n${await DataStore.get("encryptcordPublicKey")}\`\`\``, false); - sendBotMessage(getCurrentChannel().id, { content: `*Checking for any groups in this channel...*\n> If none is found, a new one will be created \n> [Tip] You can do \`/encryptcord leave\` to leave a group` }); - await sleep(5000); - if (await DataStore.get("encryptcordGroup") === true && (await DataStore.get("encryptcordChannelId") !== getCurrentChannel().id)) { - sendBotMessage(getCurrentChannel().id, { content: "*Leaving current group...*" }); - await leave("", { channel: { id: await DataStore.get("encryptcordChannelId") } }); - } else if (await DataStore.get("encryptcordGroup") === true) { - setButtonDisabled(false); - return; - } - await startGroup("", { channel: { id: getCurrentChannel().id } }); - } - setEnabled(!enabled); - setButtonDisabled(false); - }} - buttonProps={{ - style: { - transition: "transform 0.3s ease-in-out", - transform: `rotate(${enabled ? 0 : 15}deg)`, - }, - disabled: buttonDisabled - }} - > - - {!enabled && <> - - - - - } - - - - ); -}; - -// Export Plugin -export default definePlugin({ - name: "Encryptcord", - description: "End-to-end encryption in Discord!", - authors: [Devs.Inbestigator], - dependencies: ["CommandsAPI"], - patches: [ - { - find: "executeMessageComponentInteraction:", - replacement: { - match: /await\s+l\.default\.post\({\s*url:\s*A\.Endpoints\.INTERACTIONS,\s*body:\s*C,\s*timeout:\s*3e3\s*},\s*t\s*=>\s*{\s*h\(T,\s*p,\s*f,\s*t\)\s*}\s*\)/, - replace: "await $self.joinGroup(C);$&" - } - } - ], - async joinGroup(interaction) { - const sender = await UserUtils.getUser(interaction.application_id).catch(() => null); - if (!sender || (sender.bot === true && sender.id !== "1")) return; - if (interaction.data.component_type !== 2) return; - switch (interaction.data.custom_id) { - case "removeFromSelf": - await handleLeaving(sender.id, await DataStore.get("encryptcordGroupMembers") ?? {}, interaction.channel_id); - await sendTempMessage(sender.id, "", "leaving"); - FluxDispatcher.dispatch({ - type: "MESSAGE_DELETE", - channelId: interaction.channel_id, - id: interaction.message_id, - mlDeleted: true - }); - break; - case "createGroup": - await leave("", { channel: { id: interaction.channel_id } }); - await startGroup("", { channel: { id: interaction.channel_id } }); - break; - default: - return; - } - }, - flux: { - async MESSAGE_CREATE({ optimistic, type, message, channelId }: IMessageCreate) { - if (optimistic || type !== "MESSAGE_CREATE") return; - if (message.state === "SENDING") return; - if (message.author.id === UserStore.getCurrentUser().id) return; - if (!message.content) return; - const encryptcordGroupMembers = await DataStore.get("encryptcordGroupMembers"); - if (!Object.keys(encryptcordGroupMembers).some(key => key === message.author.id)) { - switch (message.content.toLowerCase().split("```")[0]) { - case "groupdata": - const response = await fetch(message.attachments[0].url); - const groupdata = await response.json(); - await handleGroupData(groupdata); - break; - case "join": - if (encryptcordGroupMembers[UserStore.getCurrentUser().id].child) return; - if (!await DataStore.get("encryptcordGroup")) return; - const sender = await UserUtils.getUser(message.author.id).catch(() => null); - if (!sender) return; - const userKey = message.content.split("```")[1]; - await handleJoin(sender.id, userKey, encryptcordGroupMembers); - break; - default: - break; - } - return; - } - const dmChannelId = await PrivateChannelsStore.getOrEnsurePrivateChannel(message.author.id); - if (channelId !== dmChannelId) return; - const sender = await UserUtils.getUser(message.author.id).catch(() => null); - if (!sender) return; - const groupChannel = await DataStore.get("encryptcordChannelId"); - switch (message.content.toLowerCase()) { - case "leaving": - handleLeaving(sender.id, encryptcordGroupMembers, groupChannel); - break; - case "message": - const msgResponse = await fetch(message.attachments[0].url); - const messagedata = await msgResponse.json(); - await handleMessage(messagedata, sender.id, groupChannel); - break; - case "groupdata": - const response = await fetch(message.attachments[0].url); - const groupdata = await response.json(); - await handleGroupData(groupdata); - break; - default: - break; - } - }, - }, - commands: [ - { - name: "encryptcord", - description: "End-to-end encryption in Discord!", - options: [ - { - name: "leave", - description: "Leave current group", - options: [], - type: ApplicationCommandOptionType.SUB_COMMAND, - }, - { - name: "data", - description: "View your keys and current group members", - options: [], - type: ApplicationCommandOptionType.SUB_COMMAND, - }, - ], - inputType: ApplicationCommandInputType.BOT, - execute: (opts, ctx) => { - switch (opts[0].name) { - case "start": - startGroup(opts[0].options, ctx); - break; - case "leave": - leave(opts[0].options, ctx); - break; - case "data": - data(opts[0].options, ctx); - break; - } - }, - }, - ], - async start() { - addChatBarButton("Encryptcord", ChatBarIcon); - const pair = await generateKeys(); - await DataStore.set("encryptcordPublicKey", pair.publicKey); - await DataStore.set("encryptcordPrivateKey", pair.privateKey); - if (await DataStore.get("encryptcordGroup") === true) { - await leave("", { channel: { id: await DataStore.get("encryptcordChannelId") } }); - } - await DataStore.set("encryptcordGroup", false); - await DataStore.set("encryptcordChannelId", ""); - await DataStore.set("encryptcordGroupMembers", {}); - }, - async stop() { - removeButton("Encryptcord"); - if (await DataStore.get("encryptcordGroup") === true) { - await leave("", { channel: { id: await DataStore.get("encryptcordChannelId") } }); - } - }, -}); - -// Send Temporary Message -async function sendTempMessage(recipientId: string, attachment: string, content: string, dm: boolean = true) { - if (recipientId === UserStore.getCurrentUser().id) return; - const channelId = dm ? await PrivateChannelsStore.getOrEnsurePrivateChannel(recipientId) : recipientId; - if (attachment && attachment !== "") { - const upload = await new CloudUtils.CloudUpload({ - file: new File([new Blob([attachment])], "file.text", { type: "text/plain; charset=utf-8" }), - isClip: false, - isThumbnail: false, - platform: 1, - }, channelId, false, 0); - upload.on("complete", async () => { - const messageId = await RestAPI.post({ - url: `/channels/${channelId}/messages`, - body: { - content, - attachments: [{ - id: "0", - filename: upload.filename, - uploaded_filename: upload.uploadedFilename, - }], - nonce: SnowflakeUtils.fromTimestamp(Date.now()), - }, - }).then(response => response.body.id); - - await sleep(500); - MessageActions.deleteMessage(channelId, messageId); - }); - await upload.upload(); - return; - } - - const messageId = await RestAPI.post({ - url: `/channels/${channelId}/messages`, - body: { - content, - nonce: SnowflakeUtils.fromTimestamp(Date.now()), - }, - }).then(response => response.body.id); - - await sleep(500); - MessageActions.deleteMessage(channelId, messageId); -} - -// Handle leaving group -async function handleLeaving(senderId: string, encryptcordGroupMembers: object, groupChannel: string) { - const updatedMembers = Object.keys(encryptcordGroupMembers).reduce((result, memberId) => { - if (memberId !== senderId) { - result[memberId] = encryptcordGroupMembers[memberId]; - if (result[memberId].child === senderId) { - result[memberId].child = encryptcordGroupMembers[senderId].child; - } - if (result[memberId].parent === senderId) { - result[memberId].parent = encryptcordGroupMembers[senderId].parent; - } - } - return result; - }, {}); - - await DataStore.set("encryptcordGroupMembers", updatedMembers); - - await MessageActions.receiveMessage(groupChannel, await createMessage("", senderId, groupChannel, 2)); -} - -// Handle receiving message -async function handleMessage(message, senderId: string, groupChannel: string) { - const decryptedMessage = await decryptData(await DataStore.get("encryptcordPrivateKey"), message); - await MessageActions.receiveMessage(groupChannel, await createMessage(decryptedMessage, senderId, groupChannel, 0)); -} - -// Handle receiving group data -async function handleGroupData(groupData) { - await DataStore.set("encryptcordChannelId", groupData.channel); - await DataStore.set("encryptcordGroupMembers", groupData.members); - await DataStore.set("encryptcordGroup", true); - await MessageActions.receiveMessage(groupData.channel, await createMessage("", UserStore.getCurrentUser().id, groupData.channel, 7)); - setEnabled(true); -} - -// Handle joining group -async function handleJoin(senderId: string, senderKey: string, encryptcordGroupMembers: object) { - encryptcordGroupMembers[senderId] = { key: senderKey, parent: UserStore.getCurrentUser().id, child: null }; - encryptcordGroupMembers[UserStore.getCurrentUser().id].child = senderId; - await DataStore.set("encryptcordGroupMembers", encryptcordGroupMembers); - const groupChannel = await DataStore.get("encryptcordChannelId"); - const newMember = await UserUtils.getUser(senderId).catch(() => null); - if (!newMember) return; - - const membersData = {}; - Object.entries(encryptcordGroupMembers) - .forEach(([memberId, value]) => { - membersData[memberId] = value; - }); - - const membersDataString = JSON.stringify({ members: membersData, channel: groupChannel }); - - const dmPromises = Object.keys(encryptcordGroupMembers).map(async memberId => { - const groupMember = await UserUtils.getUser(memberId).catch(() => null); - if (!groupMember) return; - await sendTempMessage(groupMember.id, membersDataString, "groupdata"); - }); - - await Promise.all(dmPromises); - await MessageActions.receiveMessage(groupChannel, { - ...await createMessage("", senderId, groupChannel, 7), components: [{ - type: 1, - components: [{ - type: 2, - style: 4, - label: "I don't want to talk to you!", - custom_id: "removeFromSelf" - }, - { - type: 2, - style: 2, - label: "(Other users can still send/receive messages to/from them)", - disabled: true, - custom_id: "encryptcord" - }] - }] - }); -} - -// Create message for group -async function createMessage(message: string, senderId: string, channelId: string, type: number) { - const messageStart = MessageCreator.createBotMessage({ channelId, content: "", embeds: [] }); - const sender = await UserUtils.getUser(senderId).catch(() => null); - if (!sender) return; - return { ...messageStart, content: message, author: sender, type, flags: 0 }; -} - -// Start E2EE Group -async function startGroup(opts, ctx) { - const channelId = ctx.channel.id; - await DataStore.set("encryptcordChannelId", channelId); - await DataStore.set("encryptcordGroupMembers", { - [UserStore.getCurrentUser().id]: { key: await DataStore.get("encryptcordPublicKey"), parent: null, child: null } - }); - await DataStore.set("encryptcordGroup", true); - sendBotMessage(channelId, { content: "Group created!\n> Other users can click the lock icon to join." }); - await MessageActions.receiveMessage(channelId, await createMessage("", UserStore.getCurrentUser().id, channelId, 7)); - setEnabled(true); -} - -// Leave the Group; -async function leave(opts, ctx) { - const channelId = ctx.channel.id; - if (!(await DataStore.get("encryptcordGroup"))) { - sendBotMessage(channelId, { content: "You're not in a group!" }); - return; - } - const user = UserStore.getCurrentUser(); - const encryptcordGroupMembers = await DataStore.get("encryptcordGroupMembers"); - - const dmPromises = Object.keys(encryptcordGroupMembers).map(async memberId => { - const groupMember = await UserUtils.getUser(memberId).catch(() => null); - if (!groupMember) return; - await sendTempMessage(groupMember.id, "", "leaving"); - }); - - await Promise.all(dmPromises); - await DataStore.set("encryptcordGroup", false); - await DataStore.set("encryptcordChannelId", ""); - await DataStore.set("encryptcordGroupMembers", {}); - await MessageActions.receiveMessage(channelId, await createMessage("", user.id, channelId, 2)); - setEnabled(false); -} - -// View user data -async function data(opts, ctx) { - const channelId = ctx.channel.id; - const encryptcordGroupMembers = await DataStore.get("encryptcordGroupMembers"); - const encryptcordPublicKey = await DataStore.get("encryptcordPublicKey"); - const encryptcordPrivateKey = await DataStore.get("encryptcordPrivateKey"); - const exportedPrivateKey = await crypto.subtle.exportKey("pkcs8", encryptcordPrivateKey); - const groupMembers = Object.keys(encryptcordGroupMembers); - sendBotMessage(channelId, { - content: `## Public key:\n\`\`\`${encryptcordPublicKey}\`\`\`\n## Private key:\n||\`\`\`${formatPemKey(exportedPrivateKey, "private")}\`\`\`||*(DO **NOT** SHARE THIS)*\n## Group members:\n\`\`\`json\n${JSON.stringify(groupMembers)}\`\`\`` - }); -} diff --git a/src/equicordplugins/encryptcord/rsa-utils.tsx b/src/equicordplugins/encryptcord/rsa-utils.tsx deleted file mode 100644 index 15d272d5a..000000000 --- a/src/equicordplugins/encryptcord/rsa-utils.tsx +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -export const generateKeys = async () => { - const keyPair = await crypto.subtle.generateKey( - { - name: "RSA-OAEP", - modulusLength: 4096, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["encrypt", "decrypt"] - ); - - const exportedPublicKey = await crypto.subtle.exportKey("spki", keyPair.publicKey); - const publicKey = formatPemKey(exportedPublicKey, "public"); - - return { privateKey: keyPair.privateKey, publicKey }; -}; - -export const encryptData = async (pemPublicKey, data) => { - const publicKey = await importPemPublicKey(pemPublicKey); - - const chunkSize = 446; - - const encryptedChunks: any[] = []; - const encoder = new TextEncoder(); - - for (let i = 0; i < data.length; i += chunkSize) { - const chunk = await data.substring(i, i + chunkSize); - const encryptedChunk = await crypto.subtle.encrypt( - { - name: "RSA-OAEP", - }, - publicKey, - encoder.encode(chunk) - ); - encryptedChunks.push(arrayBufferToBase64(encryptedChunk)); - } - - return encryptedChunks; -}; - -export const decryptData = async (privateKey, encArray) => { - const decryptionPromises = encArray.map(async encStr => { - const encBuffer = base64ToArrayBuffer(encStr); - - const dec = await crypto.subtle.decrypt( - { - name: "RSA-OAEP", - }, - privateKey, - encBuffer - ); - - return new TextDecoder().decode(dec); - }); - - const decryptedMessages = await Promise.all(decryptionPromises); - - return decryptedMessages.join(""); -}; - -// Helper functions -const arrayBufferToBase64 = buffer => { - const binary = String.fromCharCode(...new Uint8Array(buffer)); - return btoa(binary); -}; - -const base64ToArrayBuffer = base64String => { - const binaryString = atob(base64String); - const { length } = binaryString; - const buffer = new ArrayBuffer(length); - const view = new Uint8Array(buffer); - - for (let i = 0; i < length; i++) { - view[i] = binaryString.charCodeAt(i); - } - - return buffer; -}; - -export const formatPemKey = (keyData, type) => { - const base64Key = arrayBufferToBase64(keyData); - return `-----BEGIN ${type.toUpperCase()} KEY-----\n` + base64Key + `\n-----END ${type.toUpperCase()} KEY----- `; -}; - -const importPemPublicKey = async pemKey => { - try { - const trimmedPemKey = pemKey.trim(); - - const keyBody = trimmedPemKey - .replace("-----BEGIN PUBLIC KEY-----", "") - .replace("-----END PUBLIC KEY-----", ""); - - const binaryDer = atob(keyBody); - - const arrayBuffer = new Uint8Array(binaryDer.length); - for (let i = 0; i < binaryDer.length; i++) { - arrayBuffer[i] = binaryDer.charCodeAt(i); - } - - return await crypto.subtle.importKey( - "spki", - arrayBuffer, - { - name: "RSA-OAEP", - hash: { name: "SHA-256" }, - }, - true, - ["encrypt"] - ); - } catch (error) { - console.error("Error importing PEM public key:", error); - throw error; - } -}; diff --git a/src/equicordplugins/gifCollections/CollectionManager.ts b/src/equicordplugins/gifCollections/CollectionManager.ts deleted file mode 100644 index 71bd32419..000000000 --- a/src/equicordplugins/gifCollections/CollectionManager.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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 { DataStore } from "@api/index"; -import { Toasts } from "@webpack/common"; - -import { settings } from "./index"; -import { Collection, Gif } from "./types"; -import { getFormat } from "./utils/getFormat"; - -export const DATA_COLLECTION_NAME = "gif-collections-collections"; - -// this is here bec async + react class component dont play nice and stutters happen. IF theres a better way of doing it pls let me know -export let cache_collections: Collection[] = []; - -export const getCollections = async (): Promise => (await DataStore.get(DATA_COLLECTION_NAME)) ?? []; - -export const getCollection = async (name: string): Promise => { - const collections = await getCollections(); - return collections.find(c => c.name === name); -}; - -export const getCachedCollection = (name: string): Collection | undefined => cache_collections.find(c => c.name === name); - -export const createCollection = async (name: string, gifs: Gif[]): Promise => { - - const collections = await getCollections(); - const duplicateCollection = collections.find(c => c.name === `gc:${name}`); - if (duplicateCollection) - return Toasts.show({ - message: "That collection already exists", - type: Toasts.Type.FAILURE, - id: Toasts.genId(), - options: { - duration: 3000, - position: Toasts.Position.BOTTOM - } - }); - - // gifs shouldnt be empty because to create a collection you need to right click an image / gif and then create it yk. but cant hurt to have a null-conditional check RIGHT? - const latestGifSrc = gifs[gifs.length - 1]?.src ?? settings.store.defaultEmptyCollectionImage; - const collection = { - name: `gc:${name}`, - src: latestGifSrc, - format: getFormat(latestGifSrc), - type: "Category", - gifs - }; - - await DataStore.set(DATA_COLLECTION_NAME, [...collections, collection]); - return await refreshCacheCollection(); -}; - -export const addToCollection = async (name: string, gif: Gif): Promise => { - const collections = await getCollections(); - const collectionIndex = collections.findIndex(c => c.name === name); - if (collectionIndex === -1) return console.warn("collection not found"); - - collections[collectionIndex].gifs.push(gif); - collections[collectionIndex].src = gif.src; - collections[collectionIndex].format = getFormat(gif.src); - - await DataStore.set(DATA_COLLECTION_NAME, collections); - return await refreshCacheCollection(); - -}; - -export const removeFromCollection = async (id: string): Promise => { - const collections = await getCollections(); - const collectionIndex = collections.findIndex(c => c.gifs.some(g => g.id === id)); - if (collectionIndex === -1) return console.warn("collection not found"); - - // Remove The Gif - collections[collectionIndex].gifs = collections[collectionIndex].gifs.filter(g => g.id !== id); - - const collection = collections[collectionIndex]; - const latestGifSrc = collection.gifs.length ? collection.gifs[collection.gifs.length - 1].src : settings.store.defaultEmptyCollectionImage; - collections[collectionIndex].src = latestGifSrc; - collections[collectionIndex].format = getFormat(latestGifSrc); - - await DataStore.set(DATA_COLLECTION_NAME, collections); - return await refreshCacheCollection(); -}; - -export const deleteCollection = async (name: string): Promise => { - - const collections = await getCollections(); - const col = collections.filter(c => c.name !== name); - await DataStore.set(DATA_COLLECTION_NAME, col); - await refreshCacheCollection(); -}; - - -export const refreshCacheCollection = async (): Promise => { - cache_collections = await getCollections(); -}; diff --git a/src/equicordplugins/gifCollections/constants.ts b/src/equicordplugins/gifCollections/constants.ts deleted file mode 100644 index beb1fcbd3..000000000 --- a/src/equicordplugins/gifCollections/constants.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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 . -*/ - -// cant change them now eh. My friend uses this plugin. LOVE YOU FREEZER -export const GIF_ITEM_PREFIX = "gc-moment:"; -export const GIF_COLLECTION_PREFIX = "gc:"; diff --git a/src/equicordplugins/gifCollections/index.tsx b/src/equicordplugins/gifCollections/index.tsx deleted file mode 100644 index 627bedc5e..000000000 --- a/src/equicordplugins/gifCollections/index.tsx +++ /dev/null @@ -1,352 +0,0 @@ -/* - * 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 . -*/ - -// Plugin idea by brainfreeze (668137937333911553) 😎 - -import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu"; -import { definePluginSettings } from "@api/Settings"; -import { Devs } from "@utils/constants"; -import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal"; -import definePlugin, { OptionType } from "@utils/types"; -import { Alerts, Button, ContextMenuApi, FluxDispatcher, Forms, Menu, React, TextInput, useCallback, useState } from "@webpack/common"; - -import * as CollectionManager from "./CollectionManager"; -import { GIF_COLLECTION_PREFIX, GIF_ITEM_PREFIX } from "./constants"; -import { Category, Collection, Gif, Props } from "./types"; -import { getFormat } from "./utils/getFormat"; -import { getGif } from "./utils/getGif"; -import { downloadCollections, uploadGifCollections } from "./utils/settingsUtils"; -import { uuidv4 } from "./utils/uuidv4"; - -export const settings = definePluginSettings({ - defaultEmptyCollectionImage: { - description: "The image / gif that will be shown when a collection has no images / gifs", - type: OptionType.STRING, - default: "https://i.imgur.com/TFatP8r.png" - }, - importGifs: { - type: OptionType.COMPONENT, - description: "Import Collections", - component: () => - , - }, - exportGifs: { - type: OptionType.COMPONENT, - description: "Export Collections", - component: () => - - } -}); - - -const addCollectionContextMenuPatch: NavContextMenuPatchCallback = (children, props) => { - if (!props) return; - - const { message, itemSrc, itemHref, target } = props; - - const gif = getGif(message, itemSrc ?? itemHref, target); - - if (!gif) return; - - const group = findGroupChildrenByChildId("open-native-link", children) ?? findGroupChildrenByChildId("copy-link", children); - if (group && !group.some(child => child?.props?.id === "add-to-collection")) { - group.push( - // if i do it the normal way i get a invalid context menu thingy error -> Menu API only allows Items and groups of Items as children. - MenuThingy({ gif }) - ); - } -}; - - -export default definePlugin({ - name: "Gif Collection", - // need better description eh - description: "Allows you to have collections of gifs", - authors: [Devs.Aria], - patches: [ - { - find: "renderCategoryExtras", - replacement: [ - // This patch adds the collections to the gif part yk - { - match: /(\i\.render=function\(\){)(.{1,50}getItemGrid)/, - replace: "$1;$self.insertCollections(this);$2" - }, - // Hides the gc: from the name gc:monkeh -> monkeh - { - match: /(\i\.renderCategoryExtras=function\((?\i)\){)var (?\i)=\i\.name,/, - replace: "$1var $=$self.hidePrefix($)," - }, - // Replaces this.props.resultItems with the collection.gifs - { - match: /(\i\.renderContent=function\(\){)(.{1,50}resultItems)/, - replace: "$1;$self.renderContent(this);$2" - }, - // Delete context menu for collection - { - match: /(\i\.render=function\(\){.{1,100}renderExtras.{1,200}onClick:this\.handleClick,)/, - replace: "$1onContextMenu: (e) => $self.collectionContextMenu(e, this)," - }, - ] - }, - /* - problem: - when you click your collection in the gifs picker discord enters the collection name into the search bar - which causes discord to fetch the gifs from their api. This causes a tiny flash when the gifs have fetched successfully - solution: - if query starts with gc: and collection is not null then return early and prevent the fetch - */ - { - find: "type:\"GIF_PICKER_QUERY\"", - replacement: { - match: /(function \i\((?\i),\i\){.{1,200}dispatch\({type:"GIF_PICKER_QUERY".{1,20};)/, - replace: - "$&if($self.shouldStopFetch($)) return;" - } - }, - ], - - settings, - - - start() { - CollectionManager.refreshCacheCollection(); - - addContextMenuPatch("message", addCollectionContextMenuPatch); - }, - - stop() { - removeContextMenuPatch("message", addCollectionContextMenuPatch); - }, - CollectionManager, - - oldTrendingCat: null as Category[] | null, - sillyInstance: null as any, - sillyContentInstance: null as any, - - get collections(): Collection[] { - CollectionManager.refreshCacheCollection(); - return CollectionManager.cache_collections; - }, - - renderContent(instance) { - if (instance.props.query.startsWith(GIF_COLLECTION_PREFIX)) { - this.sillyContentInstance = instance; - const collection = this.collections.find(c => c.name === instance.props.query); - if (!collection) return; - instance.props.resultItems = collection.gifs.map(g => ({ - id: g.id, - format: getFormat(g.src), - src: g.src, - url: g.url, - width: g.width, - height: g.height - })).reverse(); - } - - }, - - hidePrefix(props: Category) { - return props.name.split(":").length > 1 ? props.name.replace(/.+?:/, "") : props.name; - }, - - insertCollections(instance: { props: Props; }) { - try { - this.sillyInstance = instance; - if (instance.props.trendingCategories.length && instance.props.trendingCategories[0].type === "Trending") - this.oldTrendingCat = instance.props.trendingCategories; - - - if (this.oldTrendingCat != null) - instance.props.trendingCategories = this.collections.reverse().concat(this.oldTrendingCat as Collection[]); - - } catch (err) { - console.error(err); - } - }, - - shouldStopFetch(query: string) { - if (query.startsWith(GIF_COLLECTION_PREFIX)) { - const collection = this.collections.find(c => c.name === query); - if (collection != null) return true; - } - return false; - }, - - collectionContextMenu(e: React.UIEvent, instance) { - const { item } = instance.props; - if (item?.name?.startsWith(GIF_COLLECTION_PREFIX)) - return ContextMenuApi.openContextMenu(e, () => - { this.sillyInstance && this.sillyInstance.forceUpdate(); }} - nameOrId={instance.props.item.name} /> - ); - if (item?.id?.startsWith(GIF_ITEM_PREFIX)) - return ContextMenuApi.openContextMenu(e, () => - { this.sillyContentInstance && this.sillyContentInstance.forceUpdate(); }} - nameOrId={instance.props.item.id} - />); - - const { src, url, height, width } = item; - if (src && url && height != null && width != null && !item.id?.startsWith(GIF_ITEM_PREFIX)) - return ContextMenuApi.openContextMenu(e, () => - FluxDispatcher.dispatch({ type: "CONTEXT_MENU_CLOSE" })} - aria-label="Gif Collections" - > - - {/* if i do it the normal way i get a invalid context menu thingy error -> Menu API only allows Items and groups of Items as children.*/} - {MenuThingy({ gif: { ...item, id: uuidv4() } })} - - - - ); - return null; - }, -}); - - - -// stolen from spotify controls -const RemoveItemContextMenu = ({ type, nameOrId, onConfirm }: { type: "gif" | "collection", nameOrId: string, onConfirm: () => void; }) => ( - FluxDispatcher.dispatch({ type: "CONTEXT_MENU_CLOSE" })} - aria-label={type === "collection" ? "Delete Collection" : "Remove"} - > - - // Stolen from Review components - type === "collection" ? Alerts.show({ - title: "Are you sure?", - body: "Do you really want to delete this collection?", - confirmText: "Delete", - confirmColor: Button.Colors.RED, - cancelText: "Nevermind", - onConfirm: async () => { - await CollectionManager.deleteCollection(nameOrId); - onConfirm(); - } - }) : CollectionManager.removeFromCollection(nameOrId).then(() => onConfirm())} - > - - - -); - - - -const MenuThingy: React.FC<{ gif: Gif; }> = ({ gif }) => { - CollectionManager.refreshCacheCollection(); - const collections = CollectionManager.cache_collections; - - return ( - - {collections.map(col => ( - CollectionManager.addToCollection(col.name, gif)} - /> - ))} - - - { - openModal(modalProps => ( - - )); - }} - /> - - ); -}; - -interface CreateCollectionModalProps { - gif: Gif; - onClose: () => void, - modalProps: ModalProps; -} - -function CreateCollectionModal({ gif, onClose, modalProps }: CreateCollectionModalProps) { - - const [name, setName] = useState(""); - - const onSubmit = useCallback((e: React.FormEvent | React.MouseEvent) => { - e.preventDefault(); - if (!name.length) return; - CollectionManager.createCollection(name, [gif]); - onClose(); - }, [name]); - - return ( - -
- - Create Collection - - - Collection Name - setName(e)} /> - -
- - - -
-
-
- ); -} diff --git a/src/equicordplugins/gifCollections/types.ts b/src/equicordplugins/gifCollections/types.ts deleted file mode 100644 index 2b99f3f85..000000000 --- a/src/equicordplugins/gifCollections/types.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 . -*/ - -export enum Format { NONE = 0, IMAGE = 1, VIDEO = 2 } - -export interface Category { - type: "Trending" | "Category"; - name: string; - src: string; - format: Format; - gifs?: Gif[]; -} - -export interface Gif { - id: string, - src: string; - url: string; - height: number, - width: number; -} - -export interface Props { - favorites: { [src: string]: any; }; - trendingCategories: Category[]; -} - -type WithRequired = T & { [P in K]-?: T[P] }; - -export type Collection = WithRequired; diff --git a/src/equicordplugins/gifCollections/utils/cleanUrl.ts b/src/equicordplugins/gifCollections/utils/cleanUrl.ts deleted file mode 100644 index cdd990f97..000000000 --- a/src/equicordplugins/gifCollections/utils/cleanUrl.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 . -*/ - -export const cleanUrl = (url: string) => { - const urlObject = new URL(url); - urlObject.search = ""; - return urlObject.href; -}; diff --git a/src/equicordplugins/gifCollections/utils/getFormat.ts b/src/equicordplugins/gifCollections/utils/getFormat.ts deleted file mode 100644 index 205e99616..000000000 --- a/src/equicordplugins/gifCollections/utils/getFormat.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 { Format } from "../types"; -import { getUrlExtension } from "./getUrlExtension"; - -const videoExtensions = ["mp4", "ogg", "webm", "avi", "wmv", "flv", "mov", "mkv", "m4v"]; - -export function getFormat(url: string) { - const extension = getUrlExtension(url); - return url.startsWith("https://media.tenor") || extension == null || videoExtensions.includes(extension) ? Format.VIDEO : Format.IMAGE; -} diff --git a/src/equicordplugins/gifCollections/utils/getGif.ts b/src/equicordplugins/gifCollections/utils/getGif.ts deleted file mode 100644 index cfaedf70c..000000000 --- a/src/equicordplugins/gifCollections/utils/getGif.ts +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 { MessageStore, SnowflakeUtils } from "@webpack/common"; -import { Message } from "discord-types/general"; - -import { Gif } from "../types"; -import { cleanUrl } from "./cleanUrl"; -import { isAudio } from "./isAudio"; -import { uuidv4 } from "./uuidv4"; - -export function getGifByTarget(url: string, target?: HTMLDivElement | null): Gif | null { - const liElement = target?.closest("li"); - if (!target || !liElement || !liElement.id) return null; - - const [channelId, messageId] = liElement.id.split("-").slice(2); - // the isValidSnowFlake part may not be nessesery cuse either way (valid or not) message will be undefined if it doenst find a message /shrug - if (!channelId || !messageId || !isValidSnowFlake(channelId) || !isValidSnowFlake(messageId)) return null; - - const message = MessageStore.getMessage(channelId, messageId); - if (!message || !message.embeds.length && !message.attachments.length) return null; - - return getGifByMessageAndUrl(url, message); -} - - -export function getGifByMessageAndTarget(target: HTMLDivElement, message: Message) { - const url = target.closest('[class^="imageWrapper"]')?.querySelector("video")?.src ?? target.closest('[class^="imageWrapper"]')?.querySelector("img")?.src; - - if (!url) return null; - - return getGifByMessageAndUrl(url, message); -} - -export function getGifByMessageAndUrl(url: string, message: Message): Gif | null { - if (!message.embeds.length && !message.attachments.length || isAudio(url)) - return null; - - url = cleanUrl(url); - - // find embed with matching url or image/thumbnail url - const embed = message.embeds.find(e => e.url === url || e.image?.url === url || e.image?.proxyURL === url || e.video?.proxyURL === url || e.thumbnail?.proxyURL === url); // no point in checking thumbnail/video url because no way of getting it eh. discord renders the img/video element with proxy urls - if (embed) { - if (embed.image) - return { - id: uuidv4(), - height: embed.image.height, - width: embed.image.width, - src: embed.image.proxyURL, - url: embed.image.url, - }; - // Tennor - if (embed.video && embed.video.proxyURL) return { - id: uuidv4(), - height: embed.video.height, - width: embed.video.width, - src: embed.video.proxyURL, - url: embed.provider?.name === "Tenor" ? embed.url ?? embed.video.url : embed.video.url, - }; - - // Youtube thumbnails and other stuff idk - if (embed.thumbnail && embed.thumbnail.proxyURL) return { - id: uuidv4(), - height: embed.thumbnail.height, - width: embed.thumbnail.width, - src: embed.thumbnail.proxyURL, - url: embed.thumbnail.url, - }; - } - - - const attachment = message.attachments.find(a => a.url === url || a.proxy_url === url); - if (attachment) return { - id: uuidv4(), - height: attachment.height ?? 50, - width: attachment.width ?? 50, - src: attachment.proxy_url, - url: attachment.url - }; - - return null; -} - -export const getGif = (message: Message | null, url: string | null, target: HTMLDivElement | null) => { - if (message && url) { - const gif = getGifByMessageAndUrl(url, message); - if (!gif) return null; - - return gif; - } - if (message && target && !url) { - const gif = getGifByMessageAndTarget(target, message); - if (!gif) return null; - - return gif; - } - if (url && target && !message) { - // youtube thumbnail url is message link for some reason eh - const gif = getGifByTarget(url.startsWith("https://discord.com/") ? target.parentElement?.querySelector("img")?.src ?? url : url, target); - if (!gif) return null; - - return gif; - } -}; - -function isValidSnowFlake(snowflake: string) { - return !Number.isNaN(SnowflakeUtils.extractTimestamp(snowflake)); -} diff --git a/src/equicordplugins/gifCollections/utils/getUrlExtension.ts b/src/equicordplugins/gifCollections/utils/getUrlExtension.ts deleted file mode 100644 index f6f79a065..000000000 --- a/src/equicordplugins/gifCollections/utils/getUrlExtension.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 . -*/ - -export function getUrlExtension(url: string) { - // tennor stuff is like //media.tenor/blah/blah - if (!url.startsWith("https:")) url = "https:" + url; - return new URL(url).pathname.split(".").pop(); -} diff --git a/src/equicordplugins/gifCollections/utils/isAudio.ts b/src/equicordplugins/gifCollections/utils/isAudio.ts deleted file mode 100644 index aec5ee1e4..000000000 --- a/src/equicordplugins/gifCollections/utils/isAudio.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 { getUrlExtension } from "./getUrlExtension"; - -const audioExtensions = ["mp3", "wav", "ogg", "aac", "m4a", "wma", "flac"]; - - -export function isAudio(url: string) { - const extension = getUrlExtension(url); - return extension && audioExtensions.includes(extension); -} diff --git a/src/equicordplugins/gifCollections/utils/settingsUtils.ts b/src/equicordplugins/gifCollections/utils/settingsUtils.ts deleted file mode 100644 index 945ea9a4c..000000000 --- a/src/equicordplugins/gifCollections/utils/settingsUtils.ts +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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 { DataStore } from "@api/index"; -import { Toasts } from "@webpack/common"; - -import { DATA_COLLECTION_NAME, getCollections, refreshCacheCollection } from "../CollectionManager"; - -// 99% of this is coppied from src\utils\settingsSync.ts - -export async function downloadCollections() { - const filename = "gif-collections.json"; - const exportData = await exportCollections(); - const data = new TextEncoder().encode(exportData); - - if (IS_WEB) { - const file = new File([data], filename, { type: "application/json" }); - const a = document.createElement("a"); - a.href = URL.createObjectURL(file); - a.download = filename; - - document.body.appendChild(a); - a.click(); - setImmediate(() => { - URL.revokeObjectURL(a.href); - document.body.removeChild(a); - }); - } else { - DiscordNative.fileManager.saveWithDialog(data, filename); - } - -} - -export async function exportCollections() { - const collections = await getCollections(); - return JSON.stringify({ collections }, null, 4); -} - - -export async function importCollections(data: string) { - try { - var parsed = JSON.parse(data); - } catch (err) { - console.log(data); - throw new Error("Failed to parse JSON: " + String(err)); - } - - if ("collections" in parsed) { - await DataStore.set(DATA_COLLECTION_NAME, parsed.collections); - await refreshCacheCollection(); - } else - throw new Error("Invalid Collections"); -} - - -export async function uploadGifCollections(showToast = true): Promise { - if (IS_WEB) { - const input = document.createElement("input"); - input.type = "file"; - input.style.display = "none"; - input.accept = "application/json"; - input.onchange = async () => { - const file = input.files?.[0]; - if (!file) return; - - const reader = new FileReader(); - reader.onload = async () => { - try { - await importCollections(reader.result as string); - if (showToast) toastSuccess(); - } catch (err) { - console.error(err); - // new Logger("SettingsSync").error(err); - if (showToast) toastFailure(err); - } - }; - reader.readAsText(file); - }; - - document.body.appendChild(input); - input.click(); - setImmediate(() => document.body.removeChild(input)); - } else { - const [file] = await DiscordNative.fileManager.openFiles({ - filters: [ - { name: "Gif Collections", extensions: ["json"] }, - { name: "all", extensions: ["*"] } - ] - }); - - if (file) { - try { - await importCollections(new TextDecoder().decode(file.data)); - if (showToast) toastSuccess(); - } catch (err) { - console.error(err); - // new Logger("SettingsSync").error(err); - if (showToast) toastFailure(err); - } - } - } -} - - - -const toastSuccess = () => Toasts.show({ - type: Toasts.Type.SUCCESS, - message: "Settings successfully imported.", - id: Toasts.genId() -}); - -const toastFailure = (err: any) => Toasts.show({ - type: Toasts.Type.FAILURE, - message: `Failed to import settings: ${String(err)}`, - id: Toasts.genId() -}); diff --git a/src/equicordplugins/gifCollections/utils/uuidv4.ts b/src/equicordplugins/gifCollections/utils/uuidv4.ts deleted file mode 100644 index 033172799..000000000 --- a/src/equicordplugins/gifCollections/utils/uuidv4.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 { GIF_ITEM_PREFIX } from "../constants"; - -export function uuidv4() { - let d = new Date().getTime(); - d += performance.now(); - return `${GIF_ITEM_PREFIX}xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g, c => { - const r = (d + Math.random() * 16) % 16 | 0; - d = Math.floor(d / 16); - return (c === "x" ? r : (r & 0x3 | 0x8)).toString(16); - }); -} diff --git a/src/equicordplugins/searchFix/index.tsx b/src/equicordplugins/searchFix/index.tsx index 09fb3c738..cb7f9f5e2 100644 --- a/src/equicordplugins/searchFix/index.tsx +++ b/src/equicordplugins/searchFix/index.tsx @@ -26,7 +26,7 @@ export default definePlugin({ authors: [EquicordDevs.Jaxx], patches: [ { - find: ".displayName=\"SearchStore\";", + find: '"SearchStore",', replacement: { match: /(\i)\.offset=null!==\((\i)=(\i)\.offset\)&&void 0!==(\i)\?(\i):0/i, replace: (_, v, v1, query, v3, v4) => `$self.main(${query}), ${v}.offset = null !== (${v1} = ${query}.offset) && void 0 !== ${v3} ? ${v4} : 0` diff --git a/src/equicordplugins/themeLibrary/index.ts b/src/equicordplugins/themeLibrary/index.ts index e0370fe56..05f6afd7d 100644 --- a/src/equicordplugins/themeLibrary/index.ts +++ b/src/equicordplugins/themeLibrary/index.ts @@ -5,6 +5,7 @@ */ import { definePluginSettings } from "@api/Settings"; +import { EquicordDevs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { SettingsRouter } from "@webpack/common"; @@ -20,10 +21,7 @@ const settings = definePluginSettings({ export default definePlugin({ name: "ThemeLibrary", description: "A library of themes for Vencord.", - authors: [{ - name: "Fafa", - id: 428188716641812481n, - }], + authors: [EquicordDevs.Fafa], settings, toolboxActions: { "Open Theme Library": () => {