/* * Vencord, a Discord client mod * Copyright (c) 2024 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ 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, 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); export interface ChatBarProps { channel: Channel; disabled: boolean; isEmpty: boolean; type: { analyticsName: string; attachments: boolean; autocomplete: { addReactionShortcut: boolean, forceChatLayer: boolean, reactions: boolean; }, commands: { enabled: boolean; }, drafts: { type: number, commandType: number, autoSave: boolean; }, emojis: { button: boolean; }, gifs: { button: boolean, allowSending: boolean; }, gifts: { button: boolean; }, permissions: { requireSendMessages: boolean; }, showThreadPromptOnReply: boolean, stickers: { button: boolean, allowSending: boolean, autoSuggest: boolean; }, users: { allowMentioning: boolean; }, submit: { button: boolean, ignorePreference: boolean, disableEnterToSubmit: boolean, clearOnSubmit: boolean, useDisabledStylesOnSubmit: boolean; }, uploadLongMessages: boolean, upsellLongMessages: { iconOnly: boolean; }, showCharacterCount: boolean, sedReplace: boolean; }; } export type ChatBarButtonFactory = (props: ChatBarProps & { isMainChat: boolean; isAnyChat: 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; }; /** * 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; const { analyticsName } = props.type; return ( <> {Array.from(ChatBarButtonMap) .filter(([key]) => chatBarButtons[key]?.enabled !== false) .map(([key, { render: Button }]) => ( logger.error(`Failed to render ${key}`, e.error)}>