Plugin
GreetStickerPicker
Allows you to use any greet sticker instead of only the random one by right-clicking the 'Wave to say hi!' button
1
/*2
* FiveCord — a Discord client mod3
* Copyright (c) 2025 FiveCord4
* SPDX-License-Identifier: GPL-3.0-or-later5
*/6
7
import { definePluginSettings } from "@api/Settings";8
import { Devs } from "@utils/constants";9
import definePlugin, { OptionType } from "@utils/types";10
import { Channel, Message } from "@vencord/discord-types";11
import { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from "@webpack/common";12
13
enum GreetMode {14
Greet = "Greet",15
NormalMessage = "Message"16
}17
18
const settings = definePluginSettings({19
greetMode: {20
type: OptionType.SELECT,21
options: [22
{ label: "Greet (you can only greet 3 times)", value: GreetMode.Greet, default: true },23
{ label: "Normal Message (you can greet spam)", value: GreetMode.NormalMessage }24
],25
description: "Choose the greet mode"26
}27
}).withPrivateSettings<{28
multiGreetChoices?: string[];29
unholyMultiGreetEnabled?: boolean;30
}>();31
32
let WELCOME_STICKERS: any;33
34
function greet(channel: Channel, message: Message, stickers: string[]) {35
const options = MessageActions.getSendMessageOptionsForReply({36
channel,37
message,38
shouldMention: true,39
showMentionToggle: true40
});41
42
if (settings.store.greetMode === GreetMode.NormalMessage || stickers.length > 1) {43
options.stickerIds = stickers;44
const msg = {45
content: "",46
tts: false,47
invalidEmojis: [],48
validNonShortcutEmojis: []49
};50
51
MessageActions._sendMessage(channel.id, msg, options);52
} else {53
MessageActions.sendGreetMessage(channel.id, stickers[0], options);54
}55
}56
57
58
function GreetMenu({ channel, message }: { message: Message, channel: Channel; }) {59
const s = settings.use(["greetMode", "multiGreetChoices"]);60
const { greetMode, multiGreetChoices = [] } = s;61
62
return (63
<Menu.Menu64
navId="greet-sticker-picker"65
onClose={() => FluxDispatcher.dispatch({ type: "CONTEXT_MENU_CLOSE" })}66
aria-label="Greet Sticker Picker"67
>68
<Menu.MenuGroup69
label="Greet Mode"70
>71
{Object.values(GreetMode).map(mode => (72
<Menu.MenuRadioItem73
key={mode}74
group="greet-mode"75
id={"greet-mode-" + mode}76
label={mode}77
checked={mode === greetMode}78
action={() => s.greetMode = mode}79
/>80
))}81
</Menu.MenuGroup>82
83
<Menu.MenuSeparator />84
85
<Menu.MenuGroup86
label="Greet Stickers"87
>88
{WELCOME_STICKERS.map(sticker => (89
<Menu.MenuItem90
key={sticker.id}91
id={"greet-" + sticker.id}92
label={sticker.description.split(" ")[0]}93
action={() => greet(channel, message, [sticker.id])}94
/>95
))}96
</Menu.MenuGroup>97
98
{!settings.store.unholyMultiGreetEnabled ? null : (99
<>100
<Menu.MenuSeparator />101
102
<Menu.MenuItem103
label="Unholy Multi-Greet"104
id="unholy-multi-greet"105
>106
{WELCOME_STICKERS.map(sticker => {107
const checked = multiGreetChoices.some(s => s === sticker.id);108
109
return (110
<Menu.MenuCheckboxItem111
key={sticker.id}112
id={"multi-greet-" + sticker.id}113
label={sticker.description.split(" ")[0]}114
checked={checked}115
disabled={!checked && multiGreetChoices.length >= 3}116
action={() => {117
s.multiGreetChoices = checked118
? multiGreetChoices.filter(s => s !== sticker.id)119
: [...multiGreetChoices, sticker.id];120
}}121
/>122
);123
})}124
125
<Menu.MenuSeparator />126
<Menu.MenuItem127
id="multi-greet-submit"128
label="Send Greets"129
action={() => greet(channel, message, multiGreetChoices!)}130
disabled={multiGreetChoices.length === 0}131
/>132
133
</Menu.MenuItem>134
</>135
)}136
</Menu.Menu>137
);138
}139
140
export default definePlugin({141
name: "GreetStickerPicker",142
description: "Allows you to use any greet sticker instead of only the random one by right-clicking the 039;Wave to say hi!039; button",143
tags: ["Emotes", "Customisation"],144
authors: [Devs.Ven],145
146
settings,147
148
patches: [149
{150
find: "#{intl::WELCOME_CTA_LABEL}",151
replacement: {152
match: /className:\i\.\i,(?=.{0,40}?"sticker")(?<={channel:\i,message:\i}=(\i).+?)/,153
replace: "$&onContextMenu:(vcEvent)=>$self.pickSticker(vcEvent, $1),"154
}155
},156
{157
find: 039;"Wumpus waves hello"039;,158
replacement: {159
match: /(?<==)(?=\[{id:"749054660769218631",format_type:\d,description:"Wumpus waves hello")/,160
replace: "$self.WELCOME_STICKERS="161
}162
}163
],164
165
set WELCOME_STICKERS(value: any) {166
WELCOME_STICKERS = value;167
},168
169
pickSticker(170
event: React.UIEvent,171
props: {172
channel: Channel,173
message: Message;174
}175
) {176
if (!(props.message as any).deleted)177
ContextMenuApi.openContextMenu(event, () => <GreetMenu {...props} />);178
}179
});180