From ce64a1c2e49880b4759310a4f623ba3cfff27c66 Mon Sep 17 00:00:00 2001 From: Jakub Bednarski <45859721+Leon135@users.noreply.github.com> Date: Mon, 2 Mar 2026 03:06:15 +0100 Subject: [PATCH] feat(declutter): combine functionality of annamox & betteruserarea while adding new selectors to remove unwanted ui elements (#846) * feat(HidePersonalization): Add a plugin that allows to hide personalization features such as avatar decorations, nameplates, profile effects, and clan tags with customizable options * fix(HidePersonalization): Fix no predicate bool handling on clan tags * feat(Cleanify): Introduce Cleanify plugin to enhance UI customization and migrate settings from BetterUserArea and Anammox. This plugin combines the functionality of them and adds new features * rename(Cleanify -> Declutter): Rename plugin and add Questify conflict detection * Update index.tsx * Update index.tsx * Update index.tsx * Update index.tsx * Update index.tsx --------- Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com> --- src/equicordplugins/_api/userArea.ts | 4 +- src/equicordplugins/anammox/index.ts | 139 -------- src/equicordplugins/betterUserArea/index.ts | 130 -------- src/equicordplugins/declutter/index.tsx | 334 ++++++++++++++++++++ src/utils/constants.ts | 4 + 5 files changed, 340 insertions(+), 271 deletions(-) delete mode 100644 src/equicordplugins/anammox/index.ts delete mode 100644 src/equicordplugins/betterUserArea/index.ts create mode 100644 src/equicordplugins/declutter/index.tsx diff --git a/src/equicordplugins/_api/userArea.ts b/src/equicordplugins/_api/userArea.ts index 9ed35d0c8..4f0d731c6 100644 --- a/src/equicordplugins/_api/userArea.ts +++ b/src/equicordplugins/_api/userArea.ts @@ -5,7 +5,7 @@ */ import { isPluginEnabled } from "@api/PluginManager"; -import betterUserArea from "@equicordplugins/betterUserArea"; +import declutter from "@equicordplugins/declutter"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { findCssClassesLazy } from "@webpack"; @@ -43,6 +43,6 @@ export default definePlugin({ }, shouldHideTooltips() { - return isPluginEnabled(betterUserArea.name) && betterUserArea.settings.store.removeButtonTooltips; + return isPluginEnabled(declutter.name) && declutter.settings.store.removeButtonTooltips; } }); diff --git a/src/equicordplugins/anammox/index.ts b/src/equicordplugins/anammox/index.ts deleted file mode 100644 index 1ec80516c..000000000 --- a/src/equicordplugins/anammox/index.ts +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { definePluginSettings } from "@api/Settings"; -import { Devs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; - -export const settings = definePluginSettings({ - dms: { - type: OptionType.BOOLEAN, - default: true, - description: "Remove shops above DMs list", - restartNeeded: true, - }, - quests: { - type: OptionType.BOOLEAN, - default: false, - description: "Remove quests above DMs list", - restartNeeded: true, - }, - serverBoost: { - type: OptionType.BOOLEAN, - default: true, - description: "Remove server boost info above channel list", - restartNeeded: true, - }, - billing: { - type: OptionType.BOOLEAN, - default: true, - description: "Remove billing settings", - restartNeeded: true, - }, - gift: { - type: OptionType.BOOLEAN, - default: true, - description: "Remove gift button", - restartNeeded: true, - }, - emojiList: { - type: OptionType.BOOLEAN, - default: true, - description: "Remove unavailable categories from the emoji picker", - restartNeeded: true, - }, -}); - -export default definePlugin({ - name: "Anammox", - description: "Hides various features related to nitro and the store", - authors: [Devs.Kyuuhachi], - settings, - - patches: [ - { - // Above DMs, mouse nav - find: 'tutorialId:"direct-messages"', - replacement: [ - { - match: /"nitro-tab-group"\)/, - replace: "$&&&undefined", - predicate: () => settings.store.dms - }, - { - match: /"discord-shop"\)/, - replace: "$&&&undefined", - predicate: () => settings.store.dms - }, - { - match: /"quests"\)/, - replace: "$&&&undefined", - predicate: () => settings.store.quests - }, - ], - }, - { - // Above DMs, keyboard nav - find: ".hasLibraryApplication()&&!", - replacement: [ - { - match: /\i\.\i\.APPLICATION_STORE,/, - replace: "/*$&*/", - }, - { - match: /\i\.\i\.COLLECTIBLES_SHOP,/, - replace: "/*$&*/", - }, - ], - predicate: () => settings.store.dms, - }, - { - // Channel list server boost progress bar - find: "useGuildActionRow", - replacement: { - match: /(GUILD_NEW_MEMBER_ACTIONS_PROGRESS_BAR\)):(\i(?:\.premiumProgressBarEnabled)?)/, - replace: "$1:null" - }, - predicate: () => settings.store.serverBoost, - }, - { - // Settings, sidebar - find: ".BILLING_SECTION,", - replacement: { - match: /(?<=buildLayout:\(\)=>)\[.+?\]/, - replace: "[]", - }, - predicate: () => settings.store.billing, - }, - { - // Gift button - find: '"sticker")', - replacement: { - match: /&&\i\.push\(\([^&]*?,"gift"\)\)/, - replace: "", - }, - predicate: () => settings.store.gift, - }, - { - // Emoji list - find: "#{intl::EMOJI_PICKER_EXPAND_EMOJI_SECTION}),size:", - replacement: { - match: /(\i)=\i\|\|!\i&&\i.\i.isEmojiCategoryNitroLocked\(\{[^}]*\}\);/, - replace: "$&$1||" - }, - predicate: () => settings.store.emojiList, - }, - { - // Emoji category list - find: "#{intl::EMOJI_CATEGORY_TOP_GUILD_EMOJI},{guildName:", - replacement: { - match: /(?<=(\i)\.unshift\((\i)\):)(?=\1\.push\(\2\))/, - replace: "$2.isNitroLocked||" - }, - predicate: () => settings.store.emojiList, - } - ], -}); diff --git a/src/equicordplugins/betterUserArea/index.ts b/src/equicordplugins/betterUserArea/index.ts deleted file mode 100644 index 0d48d04f3..000000000 --- a/src/equicordplugins/betterUserArea/index.ts +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { definePluginSettings } from "@api/Settings"; -import { Devs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; - -const settings = definePluginSettings({ - removeNameplate: { - type: OptionType.BOOLEAN, - description: "Remove nameplate styling.", - default: true, - restartNeeded: true - }, - removeAudioMenus: { - type: OptionType.BOOLEAN, - description: "Remove menus next to mute and deafen buttons.", - default: true, - restartNeeded: true - }, - alwaysShowUsername: { - type: OptionType.BOOLEAN, - description: "Always show username instead of status.", - default: true, - restartNeeded: true - }, - removeButtonTooltips: { - type: OptionType.BOOLEAN, - description: "Remove button tooltips.", - default: false, - restartNeeded: true - }, - removeAvatarDecoration: { - type: OptionType.BOOLEAN, - description: "Remove avatar decoration.", - default: true, - restartNeeded: true - }, - removeUsernameStyles: { - type: OptionType.BOOLEAN, - description: "Remove username colors and effects.", - default: true, - restartNeeded: true - } -}); - -export default definePlugin({ - name: "BetterUserArea", - description: "Customize and make the user area more clean.", - authors: [Devs.prism], - settings, - patches: [ - { - find: ".NITRO_PRIVACY_PERK_BETA_COACHMARK));", - replacement: [ - { - match: /,nameplate:\i,selectedGuildId:(\i),avatarDecoration/, - replace: ",nameplate:null,selectedGuildId:$1,avatarDecoration", - predicate: () => settings.store.removeNameplate - }, - { - match: /hoverText:(\i),forceHover:\i,children:/g, - replace: "hoverText:$1,forceHover:!0,children:", - predicate: () => settings.store.alwaysShowUsername - }, - { - match: /avatarDecoration:(.{0,70}),size:/, - replace: "avatarDecoration:void 0,size:", - predicate: () => settings.store.removeAvatarDecoration - }, - { - match: /displayNameStyles:(\i),/, - replace: "displayNameStyles:void 0,", - predicate: () => settings.store.removeUsernameStyles - } - ], - }, - { - find: '"MicrophoneButton"', - replacement: [ - { - match: /:\{tooltipText:\i\};/, - replace: ":{tooltipText:void 0};", - predicate: () => settings.store.removeButtonTooltips - }, - { - match: /(?<=#{intl::MUTE}\),)className:\i\.\i,/, - replace: "", - predicate: () => settings.store.removeAudioMenus - }, - { - match: /,\(0,\i\.jsxs?\)\(\i\.\i,\{.{0,600}#{intl::ACCOUNT_INPUT_OPTIONS}\)\}\)(?=\])/, - replace: "", - predicate: () => settings.store.removeAudioMenus - }, - ], - }, - { - find: "#{intl::f+DDY/::raw},{outputDeviceName", - replacement: [ - { - match: /(?<=role:"switch",)tooltipText:\i\}/, - replace: "tooltipText:void 0}", - predicate: () => settings.store.removeButtonTooltips - }, - { - match: /(?<=#{intl::DEAFEN}\),)className:\i\.\i,/, - replace: "", - predicate: () => settings.store.removeAudioMenus - }, - { - match: /,\(0,\i\.jsxs?\)\(\i\.\i,\{.{0,650}#{intl::ACCOUNT_OUTPUT_OPTIONS}\)\}\)(?=\])/, - replace: "", - predicate: () => settings.store.removeAudioMenus - } - ], - }, - { - find: "#{intl::USER_SETTINGS_WITH_BUILD_OVERRIDE}", - replacement: { - match: /tooltipText:\i,tooltipPositionKey/, - replace: "tooltipText:void 0,tooltipPositionKey" - }, - predicate: () => settings.store.removeButtonTooltips - }, - ], -}); diff --git a/src/equicordplugins/declutter/index.tsx b/src/equicordplugins/declutter/index.tsx new file mode 100644 index 000000000..2aef52a4e --- /dev/null +++ b/src/equicordplugins/declutter/index.tsx @@ -0,0 +1,334 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2026 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { definePluginSettings, migratePluginSetting, migratePluginSettings } from "@api/Settings"; +import { HeadingSecondary } from "@components/Heading"; +import { Devs, EquicordDevs } from "@utils/index"; +import definePlugin, { OptionType } from "@utils/types"; + +migratePluginSettings("Declutter", "BetterUserArea", "Anammox"); + +const migrationsAnammox = [ + ["dms", "removeShopAboveDM"], + ["quests", "removeQuestsAboveDM"], + ["serverBoost", "removeServerBoostInfo"], + ["billing", "removeBillingSettings"], + ["gift", "removeGiftButton"], + ["emojiList", "removeUnavailableEmojiPicker"], +]; + +for (const [oldKey, newKey] of migrationsAnammox) { + migratePluginSetting("Anammox", newKey, oldKey); +} + +export const settings = definePluginSettings({ + userProfileHeader: { + type: OptionType.COMPONENT, + component: () => SectionSeparator("User Profile"), + }, + removeAvatarDecoration: { + type: OptionType.BOOLEAN, + description: "Remove avatar decorations.", + default: true, + restartNeeded: true, + }, + removeNameplate: { + type: OptionType.BOOLEAN, + description: "Remove nameplates.", + default: true, + restartNeeded: true, + }, + removeProfileEffect: { + type: OptionType.BOOLEAN, + description: "Remove profile animation effects on open.", + default: true, + restartNeeded: true, + }, + removeClanTag: { + type: OptionType.BOOLEAN, + description: "Remove clan tags.", + default: true, + restartNeeded: true, + }, + alwaysShowUsername: { + type: OptionType.BOOLEAN, + description: "Always show username instead of status.", + default: true, + restartNeeded: true + }, + removeUsernameStyles: { + type: OptionType.BOOLEAN, + description: "Remove username colors and effects.", + default: true, + restartNeeded: true + }, + friendsListHeader: { + type: OptionType.COMPONENT, + component: () => SectionSeparator("Above Friends/DMs List"), + }, + removeShopAboveDM: { + type: OptionType.BOOLEAN, + description: "Remove shops above DMs list.", + default: true, + restartNeeded: true, + }, + removeQuestsAboveDM: { + type: OptionType.BOOLEAN, + description: "Remove quests above DMs list.", + default: false, + restartNeeded: true, + }, + miscHeader: { + type: OptionType.COMPONENT, + component: () => SectionSeparator("Misc"), + }, + removeServerBoostInfo: { + type: OptionType.BOOLEAN, + description: "Remove server boost info above channel list.", + default: true, + restartNeeded: true, + }, + removeBillingSettings: { + type: OptionType.BOOLEAN, + description: "Remove billing settings.", + default: true, + restartNeeded: true, + }, + removeGiftButton: { + type: OptionType.BOOLEAN, + description: "Remove gift button.", + default: true, + restartNeeded: true, + }, + removeUnavailableEmojiPicker: { + type: OptionType.BOOLEAN, + description: "Remove unavailable categories from the emoji picker.", + default: true, + restartNeeded: true, + }, + removeAudioMenus: { + type: OptionType.BOOLEAN, + description: "Remove menus next to mute and deafen buttons.", + default: true, + restartNeeded: true + }, + removeButtonTooltips: { + type: OptionType.BOOLEAN, + description: "Remove button tooltips.", + default: false, + restartNeeded: true + }, +}); + +function SectionSeparator(title: string) { + return ( + <> +