From eb5a42dd872d34e8c81016d1ec140cd03b4d04a0 Mon Sep 17 00:00:00 2001 From: V Date: Fri, 21 Nov 2025 13:53:30 +0100 Subject: [PATCH] Add the option to toggle plugin chatbar & message hover buttons (#3693) --- src/api/ChatButtons.tsx | 84 ++++++++++++-- src/api/MessagePopover.tsx | 71 ++++++++---- src/api/PluginManager.ts | 20 ++-- src/api/Settings.ts | 22 ++++ src/components/Icons.tsx | 14 +++ .../settings/tabs/plugins/UIElements.css | 42 +++++++ .../settings/tabs/plugins/UIElements.tsx | 107 ++++++++++++++++++ .../settings/tabs/plugins/index.tsx | 3 + src/plugins/hideAttachments/index.tsx | 41 +++---- src/plugins/previewMessage/index.tsx | 34 ++++-- src/plugins/quickMention/index.tsx | 51 +++++---- src/plugins/sendTimestamps/index.tsx | 42 ++++--- src/plugins/silentMessageToggle/index.tsx | 50 +++++--- src/plugins/silentTyping/index.tsx | 47 +++++--- src/plugins/translate/TranslateIcon.tsx | 5 +- src/plugins/translate/index.tsx | 34 +++--- src/plugins/viewRaw/index.tsx | 88 ++++++++------ src/utils/types.ts | 40 ++++--- 18 files changed, 586 insertions(+), 209 deletions(-) create mode 100644 src/components/settings/tabs/plugins/UIElements.css create mode 100644 src/components/settings/tabs/plugins/UIElements.tsx diff --git a/src/api/ChatButtons.tsx b/src/api/ChatButtons.tsx index 3c5e59a73..52052a528 100644 --- a/src/api/ChatButtons.tsx +++ b/src/api/ChatButtons.tsx @@ -9,11 +9,15 @@ import "./ChatButton.css"; import ErrorBoundary from "@components/ErrorBoundary"; import { Logger } from "@utils/Logger"; import { classes } from "@utils/misc"; +import { IconComponent } from "@utils/types"; import { Channel } from "@vencord/discord-types"; import { waitFor } from "@webpack"; -import { ButtonWrapperClasses, Clickable, Tooltip } from "@webpack/common"; +import { ButtonWrapperClasses, Clickable, Menu, Tooltip } from "@webpack/common"; import { HTMLProps, JSX, MouseEventHandler, ReactNode } from "react"; +import { addContextMenuPatch, findGroupChildrenByChildId } from "./ContextMenu"; +import { useSettings } from "./Settings"; + let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>; waitFor(["buttonContainer", "channelTextArea"], m => ChannelTextAreaClasses = m); @@ -76,26 +80,51 @@ export interface ChatBarProps { } export type ChatBarButtonFactory = (props: ChatBarProps & { isMainChat: boolean; }) => JSX.Element | null; +export type ChatBarButtonData = { + render: ChatBarButtonFactory; + /** + * This icon is used only for Settings UI. Your render function must still render an icon, + * and it can be different from this one. + */ + icon: IconComponent; +}; -const buttonFactories = new Map(); +/** + * Don't use this directly, use {@link addChatBarButton} and {@link removeChatBarButton} instead. + */ +export const ChatBarButtonMap = new Map(); const logger = new Logger("ChatButtons"); +function VencordChatBarButtons(props: ChatBarProps) { + const { chatBarButtons } = useSettings(["uiElements.chatBarButtons.*"]).uiElements; + + return ( + <> + {Array.from(ChatBarButtonMap) + .filter(([key]) => chatBarButtons[key]?.enabled !== false) + .map(([key, { render: Button }]) => ( + logger.error(`Failed to render ${key}`, e.error)}> +