Add chat bar button api ~ fixes buttons for russian users
This commit is contained in:
		
							parent
							
								
									8938f4a3cf
								
							
						
					
					
						commit
						bf977e0047
					
				
					 10 changed files with 325 additions and 307 deletions
				
			
		
							
								
								
									
										123
									
								
								src/api/ChatButtons.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/api/ChatButtons.tsx
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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 });
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,7 @@
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as $Badges from "./Badges";
 | 
					import * as $Badges from "./Badges";
 | 
				
			||||||
 | 
					import * as $ChatButtons from "./ChatButtons";
 | 
				
			||||||
import * as $Commands from "./Commands";
 | 
					import * as $Commands from "./Commands";
 | 
				
			||||||
import * as $ContextMenu from "./ContextMenu";
 | 
					import * as $ContextMenu from "./ContextMenu";
 | 
				
			||||||
import * as $DataStore from "./DataStore";
 | 
					import * as $DataStore from "./DataStore";
 | 
				
			||||||
| 
						 | 
					@ -104,3 +105,8 @@ export const Notifications = $Notifications;
 | 
				
			||||||
 * An api allowing you to patch and add/remove items to/from context menus
 | 
					 * An api allowing you to patch and add/remove items to/from context menus
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export const ContextMenu = $ContextMenu;
 | 
					export const ContextMenu = $ContextMenu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * An API allowing you to add buttons to the chat input
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const ChatButtons = $ChatButtons;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								src/plugins/_api/chatButtons.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/plugins/_api/chatButtons.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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]);"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }]
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -16,13 +16,14 @@
 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { addChatBarButton, ChatBarButton } from "@api/ChatButtons";
 | 
				
			||||||
import { addButton, removeButton } from "@api/MessagePopover";
 | 
					import { addButton, removeButton } from "@api/MessagePopover";
 | 
				
			||||||
import { definePluginSettings } from "@api/Settings";
 | 
					import { definePluginSettings } from "@api/Settings";
 | 
				
			||||||
import ErrorBoundary from "@components/ErrorBoundary";
 | 
					import ErrorBoundary from "@components/ErrorBoundary";
 | 
				
			||||||
import { Devs } from "@utils/constants";
 | 
					import { Devs } from "@utils/constants";
 | 
				
			||||||
import { getStegCloak } from "@utils/dependencies";
 | 
					import { getStegCloak } from "@utils/dependencies";
 | 
				
			||||||
import definePlugin, { OptionType } from "@utils/types";
 | 
					import definePlugin, { OptionType } from "@utils/types";
 | 
				
			||||||
import { Button, ButtonLooks, ButtonWrapperClasses, ChannelStore, FluxDispatcher, RestAPI, Tooltip } from "@webpack/common";
 | 
					import { ChannelStore, FluxDispatcher, RestAPI, Tooltip } from "@webpack/common";
 | 
				
			||||||
import { Message } from "discord-types/general";
 | 
					import { Message } from "discord-types/general";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { buildDecModal } from "./components/DecryptionModal";
 | 
					import { buildDecModal } from "./components/DecryptionModal";
 | 
				
			||||||
| 
						 | 
					@ -64,54 +65,32 @@ function Indicator() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ChatBarIcon(chatBoxProps: {
 | 
					const ChatBarIcon: ChatBarButton = (_, isMainChat) => {
 | 
				
			||||||
    type: {
 | 
					    if (!isMainChat) return null;
 | 
				
			||||||
        analyticsName: string;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}) {
 | 
					 | 
				
			||||||
    if (chatBoxProps.type.analyticsName !== "normal") return null;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <Tooltip text="Encrypt Message">
 | 
					        <ChatBarButton
 | 
				
			||||||
            {({ onMouseEnter, onMouseLeave }) => (
 | 
					            tooltip="Encrypt Message"
 | 
				
			||||||
                // size="" = Button.Sizes.NONE
 | 
					            onClick={() => buildEncModal()}
 | 
				
			||||||
                /*
 | 
					
 | 
				
			||||||
                    many themes set "> button" to display: none, as the gift button is
 | 
					            buttonProps={{
 | 
				
			||||||
                    the only directly descending button (all the other elements are divs.)
 | 
					                "aria-haspopup": "dialog",
 | 
				
			||||||
                    Thus, wrap in a div here to avoid getting hidden by that.
 | 
					                style: { padding: "0 2px", scale: "0.9" }
 | 
				
			||||||
                    flex is for some reason necessary as otherwise the button goes flying off
 | 
					            }}
 | 
				
			||||||
                */
 | 
					        >
 | 
				
			||||||
                <div style={{ display: "flex" }}>
 | 
					            <svg
 | 
				
			||||||
                    <Button
 | 
					                aria-hidden
 | 
				
			||||||
                        aria-haspopup="dialog"
 | 
					                role="img"
 | 
				
			||||||
                        aria-label="Encrypt Message"
 | 
					                width="32"
 | 
				
			||||||
                        size=""
 | 
					                height="32"
 | 
				
			||||||
                        look={ButtonLooks.BLANK}
 | 
					                viewBox={"0 0 64 64"}
 | 
				
			||||||
                        onMouseEnter={onMouseEnter}
 | 
					                style={{ scale: "1.1" }}
 | 
				
			||||||
                        onMouseLeave={onMouseLeave}
 | 
					            >
 | 
				
			||||||
                        innerClassName={ButtonWrapperClasses.button}
 | 
					                <path fill="currentColor" d="M 32 9 C 24.832 9 19 14.832 19 22 L 19 27.347656 C 16.670659 28.171862 15 30.388126 15 33 L 15 49 C 15 52.314 17.686 55 21 55 L 43 55 C 46.314 55 49 52.314 49 49 L 49 33 C 49 30.388126 47.329341 28.171862 45 27.347656 L 45 22 C 45 14.832 39.168 9 32 9 z M 32 13 C 36.963 13 41 17.038 41 22 L 41 27 L 23 27 L 23 22 C 23 17.038 27.037 13 32 13 z" />
 | 
				
			||||||
                        onClick={() => buildEncModal()}
 | 
					            </svg>
 | 
				
			||||||
                        style={{ padding: "0 2px", scale: "0.9" }}
 | 
					        </ChatBarButton>
 | 
				
			||||||
                    >
 | 
					 | 
				
			||||||
                        <div className={ButtonWrapperClasses.buttonWrapper}>
 | 
					 | 
				
			||||||
                            <svg
 | 
					 | 
				
			||||||
                                aria-hidden
 | 
					 | 
				
			||||||
                                role="img"
 | 
					 | 
				
			||||||
                                width="32"
 | 
					 | 
				
			||||||
                                height="32"
 | 
					 | 
				
			||||||
                                viewBox={"0 0 64 64"}
 | 
					 | 
				
			||||||
                                style={{ scale: "1.1" }}
 | 
					 | 
				
			||||||
                            >
 | 
					 | 
				
			||||||
                                <path fill="currentColor" d="M 32 9 C 24.832 9 19 14.832 19 22 L 19 27.347656 C 16.670659 28.171862 15 30.388126 15 33 L 15 49 C 15 52.314 17.686 55 21 55 L 43 55 C 46.314 55 49 52.314 49 49 L 49 33 C 49 30.388126 47.329341 28.171862 45 27.347656 L 45 22 C 45 14.832 39.168 9 32 9 z M 32 13 C 36.963 13 41 17.038 41 22 L 41 27 L 23 27 L 23 22 C 23 17.038 27.037 13 32 13 z" />
 | 
					 | 
				
			||||||
                            </svg>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                    </Button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        </Tooltip >
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const settings = definePluginSettings({
 | 
					const settings = definePluginSettings({
 | 
				
			||||||
    savedPasswords: {
 | 
					    savedPasswords: {
 | 
				
			||||||
| 
						 | 
					@ -125,7 +104,7 @@ export default definePlugin({
 | 
				
			||||||
    name: "InvisibleChat",
 | 
					    name: "InvisibleChat",
 | 
				
			||||||
    description: "Encrypt your Messages in a non-suspicious way!",
 | 
					    description: "Encrypt your Messages in a non-suspicious way!",
 | 
				
			||||||
    authors: [Devs.SammCheese],
 | 
					    authors: [Devs.SammCheese],
 | 
				
			||||||
    dependencies: ["MessagePopoverAPI"],
 | 
					    dependencies: ["MessagePopoverAPI", "ChatInputButtonAPI"],
 | 
				
			||||||
    patches: [
 | 
					    patches: [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Indicator
 | 
					            // Indicator
 | 
				
			||||||
| 
						 | 
					@ -135,13 +114,6 @@ export default definePlugin({
 | 
				
			||||||
                replace: "try {$1 && $self.INV_REGEX.test($1.message.content) ? $1.content.push($self.indicator()) : null } catch {};$&"
 | 
					                replace: "try {$1 && $self.INV_REGEX.test($1.message.content) ? $1.content.push($self.indicator()) : null } catch {};$&"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            find: "ChannelTextAreaButtons",
 | 
					 | 
				
			||||||
            replacement: {
 | 
					 | 
				
			||||||
                match: /(\i)\.push.{1,30}disabled:(\i),.{1,20}\},"gift"\)\)/,
 | 
					 | 
				
			||||||
                replace: "$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EMBED_API_URL: "https://embed.sammcheese.net",
 | 
					    EMBED_API_URL: "https://embed.sammcheese.net",
 | 
				
			||||||
| 
						 | 
					@ -154,7 +126,7 @@ export default definePlugin({
 | 
				
			||||||
        const { default: StegCloak } = await getStegCloak();
 | 
					        const { default: StegCloak } = await getStegCloak();
 | 
				
			||||||
        steggo = new StegCloak(true, false);
 | 
					        steggo = new StegCloak(true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        addButton("invDecrypt", message => {
 | 
					        addButton("InvisibleChat", message => {
 | 
				
			||||||
            return this.INV_REGEX.test(message?.content)
 | 
					            return this.INV_REGEX.test(message?.content)
 | 
				
			||||||
                ? {
 | 
					                ? {
 | 
				
			||||||
                    label: "Decrypt Message",
 | 
					                    label: "Decrypt Message",
 | 
				
			||||||
| 
						 | 
					@ -170,10 +142,13 @@ export default definePlugin({
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                : null;
 | 
					                : null;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        addChatBarButton("InvisibleChat", ChatBarIcon);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stop() {
 | 
					    stop() {
 | 
				
			||||||
        removeButton("invDecrypt");
 | 
					        removeButton("InvisibleChat");
 | 
				
			||||||
 | 
					        removeButton("InvisibleChat");
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Gets the Embed of a Link
 | 
					    // Gets the Embed of a Link
 | 
				
			||||||
| 
						 | 
					@ -216,7 +191,6 @@ export default definePlugin({
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    chatBarIcon: ErrorBoundary.wrap(ChatBarIcon, { noop: true }),
 | 
					 | 
				
			||||||
    popOverIcon: () => <PopOverIcon />,
 | 
					    popOverIcon: () => <PopOverIcon />,
 | 
				
			||||||
    indicator: ErrorBoundary.wrap(Indicator, { noop: true })
 | 
					    indicator: ErrorBoundary.wrap(Indicator, { noop: true })
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,22 +16,14 @@
 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { addChatBarButton, ChatBarButton, removeChatBarButton } from "@api/ChatButtons";
 | 
				
			||||||
import { generateId, sendBotMessage } from "@api/Commands";
 | 
					import { generateId, sendBotMessage } from "@api/Commands";
 | 
				
			||||||
import ErrorBoundary from "@components/ErrorBoundary";
 | 
					 | 
				
			||||||
import { Devs } from "@utils/constants";
 | 
					import { Devs } from "@utils/constants";
 | 
				
			||||||
import definePlugin from "@utils/types";
 | 
					import definePlugin from "@utils/types";
 | 
				
			||||||
import { findByPropsLazy } from "@webpack";
 | 
					import { findByPropsLazy } from "@webpack";
 | 
				
			||||||
import { Button, ButtonLooks, ButtonWrapperClasses, DraftStore, DraftType, SelectedChannelStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common";
 | 
					import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common";
 | 
				
			||||||
import { MessageAttachment } from "discord-types/general";
 | 
					import { MessageAttachment } from "discord-types/general";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Props {
 | 
					 | 
				
			||||||
    type: {
 | 
					 | 
				
			||||||
        analyticsName: string;
 | 
					 | 
				
			||||||
        isEmpty: boolean;
 | 
					 | 
				
			||||||
        attachments: boolean;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const UploadStore = findByPropsLazy("getUploads");
 | 
					const UploadStore = findByPropsLazy("getUploads");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getDraft = (channelId: string) => DraftStore.getDraft(channelId, DraftType.ChannelMessage);
 | 
					const getDraft = (channelId: string) => DraftStore.getDraft(channelId, DraftType.ChannelMessage);
 | 
				
			||||||
| 
						 | 
					@ -81,13 +73,13 @@ const getAttachments = async (channelId: string) =>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function PreviewButton(chatBoxProps: Props) {
 | 
					const PreviewButton: ChatBarButton = (props, isMainChat) => {
 | 
				
			||||||
    const { isEmpty, attachments } = chatBoxProps.type;
 | 
					    const { isEmpty, type: { attachments } } = props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const channelId = SelectedChannelStore.getChannelId();
 | 
					    const channelId = SelectedChannelStore.getChannelId();
 | 
				
			||||||
    const draft = useStateFromStores([DraftStore], () => getDraft(channelId));
 | 
					    const draft = useStateFromStores([DraftStore], () => getDraft(channelId));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (chatBoxProps.type.analyticsName !== "normal") return null;
 | 
					    if (!isMainChat) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const hasAttachments = attachments && UploadStore.getUploads(channelId, DraftType.ChannelMessage).length > 0;
 | 
					    const hasAttachments = attachments && UploadStore.getUploads(channelId, DraftType.ChannelMessage).length > 0;
 | 
				
			||||||
    const hasContent = !isEmpty && draft?.length > 0;
 | 
					    const hasContent = !isEmpty && draft?.length > 0;
 | 
				
			||||||
| 
						 | 
					@ -95,47 +87,33 @@ export function PreviewButton(chatBoxProps: Props) {
 | 
				
			||||||
    if (!hasContent && !hasAttachments) return null;
 | 
					    if (!hasContent && !hasAttachments) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <Tooltip text="Preview Message">
 | 
					        <ChatBarButton
 | 
				
			||||||
            {tooltipProps => (
 | 
					            tooltip="Preview Message"
 | 
				
			||||||
                <Button
 | 
					            onClick={async () =>
 | 
				
			||||||
                    {...tooltipProps}
 | 
					                sendBotMessage(
 | 
				
			||||||
                    onClick={async () =>
 | 
					                    channelId,
 | 
				
			||||||
                        sendBotMessage(
 | 
					                    {
 | 
				
			||||||
                            channelId,
 | 
					                        content: getDraft(channelId),
 | 
				
			||||||
                            {
 | 
					                        author: UserStore.getCurrentUser(),
 | 
				
			||||||
                                content: getDraft(channelId),
 | 
					                        attachments: hasAttachments ? await getAttachments(channelId) : undefined,
 | 
				
			||||||
                                author: UserStore.getCurrentUser(),
 | 
					                    }
 | 
				
			||||||
                                attachments: hasAttachments ? await getAttachments(channelId) : undefined,
 | 
					                )}
 | 
				
			||||||
                            }
 | 
					            buttonProps={{
 | 
				
			||||||
                        )}
 | 
					                style: { padding: "0 2px", height: "100%" }
 | 
				
			||||||
                    size=""
 | 
					            }}
 | 
				
			||||||
                    look={ButtonLooks.BLANK}
 | 
					        >
 | 
				
			||||||
                    innerClassName={ButtonWrapperClasses.button}
 | 
					            <img width={24} height={24} src="https://discord.com/assets/4c5a77a89716352686f590a6f014770c.svg" />
 | 
				
			||||||
                    style={{ padding: "0 2px", height: "100%" }}
 | 
					        </ChatBarButton>
 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                    <div className={ButtonWrapperClasses.buttonWrapper}>
 | 
					 | 
				
			||||||
                        <img width={24} height={24} src="https://discord.com/assets/4c5a77a89716352686f590a6f014770c.svg" />
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                </Button>
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
        </Tooltip>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default definePlugin({
 | 
					export default definePlugin({
 | 
				
			||||||
    name: "PreviewMessage",
 | 
					    name: "PreviewMessage",
 | 
				
			||||||
    description: "Lets you preview your message before sending it.",
 | 
					    description: "Lets you preview your message before sending it.",
 | 
				
			||||||
    authors: [Devs.Aria],
 | 
					    authors: [Devs.Aria],
 | 
				
			||||||
    patches: [
 | 
					    dependencies: ["ChatInputButtonAPI"],
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            find: "ChannelTextAreaButtons",
 | 
					 | 
				
			||||||
            replacement: {
 | 
					 | 
				
			||||||
                match: /(\i)\.push.{1,30}disabled:(\i),.{1,20}\},"gift"\)\)/,
 | 
					 | 
				
			||||||
                replace: "$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    chatBarIcon: ErrorBoundary.wrap(PreviewButton, { noop: true }),
 | 
					    start: () => addChatBarButton("previewMessage", PreviewButton),
 | 
				
			||||||
 | 
					    stop: () => removeChatBarButton("previewMessage"),
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "./styles.css";
 | 
					import "./styles.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { addChatBarButton, ChatBarButton, removeChatBarButton } from "@api/ChatButtons";
 | 
				
			||||||
import { addPreSendListener, removePreSendListener } from "@api/MessageEvents";
 | 
					import { addPreSendListener, removePreSendListener } from "@api/MessageEvents";
 | 
				
			||||||
import { definePluginSettings } from "@api/Settings";
 | 
					import { definePluginSettings } from "@api/Settings";
 | 
				
			||||||
import { classNameFactory } from "@api/Styles";
 | 
					import { classNameFactory } from "@api/Styles";
 | 
				
			||||||
| 
						 | 
					@ -26,7 +27,7 @@ import { getTheme, insertTextIntoChatInputBox, Theme } from "@utils/discord";
 | 
				
			||||||
import { Margins } from "@utils/margins";
 | 
					import { Margins } from "@utils/margins";
 | 
				
			||||||
import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal";
 | 
					import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal";
 | 
				
			||||||
import definePlugin, { OptionType } from "@utils/types";
 | 
					import definePlugin, { OptionType } from "@utils/types";
 | 
				
			||||||
import { Button, ButtonLooks, ButtonWrapperClasses, Forms, Parser, Select, Tooltip, useMemo, useState } from "@webpack/common";
 | 
					import { Button, Forms, Parser, Select, useMemo, useState } from "@webpack/common";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const settings = definePluginSettings({
 | 
					const settings = definePluginSettings({
 | 
				
			||||||
    replaceMessageContents: {
 | 
					    replaceMessageContents: {
 | 
				
			||||||
| 
						 | 
					@ -122,25 +123,51 @@ function PickerModal({ rootProps, close }: { rootProps: ModalProps, close(): voi
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ChatBarIcon: ChatBarButton = (_, isMainChat) => {
 | 
				
			||||||
 | 
					    if (!isMainChat) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <ChatBarButton
 | 
				
			||||||
 | 
					            tooltip="Insert Timestamp"
 | 
				
			||||||
 | 
					            onClick={() => {
 | 
				
			||||||
 | 
					                const key = openModal(props => (
 | 
				
			||||||
 | 
					                    <PickerModal
 | 
				
			||||||
 | 
					                        rootProps={props}
 | 
				
			||||||
 | 
					                        close={() => closeModal(key)}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					            buttonProps={{
 | 
				
			||||||
 | 
					                "aria-haspopup": "dialog",
 | 
				
			||||||
 | 
					                className: cl("button")
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <svg
 | 
				
			||||||
 | 
					                aria-hidden="true"
 | 
				
			||||||
 | 
					                role="img"
 | 
				
			||||||
 | 
					                width="24"
 | 
				
			||||||
 | 
					                height="24"
 | 
				
			||||||
 | 
					                viewBox="0 0 24 24"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                <g fill="none" fill-rule="evenodd">
 | 
				
			||||||
 | 
					                    <path fill="currentColor" d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7v-5z" />
 | 
				
			||||||
 | 
					                    <rect width="24" height="24" />
 | 
				
			||||||
 | 
					                </g>
 | 
				
			||||||
 | 
					            </svg>
 | 
				
			||||||
 | 
					        </ChatBarButton>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default definePlugin({
 | 
					export default definePlugin({
 | 
				
			||||||
    name: "SendTimestamps",
 | 
					    name: "SendTimestamps",
 | 
				
			||||||
    description: "Send timestamps easily via chat box button & text shortcuts. Read the extended description!",
 | 
					    description: "Send timestamps easily via chat box button & text shortcuts. Read the extended description!",
 | 
				
			||||||
    authors: [Devs.Ven, Devs.Tyler, Devs.Grzesiek11],
 | 
					    authors: [Devs.Ven, Devs.Tyler, Devs.Grzesiek11],
 | 
				
			||||||
    dependencies: ["MessageEventsAPI"],
 | 
					    dependencies: ["MessageEventsAPI", "ChatInputButtonAPI"],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    settings: settings,
 | 
					    settings,
 | 
				
			||||||
 | 
					 | 
				
			||||||
    patches: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            find: "ChannelTextAreaButtons",
 | 
					 | 
				
			||||||
            replacement: {
 | 
					 | 
				
			||||||
                match: /(\i)\.push.{1,30}disabled:(\i),.{1,20}\},"gift"\)\)/,
 | 
					 | 
				
			||||||
                replace: "$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    start() {
 | 
					    start() {
 | 
				
			||||||
 | 
					        addChatBarButton("SendTimestamps", ChatBarIcon);
 | 
				
			||||||
        this.listener = addPreSendListener((_, msg) => {
 | 
					        this.listener = addPreSendListener((_, msg) => {
 | 
				
			||||||
            if (settings.store.replaceMessageContents) {
 | 
					            if (settings.store.replaceMessageContents) {
 | 
				
			||||||
                msg.content = msg.content.replace(/`\d{1,2}:\d{2} ?(?:AM|PM)?`/gi, parseTime);
 | 
					                msg.content = msg.content.replace(/`\d{1,2}:\d{2} ?(?:AM|PM)?`/gi, parseTime);
 | 
				
			||||||
| 
						 | 
					@ -149,56 +176,10 @@ export default definePlugin({
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stop() {
 | 
					    stop() {
 | 
				
			||||||
 | 
					        removeChatBarButton("SendTimestamps");
 | 
				
			||||||
        removePreSendListener(this.listener);
 | 
					        removePreSendListener(this.listener);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    chatBarIcon(chatBoxProps: { type: { analyticsName: string; }; }) {
 | 
					 | 
				
			||||||
        if (chatBoxProps.type.analyticsName !== "normal") return null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return (
 | 
					 | 
				
			||||||
            <Tooltip text="Insert Timestamp">
 | 
					 | 
				
			||||||
                {({ onMouseEnter, onMouseLeave }) => (
 | 
					 | 
				
			||||||
                    <div style={{ display: "flex" }}>
 | 
					 | 
				
			||||||
                        <Button
 | 
					 | 
				
			||||||
                            aria-haspopup="dialog"
 | 
					 | 
				
			||||||
                            aria-label="Insert Timestamp"
 | 
					 | 
				
			||||||
                            size=""
 | 
					 | 
				
			||||||
                            look={ButtonLooks.BLANK}
 | 
					 | 
				
			||||||
                            onMouseEnter={onMouseEnter}
 | 
					 | 
				
			||||||
                            onMouseLeave={onMouseLeave}
 | 
					 | 
				
			||||||
                            innerClassName={ButtonWrapperClasses.button}
 | 
					 | 
				
			||||||
                            onClick={() => {
 | 
					 | 
				
			||||||
                                const key = openModal(props => (
 | 
					 | 
				
			||||||
                                    <PickerModal
 | 
					 | 
				
			||||||
                                        rootProps={props}
 | 
					 | 
				
			||||||
                                        close={() => closeModal(key)}
 | 
					 | 
				
			||||||
                                    />
 | 
					 | 
				
			||||||
                                ));
 | 
					 | 
				
			||||||
                            }}
 | 
					 | 
				
			||||||
                            className={cl("button")}
 | 
					 | 
				
			||||||
                        >
 | 
					 | 
				
			||||||
                            <div className={ButtonWrapperClasses.buttonWrapper}>
 | 
					 | 
				
			||||||
                                <svg
 | 
					 | 
				
			||||||
                                    aria-hidden="true"
 | 
					 | 
				
			||||||
                                    role="img"
 | 
					 | 
				
			||||||
                                    width="24"
 | 
					 | 
				
			||||||
                                    height="24"
 | 
					 | 
				
			||||||
                                    viewBox="0 0 24 24"
 | 
					 | 
				
			||||||
                                >
 | 
					 | 
				
			||||||
                                    <g fill="none" fill-rule="evenodd">
 | 
					 | 
				
			||||||
                                        <path fill="currentColor" d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7v-5z" />
 | 
					 | 
				
			||||||
                                        <rect width="24" height="24" />
 | 
					 | 
				
			||||||
                                    </g>
 | 
					 | 
				
			||||||
                                </svg>
 | 
					 | 
				
			||||||
                            </div>
 | 
					 | 
				
			||||||
                        </Button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            </Tooltip >
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    settingsAboutComponent() {
 | 
					    settingsAboutComponent() {
 | 
				
			||||||
        const samples = [
 | 
					        const samples = [
 | 
				
			||||||
            "12:00",
 | 
					            "12:00",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,12 +16,12 @@
 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { addChatBarButton, ChatBarButton, removeChatBarButton } from "@api/ChatButtons";
 | 
				
			||||||
import { addPreSendListener, removePreSendListener, SendListener } from "@api/MessageEvents";
 | 
					import { addPreSendListener, removePreSendListener, SendListener } from "@api/MessageEvents";
 | 
				
			||||||
import { definePluginSettings } from "@api/Settings";
 | 
					import { definePluginSettings } from "@api/Settings";
 | 
				
			||||||
import ErrorBoundary from "@components/ErrorBoundary";
 | 
					 | 
				
			||||||
import { Devs } from "@utils/constants";
 | 
					import { Devs } from "@utils/constants";
 | 
				
			||||||
import definePlugin, { OptionType } from "@utils/types";
 | 
					import definePlugin, { OptionType } from "@utils/types";
 | 
				
			||||||
import { Button, ButtonLooks, ButtonWrapperClasses, React, Tooltip } from "@webpack/common";
 | 
					import { React, useEffect, useState } from "@webpack/common";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let lastState = false;
 | 
					let lastState = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,19 +41,15 @@ const settings = definePluginSettings({
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function SilentMessageToggle(chatBoxProps: {
 | 
					const SilentMessageToggle: ChatBarButton = (_, isMainChat) => {
 | 
				
			||||||
    type: {
 | 
					    const [enabled, setEnabled] = useState(lastState);
 | 
				
			||||||
        analyticsName: string;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}) {
 | 
					 | 
				
			||||||
    const [enabled, setEnabled] = React.useState(lastState);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function setEnabledValue(value: boolean) {
 | 
					    function setEnabledValue(value: boolean) {
 | 
				
			||||||
        if (settings.store.persistState) lastState = value;
 | 
					        if (settings.store.persistState) lastState = value;
 | 
				
			||||||
        setEnabled(value);
 | 
					        setEnabled(value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    React.useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
        const listener: SendListener = (_, message) => {
 | 
					        const listener: SendListener = (_, message) => {
 | 
				
			||||||
            if (enabled) {
 | 
					            if (enabled) {
 | 
				
			||||||
                if (settings.store.autoDisable) setEnabledValue(false);
 | 
					                if (settings.store.autoDisable) setEnabledValue(false);
 | 
				
			||||||
| 
						 | 
					@ -65,55 +61,37 @@ function SilentMessageToggle(chatBoxProps: {
 | 
				
			||||||
        return () => void removePreSendListener(listener);
 | 
					        return () => void removePreSendListener(listener);
 | 
				
			||||||
    }, [enabled]);
 | 
					    }, [enabled]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (chatBoxProps.type.analyticsName !== "normal") return null;
 | 
					    if (!isMainChat) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <Tooltip text={enabled ? "Disable Silent Message" : "Enable Silent Message"}>
 | 
					        <ChatBarButton
 | 
				
			||||||
            {tooltipProps => (
 | 
					            tooltip={enabled ? "Disable Silent Message" : "Enable Silent Message"}
 | 
				
			||||||
                <div style={{ display: "flex" }}>
 | 
					            onClick={() => setEnabledValue(!enabled)}
 | 
				
			||||||
                    <Button
 | 
					            buttonProps={{
 | 
				
			||||||
                        {...tooltipProps}
 | 
					                style: { padding: "0 6px" }
 | 
				
			||||||
                        onClick={() => setEnabledValue(!enabled)}
 | 
					            }}
 | 
				
			||||||
                        size=""
 | 
					        >
 | 
				
			||||||
                        look={ButtonLooks.BLANK}
 | 
					            <svg width="24" height="24" viewBox="0 0 24 24">
 | 
				
			||||||
                        innerClassName={ButtonWrapperClasses.button}
 | 
					                <path fill="currentColor" mask="url(#_)" d="M18 10.7101C15.1085 9.84957 13 7.17102 13 4c0-.30736.0198-.6101.0582-.907C12.7147 3.03189 12.3611 3 12 3 8.686 3 6 5.686 6 9v5c0 1.657-1.344 3-3 3v1h18v-1c-1.656 0-3-1.343-3-3v-3.2899ZM8.55493 19c.693 1.19 1.96897 2 3.44497 2s2.752-.81 3.445-2H8.55493ZM18.2624 5.50209 21 2.5V1h-4.9651v1.49791h2.4411L16 5.61088V7h5V5.50209h-2.7376Z" />
 | 
				
			||||||
                        style={{ padding: "0 6px" }}
 | 
					                {!enabled && <>
 | 
				
			||||||
                    >
 | 
					                    <mask id="_">
 | 
				
			||||||
                        <div className={ButtonWrapperClasses.buttonWrapper}>
 | 
					                        <path fill="#fff" d="M0 0h24v24H0Z" />
 | 
				
			||||||
                            <svg width="24" height="24" viewBox="0 0 24 24">
 | 
					                        <path stroke="#000" stroke-width="5.99068" d="M0 24 24 0" />
 | 
				
			||||||
                                <path fill="currentColor" mask="url(#_)" d="M18 10.7101C15.1085 9.84957 13 7.17102 13 4c0-.30736.0198-.6101.0582-.907C12.7147 3.03189 12.3611 3 12 3 8.686 3 6 5.686 6 9v5c0 1.657-1.344 3-3 3v1h18v-1c-1.656 0-3-1.343-3-3v-3.2899ZM8.55493 19c.693 1.19 1.96897 2 3.44497 2s2.752-.81 3.445-2H8.55493ZM18.2624 5.50209 21 2.5V1h-4.9651v1.49791h2.4411L16 5.61088V7h5V5.50209h-2.7376Z" />
 | 
					                    </mask>
 | 
				
			||||||
                                {!enabled && <>
 | 
					                    <path fill="var(--status-danger)" d="m21.178 1.70703 1.414 1.414L4.12103 21.593l-1.414-1.415L21.178 1.70703Z" />
 | 
				
			||||||
                                    <mask id="_">
 | 
					                </>}
 | 
				
			||||||
                                        <path fill="#fff" d="M0 0h24v24H0Z" />
 | 
					            </svg>
 | 
				
			||||||
                                        <path stroke="#000" stroke-width="5.99068" d="M0 24 24 0" />
 | 
					        </ChatBarButton>
 | 
				
			||||||
                                    </mask>
 | 
					 | 
				
			||||||
                                    <path fill="var(--status-danger)" d="m21.178 1.70703 1.414 1.414L4.12103 21.593l-1.414-1.415L21.178 1.70703Z" />
 | 
					 | 
				
			||||||
                                </>}
 | 
					 | 
				
			||||||
                            </svg>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                    </Button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
        </Tooltip>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default definePlugin({
 | 
					export default definePlugin({
 | 
				
			||||||
    name: "SilentMessageToggle",
 | 
					    name: "SilentMessageToggle",
 | 
				
			||||||
    authors: [Devs.Nuckyz, Devs.CatNoir],
 | 
					    authors: [Devs.Nuckyz, Devs.CatNoir],
 | 
				
			||||||
    description: "Adds a button to the chat bar to toggle sending a silent message.",
 | 
					    description: "Adds a button to the chat bar to toggle sending a silent message.",
 | 
				
			||||||
    dependencies: ["MessageEventsAPI"],
 | 
					    dependencies: ["MessageEventsAPI", "ChatInputButtonAPI"],
 | 
				
			||||||
 | 
					 | 
				
			||||||
    settings,
 | 
					    settings,
 | 
				
			||||||
    patches: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            find: "ChannelTextAreaButtons",
 | 
					 | 
				
			||||||
            replacement: {
 | 
					 | 
				
			||||||
                match: /(\i)\.push.{1,30}disabled:(\i),.{1,20}\},"gift"\)\)/,
 | 
					 | 
				
			||||||
                replace: "$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    chatBarIcon: ErrorBoundary.wrap(SilentMessageToggle, { noop: true }),
 | 
					    start: () => addChatBarButton("SilentMessageToggle", SilentMessageToggle),
 | 
				
			||||||
 | 
					    stop: () => removeChatBarButton("SilentMessageToggle")
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,12 +16,12 @@
 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { addChatBarButton, ChatBarButton, removeChatBarButton } from "@api/ChatButtons";
 | 
				
			||||||
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
 | 
					import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
 | 
				
			||||||
import { definePluginSettings } from "@api/Settings";
 | 
					import { definePluginSettings } from "@api/Settings";
 | 
				
			||||||
import ErrorBoundary from "@components/ErrorBoundary";
 | 
					 | 
				
			||||||
import { Devs } from "@utils/constants";
 | 
					import { Devs } from "@utils/constants";
 | 
				
			||||||
import definePlugin, { OptionType } from "@utils/types";
 | 
					import definePlugin, { OptionType } from "@utils/types";
 | 
				
			||||||
import { Button, ButtonLooks, ButtonWrapperClasses, FluxDispatcher, React, Tooltip } from "@webpack/common";
 | 
					import { FluxDispatcher, React } from "@webpack/common";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const settings = definePluginSettings({
 | 
					const settings = definePluginSettings({
 | 
				
			||||||
    showIcon: {
 | 
					    showIcon: {
 | 
				
			||||||
| 
						 | 
					@ -37,45 +37,35 @@ const settings = definePluginSettings({
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function SilentTypingToggle(chatBoxProps: {
 | 
					const SilentTypingToggle: ChatBarButton = (_, isMainChat) => {
 | 
				
			||||||
    type: {
 | 
					    const { isEnabled, showIcon } = settings.use(["isEnabled", "showIcon"]);
 | 
				
			||||||
        analyticsName: string;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}) {
 | 
					 | 
				
			||||||
    const { isEnabled } = settings.use(["isEnabled"]);
 | 
					 | 
				
			||||||
    const toggle = () => settings.store.isEnabled = !settings.store.isEnabled;
 | 
					    const toggle = () => settings.store.isEnabled = !settings.store.isEnabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (chatBoxProps.type.analyticsName !== "normal") return null;
 | 
					    if (!isMainChat || !showIcon) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <Tooltip text={isEnabled ? "Disable Silent Typing" : "Enable Silent Typing"}>
 | 
					        <ChatBarButton
 | 
				
			||||||
            {(tooltipProps: any) => (
 | 
					            tooltip={isEnabled ? "Disable Silent Typing" : "Enable Silent Typing"}
 | 
				
			||||||
                <div style={{ display: "flex" }}>
 | 
					            onClick={toggle}
 | 
				
			||||||
                    <Button
 | 
					            buttonProps={{
 | 
				
			||||||
                        {...tooltipProps}
 | 
					                style: { padding: "0 6px" }
 | 
				
			||||||
                        onClick={toggle}
 | 
					            }}
 | 
				
			||||||
                        size=""
 | 
					        >
 | 
				
			||||||
                        look={ButtonLooks.BLANK}
 | 
					            <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
 | 
				
			||||||
                        innerClassName={ButtonWrapperClasses.button}
 | 
					                <path fill="currentColor" d="M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z" />
 | 
				
			||||||
                        style={{ padding: "0 6px" }}
 | 
					                {isEnabled && <path d="M13 432L590 48" stroke="var(--red-500)" stroke-width="72" stroke-linecap="round" />}
 | 
				
			||||||
                    >
 | 
					            </svg>
 | 
				
			||||||
                        <div className={ButtonWrapperClasses.buttonWrapper}>
 | 
					        </ChatBarButton>
 | 
				
			||||||
                            <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
 | 
					 | 
				
			||||||
                                <path fill="currentColor" d="M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z" />
 | 
					 | 
				
			||||||
                                {isEnabled && <path d="M13 432L590 48" stroke="var(--red-500)" stroke-width="72" stroke-linecap="round" />}
 | 
					 | 
				
			||||||
                            </svg>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                    </Button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
        </Tooltip>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default definePlugin({
 | 
					export default definePlugin({
 | 
				
			||||||
    name: "SilentTyping",
 | 
					    name: "SilentTyping",
 | 
				
			||||||
    authors: [Devs.Ven, Devs.Rini],
 | 
					    authors: [Devs.Ven, Devs.Rini],
 | 
				
			||||||
    description: "Hide that you are typing",
 | 
					    description: "Hide that you are typing",
 | 
				
			||||||
 | 
					    dependencies: ["CommandsAPI", "ChatInputButtonAPI"],
 | 
				
			||||||
 | 
					    settings,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    patches: [
 | 
					    patches: [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            find: '.dispatch({type:"TYPING_START_LOCAL"',
 | 
					            find: '.dispatch({type:"TYPING_START_LOCAL"',
 | 
				
			||||||
| 
						 | 
					@ -84,17 +74,8 @@ export default definePlugin({
 | 
				
			||||||
                replace: "startTyping:$self.startTyping,stop"
 | 
					                replace: "startTyping:$self.startTyping,stop"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            find: "ChannelTextAreaButtons",
 | 
					 | 
				
			||||||
            predicate: () => settings.store.showIcon,
 | 
					 | 
				
			||||||
            replacement: {
 | 
					 | 
				
			||||||
                match: /(\i)\.push.{1,30}disabled:(\i),.{1,20}\},"gift"\)\)/,
 | 
					 | 
				
			||||||
                replace: "$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    dependencies: ["CommandsAPI"],
 | 
					
 | 
				
			||||||
    settings,
 | 
					 | 
				
			||||||
    commands: [{
 | 
					    commands: [{
 | 
				
			||||||
        name: "silenttype",
 | 
					        name: "silenttype",
 | 
				
			||||||
        description: "Toggle whether you're hiding that you're typing or not.",
 | 
					        description: "Toggle whether you're hiding that you're typing or not.",
 | 
				
			||||||
| 
						 | 
					@ -120,5 +101,6 @@ export default definePlugin({
 | 
				
			||||||
        FluxDispatcher.dispatch({ type: "TYPING_START_LOCAL", channelId });
 | 
					        FluxDispatcher.dispatch({ type: "TYPING_START_LOCAL", channelId });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    chatBarIcon: ErrorBoundary.wrap(SilentTypingToggle, { noop: true }),
 | 
					    start: () => addChatBarButton("SilentTyping", SilentTypingToggle),
 | 
				
			||||||
 | 
					    stop: () => removeChatBarButton("SilentTyping"),
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,9 +16,9 @@
 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { ChatBarButton } from "@api/ChatButtons";
 | 
				
			||||||
import { classes } from "@utils/misc";
 | 
					import { classes } from "@utils/misc";
 | 
				
			||||||
import { openModal } from "@utils/modal";
 | 
					import { openModal } from "@utils/modal";
 | 
				
			||||||
import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { settings } from "./settings";
 | 
					import { settings } from "./settings";
 | 
				
			||||||
import { TranslateModal } from "./TranslateModal";
 | 
					import { TranslateModal } from "./TranslateModal";
 | 
				
			||||||
| 
						 | 
					@ -37,42 +37,30 @@ export function TranslateIcon({ height = 24, width = 24, className }: { height?:
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function TranslateChatBarIcon({ slateProps }: { slateProps: { type: { analyticsName: string; }; }; }) {
 | 
					export const TranslateChatBarIcon: ChatBarButton = (props, isMainChat) => {
 | 
				
			||||||
    const { autoTranslate } = settings.use(["autoTranslate"]);
 | 
					    const { autoTranslate } = settings.use(["autoTranslate"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (slateProps.type.analyticsName !== "normal")
 | 
					    if (!isMainChat) return null;
 | 
				
			||||||
        return null;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const toggle = () => settings.store.autoTranslate = !autoTranslate;
 | 
					    const toggle = () => settings.store.autoTranslate = !autoTranslate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <Tooltip text="Open Translate Modal">
 | 
					        <ChatBarButton
 | 
				
			||||||
            {({ onMouseEnter, onMouseLeave }) => (
 | 
					            tooltip="Open Translate Modal"
 | 
				
			||||||
                <div style={{ display: "flex" }}>
 | 
					            onClick={e => {
 | 
				
			||||||
                    <Button
 | 
					                if (e.shiftKey) return toggle();
 | 
				
			||||||
                        aria-haspopup="dialog"
 | 
					 | 
				
			||||||
                        aria-label="Open Translate Modal"
 | 
					 | 
				
			||||||
                        size=""
 | 
					 | 
				
			||||||
                        look={ButtonLooks.BLANK}
 | 
					 | 
				
			||||||
                        onMouseEnter={onMouseEnter}
 | 
					 | 
				
			||||||
                        onMouseLeave={onMouseLeave}
 | 
					 | 
				
			||||||
                        innerClassName={ButtonWrapperClasses.button}
 | 
					 | 
				
			||||||
                        onClick={e => {
 | 
					 | 
				
			||||||
                            if (e.shiftKey) return toggle();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            openModal(props => (
 | 
					                openModal(props => (
 | 
				
			||||||
                                <TranslateModal rootProps={props} />
 | 
					                    <TranslateModal rootProps={props} />
 | 
				
			||||||
                            ));
 | 
					                ));
 | 
				
			||||||
                        }}
 | 
					            }}
 | 
				
			||||||
                        onContextMenu={() => toggle()}
 | 
					            onContextMenu={() => toggle()}
 | 
				
			||||||
                        style={{ padding: "0 4px" }}
 | 
					            buttonProps={{
 | 
				
			||||||
                    >
 | 
					                "aria-haspopup": "dialog",
 | 
				
			||||||
                        <div className={ButtonWrapperClasses.buttonWrapper}>
 | 
					                style: { padding: "0 4px" }
 | 
				
			||||||
                            <TranslateIcon className={cl({ "auto-translate": autoTranslate })} />
 | 
					            }}
 | 
				
			||||||
                        </div>
 | 
					        >
 | 
				
			||||||
                    </Button>
 | 
					            <TranslateIcon className={cl({ "auto-translate": autoTranslate })} />
 | 
				
			||||||
                </div>
 | 
					        </ChatBarButton>
 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
        </Tooltip>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,11 +18,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "./styles.css";
 | 
					import "./styles.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { addChatBarButton, removeChatBarButton } from "@api/ChatButtons";
 | 
				
			||||||
import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
 | 
					import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
 | 
				
			||||||
import { addAccessory, removeAccessory } from "@api/MessageAccessories";
 | 
					import { addAccessory, removeAccessory } from "@api/MessageAccessories";
 | 
				
			||||||
import { addPreSendListener, removePreSendListener } from "@api/MessageEvents";
 | 
					import { addPreSendListener, removePreSendListener } from "@api/MessageEvents";
 | 
				
			||||||
import { addButton, removeButton } from "@api/MessagePopover";
 | 
					import { addButton, removeButton } from "@api/MessagePopover";
 | 
				
			||||||
import ErrorBoundary from "@components/ErrorBoundary";
 | 
					 | 
				
			||||||
import { Devs } from "@utils/constants";
 | 
					import { Devs } from "@utils/constants";
 | 
				
			||||||
import definePlugin from "@utils/types";
 | 
					import definePlugin from "@utils/types";
 | 
				
			||||||
import { ChannelStore, Menu } from "@webpack/common";
 | 
					import { ChannelStore, Menu } from "@webpack/common";
 | 
				
			||||||
| 
						 | 
					@ -55,25 +55,16 @@ export default definePlugin({
 | 
				
			||||||
    name: "Translate",
 | 
					    name: "Translate",
 | 
				
			||||||
    description: "Translate messages with Google Translate",
 | 
					    description: "Translate messages with Google Translate",
 | 
				
			||||||
    authors: [Devs.Ven],
 | 
					    authors: [Devs.Ven],
 | 
				
			||||||
    dependencies: ["MessageAccessoriesAPI", "MessagePopoverAPI", "MessageEventsAPI"],
 | 
					    dependencies: ["MessageAccessoriesAPI", "MessagePopoverAPI", "MessageEventsAPI", "ChatInputButtonAPI"],
 | 
				
			||||||
    settings,
 | 
					    settings,
 | 
				
			||||||
    // not used, just here in case some other plugin wants it or w/e
 | 
					    // not used, just here in case some other plugin wants it or w/e
 | 
				
			||||||
    translate,
 | 
					    translate,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    patches: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            find: "ChannelTextAreaButtons",
 | 
					 | 
				
			||||||
            replacement: {
 | 
					 | 
				
			||||||
                match: /(\i)\.push.{1,30}disabled:(\i),.{1,20}\},"gift"\)\)/,
 | 
					 | 
				
			||||||
                replace: "$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    start() {
 | 
					    start() {
 | 
				
			||||||
        addAccessory("vc-translation", props => <TranslationAccessory message={props.message} />);
 | 
					        addAccessory("vc-translation", props => <TranslationAccessory message={props.message} />);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        addContextMenuPatch("message", messageCtxPatch);
 | 
					        addContextMenuPatch("message", messageCtxPatch);
 | 
				
			||||||
 | 
					        addChatBarButton("vc-translate", TranslateChatBarIcon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        addButton("vc-translate", message => {
 | 
					        addButton("vc-translate", message => {
 | 
				
			||||||
            if (!message.content) return null;
 | 
					            if (!message.content) return null;
 | 
				
			||||||
| 
						 | 
					@ -101,13 +92,8 @@ export default definePlugin({
 | 
				
			||||||
    stop() {
 | 
					    stop() {
 | 
				
			||||||
        removePreSendListener(this.preSend);
 | 
					        removePreSendListener(this.preSend);
 | 
				
			||||||
        removeContextMenuPatch("message", messageCtxPatch);
 | 
					        removeContextMenuPatch("message", messageCtxPatch);
 | 
				
			||||||
 | 
					        removeChatBarButton("vc-translate");
 | 
				
			||||||
        removeButton("vc-translate");
 | 
					        removeButton("vc-translate");
 | 
				
			||||||
        removeAccessory("vc-translation");
 | 
					        removeAccessory("vc-translation");
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					 | 
				
			||||||
    chatBarIcon: (slateProps: any) => (
 | 
					 | 
				
			||||||
        <ErrorBoundary noop>
 | 
					 | 
				
			||||||
            <TranslateChatBarIcon slateProps={slateProps} />
 | 
					 | 
				
			||||||
        </ErrorBoundary>
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue