From 4d836524c133c9e6a8c8e896dd943df3a39701fe Mon Sep 17 00:00:00 2001
From: V <vendicated@riseup.net>
Date: Wed, 12 Apr 2023 02:33:51 +0200
Subject: GreetStickerPicker: greet with stickers of your choice (#866)

Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com>
---
 src/plugins/welcomeStickerPicker.tsx | 185 +++++++++++++++++++++++++++++++++++
 1 file changed, 185 insertions(+)
 create mode 100644 src/plugins/welcomeStickerPicker.tsx

(limited to 'src/plugins/welcomeStickerPicker.tsx')

diff --git a/src/plugins/welcomeStickerPicker.tsx b/src/plugins/welcomeStickerPicker.tsx
new file mode 100644
index 0000000..40af7e2
--- /dev/null
+++ b/src/plugins/welcomeStickerPicker.tsx
@@ -0,0 +1,185 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2023 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import { definePluginSettings } from "@api/settings";
+import { Devs } from "@utils/constants";
+import definePlugin, { OptionType } from "@utils/types";
+import { findByPropsLazy } from "@webpack";
+import { ContextMenu, FluxDispatcher, Menu } from "@webpack/common";
+import { Channel, Message } from "discord-types/general";
+
+interface Sticker {
+    id: string;
+    format_type: number;
+    description: string;
+    name: string;
+}
+
+enum GreetMode {
+    Greet = "Greet",
+    NormalMessage = "Message"
+}
+
+const settings = definePluginSettings({
+    greetMode: {
+        type: OptionType.SELECT,
+        options: [
+            { label: "Greet (you can only greet 3 times)", value: GreetMode.Greet, default: true },
+            { label: "Normal Message (you can greet spam)", value: GreetMode.NormalMessage }
+        ],
+        description: "Choose the greet mode"
+    }
+});
+
+const MessageActions = findByPropsLazy("sendGreetMessage");
+
+function greet(channel: Channel, message: Message, stickers: string[]) {
+    const options = MessageActions.getSendMessageOptionsForReply({
+        channel,
+        message,
+        shouldMention: true,
+        showMentionToggle: true
+    });
+
+    if (settings.store.greetMode === GreetMode.NormalMessage || stickers.length > 1) {
+        options.stickerIds = stickers;
+        const msg = {
+            content: "",
+            tts: false,
+            invalidEmojis: [],
+            validNonShortcutEmojis: []
+        };
+
+        MessageActions._sendMessage(channel.id, msg, options);
+    } else {
+        MessageActions.sendGreetMessage(channel.id, stickers[0], options);
+    }
+}
+
+
+function GreetMenu({ stickers, channel, message }: { stickers: Sticker[], message: Message, channel: Channel; }) {
+    const s = settings.use(["greetMode", "multiGreetChoices"] as any) as { greetMode: GreetMode, multiGreetChoices: string[]; };
+    const { greetMode, multiGreetChoices = [] } = s;
+
+    return (
+        <Menu.Menu
+            navId="greet-sticker-picker"
+            onClose={() => FluxDispatcher.dispatch({ type: "CONTEXT_MENU_CLOSE" })}
+            aria-label="Greet Sticker Picker"
+        >
+            <Menu.MenuGroup
+                label="Greet Mode"
+            >
+                {Object.values(GreetMode).map(mode => (
+                    <Menu.MenuRadioItem
+                        key={mode}
+                        group="greet-mode"
+                        id={"greet-mode-" + mode}
+                        label={mode}
+                        checked={mode === greetMode}
+                        action={() => s.greetMode = mode}
+                    />
+                ))}
+            </Menu.MenuGroup>
+
+            <Menu.MenuSeparator />
+
+            <Menu.MenuGroup
+                label="Greet Stickers"
+            >
+                {stickers.map(sticker => (
+                    <Menu.MenuItem
+                        key={sticker.id}
+                        id={"greet-" + sticker.id}
+                        label={sticker.description.split(" ")[0]}
+                        action={() => greet(channel, message, [sticker.id])}
+                    />
+                ))}
+            </Menu.MenuGroup>
+
+            {!(settings.store as any).unholyMultiGreetEnabled ? null : (
+                <>
+                    <Menu.MenuSeparator />
+
+                    <Menu.MenuItem
+                        label="Unholy Multi-Greet"
+                        id="unholy-multi-greet"
+                    >
+                        {stickers.map(sticker => {
+                            const checked = multiGreetChoices.some(s => s === sticker.id);
+
+                            return (
+                                <Menu.MenuCheckboxItem
+                                    key={sticker.id}
+                                    id={"multi-greet-" + sticker.id}
+                                    label={sticker.description.split(" ")[0]}
+                                    checked={checked}
+                                    disabled={!checked && multiGreetChoices.length >= 3}
+                                    action={() => {
+                                        s.multiGreetChoices = checked
+                                            ? multiGreetChoices.filter(s => s !== sticker.id)
+                                            : [...multiGreetChoices, sticker.id];
+                                    }}
+                                />
+                            );
+                        })}
+
+                        <Menu.MenuSeparator />
+                        <Menu.MenuItem
+                            id="multi-greet-submit"
+                            label="Send Greets"
+                            action={() => greet(channel, message, multiGreetChoices!)}
+                            disabled={multiGreetChoices.length === 0}
+                        />
+
+                    </Menu.MenuItem>
+                </>
+            )}
+        </Menu.Menu>
+    );
+}
+
+export default definePlugin({
+    name: "GreetStickerPicker",
+    description: "Allows you to use any greet sticker instead of only the random one by right-clicking the 'Wave to say hi!' button",
+    authors: [Devs.Ven],
+
+    settings,
+
+    patches: [
+        {
+            find: "Messages.WELCOME_CTA_LABEL",
+            replacement: {
+                match: /innerClassName:\i\(\).welcomeCTAButton,(?<=%\i\.length;return (\i)\[\i\].+?)/,
+                replace: "$&onContextMenu:(e)=>$self.pickSticker(e,$1,arguments[0]),"
+            }
+        }
+    ],
+
+    pickSticker(
+        event: React.UIEvent,
+        stickers: Sticker[],
+        props: {
+            channel: Channel,
+            message: Message;
+        }
+    ) {
+        if (!(props.message as any).deleted)
+            ContextMenu.open(event, () => <GreetMenu stickers={stickers} {...props} />);
+    }
+});
-- 
cgit 

