parent
8938f4a3cf
commit
bf977e0047
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
|
import { Logger } from "@utils/Logger";
|
||||||
|
import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common";
|
||||||
|
import { Channel } from "discord-types/general";
|
||||||
|
import { HTMLProps, MouseEventHandler, ReactNode } from "react";
|
||||||
|
|
||||||
|
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 ChatBarButton = (props: ChatBarProps, isMainChat: boolean) => ReactNode;
|
||||||
|
|
||||||
|
const buttonFactories = new Map<string, ChatBarButton>();
|
||||||
|
const logger = new Logger("ChatButtons");
|
||||||
|
|
||||||
|
export function _injectButtons(buttons: ReactNode[], props: ChatBarProps) {
|
||||||
|
if (props.type.analyticsName !== "normal") return;
|
||||||
|
|
||||||
|
for (const [key, makeButton] of buttonFactories) {
|
||||||
|
try {
|
||||||
|
const res = makeButton(props, props.type.analyticsName === "normal");
|
||||||
|
if (res) buttons.push(res);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`Failed to render button ${key}`, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const addChatBarButton = (id: string, button: ChatBarButton) => buttonFactories.set(id, button);
|
||||||
|
export const removeChatBarButton = (id: string) => buttonFactories.delete(id);
|
||||||
|
|
||||||
|
export interface ChatBarButtonProps {
|
||||||
|
children: ReactNode;
|
||||||
|
tooltip: string;
|
||||||
|
onClick: MouseEventHandler<HTMLButtonElement>;
|
||||||
|
onContextMenu?: MouseEventHandler<HTMLButtonElement>;
|
||||||
|
buttonProps?: Omit<HTMLProps<HTMLButtonElement>, "size" | "onClick" | "onContextMenu">;
|
||||||
|
}
|
||||||
|
export const ChatBarButton = ErrorBoundary.wrap((props: ChatBarButtonProps) => {
|
||||||
|
return (
|
||||||
|
<Tooltip text={props.tooltip}>
|
||||||
|
{({ onMouseEnter, onMouseLeave }) => (
|
||||||
|
<div style={{ display: "flex" }}>
|
||||||
|
<Button
|
||||||
|
aria-label={props.tooltip}
|
||||||
|
size=""
|
||||||
|
look={ButtonLooks.BLANK}
|
||||||
|
onMouseEnter={onMouseEnter}
|
||||||
|
onMouseLeave={onMouseLeave}
|
||||||
|
innerClassName={ButtonWrapperClasses.button}
|
||||||
|
onClick={props.onClick}
|
||||||
|
onContextMenu={props.onContextMenu}
|
||||||
|
{...props.buttonProps}
|
||||||
|
>
|
||||||
|
<div className={ButtonWrapperClasses.buttonWrapper}>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}, { noop: true });
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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";
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "ChatInputButtonAPI",
|
||||||
|
description: "API to add buttons to the chat input",
|
||||||
|
authors: [Devs.Ven],
|
||||||
|
|
||||||
|
patches: [{
|
||||||
|
find: 'location:"ChannelTextAreaButtons"',
|
||||||
|
replacement: {
|
||||||
|
match: /if\(!\i\.isMobile\)\{(?=.+?&&(\i)\.push\(.{0,50}"gift")/,
|
||||||
|
replace: "$&Vencord.Api.ChatButtons._injectButtons($1,arguments[0]);"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
Loading…
Reference in new issue