blob: da10cfbcbc2c72acabbe5fccf8540eef18a8259b [file] [log] [blame]
pineafan73a7c4a2022-07-24 10:38:04 +01001import Discord, { CommandInteraction, MessageActionRow, Message, MessageButton, TextInputComponent } from "discord.js";
2import { modalInteractionCollector } from "./dualCollector.js";
pineafan4edb7762022-06-26 19:21:04 +01003import EmojiEmbed from "./generateEmojiEmbed.js"
pineafan8b4b17f2022-02-27 20:42:52 +00004import getEmojiByName from "./getEmojiByName.js";
pineafan4f164f32022-02-26 22:07:12 +00005
6class confirmationMessage {
7 interaction: CommandInteraction;
pineafan73a7c4a2022-07-24 10:38:04 +01008 title: string = "";
9 emoji: string = "";
10 description: string = "";
11 color: string = "";
12 customCallback: () => any = () => {};
pineafan377794f2022-04-18 19:01:01 +010013 customButtonTitle: string;
14 customButtonDisabled: boolean;
15 customCallbackString: string = "";
16 customCallbackClicked: boolean = false;
17 customCallbackResponse: any = null;
pineafan73a7c4a2022-07-24 10:38:04 +010018 customBoolean: () => any = () => {}; // allow multiple booleans
pineafan6fb3e072022-05-20 19:27:23 +010019 customBooleanClicked: boolean = null;
pineafan73a7c4a2022-07-24 10:38:04 +010020 inverted: boolean = false;
21 reason: string | null = null;
pineafan4f164f32022-02-26 22:07:12 +000022
23 constructor(interaction: CommandInteraction) {
24 this.interaction = interaction;
pineafan4f164f32022-02-26 22:07:12 +000025 }
26
27 setTitle(title: string) { this.title = title; return this }
28 setEmoji(emoji: string) { this.emoji = emoji; return this }
29 setDescription(description: string) { this.description = description; return this }
30 setColor(color: string) { this.color = color; return this }
pineafan167bde32022-05-19 19:33:46 +010031 setInverted(inverted: boolean) { this.inverted = inverted; return this }
pineafan377794f2022-04-18 19:01:01 +010032 addCustomCallback(title: string, disabled: boolean, callback: () => any, callbackClicked: string) {
pineafan6fb3e072022-05-20 19:27:23 +010033 if (this.customButtonTitle) return this
pineafan377794f2022-04-18 19:01:01 +010034 this.customButtonTitle = title;
35 this.customButtonDisabled = disabled;
36 this.customCallback = callback;
37 this.customCallbackString = callbackClicked;
38 return this;
39 }
pineafan6fb3e072022-05-20 19:27:23 +010040 addCustomBoolean(title: string, disabled: boolean, callback: () => any, callbackClicked: string) {
41 if (this.customButtonTitle) return this
42 this.customButtonTitle = title;
43 this.customButtonDisabled = disabled;
44 this.customBoolean = callback;
45 this.customCallbackString = callbackClicked;
46 this.customBooleanClicked = false;
47 return this;
48 }
pineafan73a7c4a2022-07-24 10:38:04 +010049 addReasonButton(reason: string) {
50 this.reason = reason;
51 return this;
52 }
pineafan8b4b17f2022-02-27 20:42:52 +000053 async send(editOnly?: boolean) {
pineafan377794f2022-04-18 19:01:01 +010054 while (true) {
55 let object = {
56 embeds: [
pineafan4edb7762022-06-26 19:21:04 +010057 new EmojiEmbed()
pineafan377794f2022-04-18 19:01:01 +010058 .setEmoji(this.emoji)
59 .setTitle(this.title)
60 .setDescription(this.description)
61 .setStatus(this.color)
pineafan6fb3e072022-05-20 19:27:23 +010062 .setFooter({text: (this.customBooleanClicked ?? this.customCallbackClicked) ? this.customCallbackString : ""})
pineafan377794f2022-04-18 19:01:01 +010063 ],
64 components: [
65 new MessageActionRow().addComponents([
66 new Discord.MessageButton()
67 .setCustomId("yes")
PineappleFan19b002b2022-05-19 11:54:01 +010068 .setLabel("Confirm")
69 .setStyle(this.inverted ? "SUCCESS" : "DANGER")
pineafan377794f2022-04-18 19:01:01 +010070 .setEmoji(getEmojiByName("CONTROL.TICK", "id")),
71 new Discord.MessageButton()
72 .setCustomId("no")
73 .setLabel("Cancel")
pineafan17aba6d2022-05-19 20:27:22 +010074 .setStyle("SECONDARY")
pineafan377794f2022-04-18 19:01:01 +010075 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
76 ].concat(this.customButtonTitle ? [new Discord.MessageButton()
77 .setCustomId("custom")
78 .setLabel(this.customButtonTitle)
pineafan6fb3e072022-05-20 19:27:23 +010079 .setStyle(this.customBooleanClicked !== null ?
80 ( this.customBooleanClicked ? "SUCCESS" : "PRIMARY" ) :
81 "PRIMARY"
82 )
pineafan377794f2022-04-18 19:01:01 +010083 .setDisabled(this.customButtonDisabled)
pineafane625d782022-05-09 18:04:32 +010084 .setEmoji(getEmojiByName("CONTROL.TICKET", "id"))
pineafan73a7c4a2022-07-24 10:38:04 +010085 ] : [])
86 .concat(this.reason !== null ? [new Discord.MessageButton()
87 .setCustomId("reason")
88 .setLabel(`Edit Reason`)
89 .setStyle("PRIMARY")
90 .setEmoji(getEmojiByName("ICONS.EDIT", "id"))
pineafan377794f2022-04-18 19:01:01 +010091 ] : []))
92 ],
93 ephemeral: true,
94 fetchReply: true
95 }
96 let m;
97 if ( editOnly ) {
98 m = await this.interaction.editReply(object);
99 } else {
100 m = await this.interaction.reply(object)
101 }
102 let component;
103 try {
pineafanc6158ab2022-06-17 16:34:07 +0100104 component = await (m as Message).awaitMessageComponent({filter: (m) => m.user.id === this.interaction.user.id, time: 300000});
pineafan377794f2022-04-18 19:01:01 +0100105 } catch (e) {
pineafan6fb3e072022-05-20 19:27:23 +0100106 return {
107 success: false,
108 buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
109 response: this.customCallbackResponse
110 };
pineafan377794f2022-04-18 19:01:01 +0100111 }
112 if (component.customId === "yes") {
113 component.deferUpdate();
pineafan6fb3e072022-05-20 19:27:23 +0100114 if (this.customBooleanClicked === true) this.customCallbackResponse = await this.customBoolean();
115 return {
116 success: true,
117 buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
118 response: this.customCallbackResponse
119 };
pineafan377794f2022-04-18 19:01:01 +0100120 } else if (component.customId === "no") {
121 component.deferUpdate();
pineafan6fb3e072022-05-20 19:27:23 +0100122 return {
123 success: false,
124 buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
125 response: this.customCallbackResponse
126 };
pineafan377794f2022-04-18 19:01:01 +0100127 } else if (component.customId === "custom") {
128 component.deferUpdate();
pineafan6fb3e072022-05-20 19:27:23 +0100129 if (this.customBooleanClicked !== null) {
130 this.customBooleanClicked = !this.customBooleanClicked;
131 } else {
132 this.customCallbackResponse = await this.customCallback();
133 this.customCallbackClicked = true;
134 this.customButtonDisabled = true;
135 }
pineafan377794f2022-04-18 19:01:01 +0100136 editOnly = true;
pineafan73a7c4a2022-07-24 10:38:04 +0100137 } else if (component.customId === "reason") {
138 await component.showModal(new Discord.Modal().setCustomId("modal").setTitle(`Editing reason`).addComponents(
139 // @ts-ignore
140 new MessageActionRow().addComponents(new TextInputComponent()
141 .setCustomId("reason")
142 .setLabel("Reason")
143 .setMaxLength(2000)
144 .setRequired(false)
145 .setStyle("PARAGRAPH")
146 .setPlaceholder("Spammed in #general")
147 .setValue(this.reason ? this.reason : "")
148 )
149 ))
150 await this.interaction.editReply({
151 embeds: [new EmojiEmbed()
152 .setTitle(this.title)
153 .setDescription("Modal opened. If you can't see it, click back and try again.")
154 .setStatus(this.color)
155 .setEmoji(this.emoji)
156 ], components: [new MessageActionRow().addComponents([new MessageButton()
157 .setLabel("Back")
158 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
159 .setStyle("PRIMARY")
160 .setCustomId("back")
161 ])]
162 });
163 let out;
164 try {
165 out = await modalInteractionCollector(m, (m) => m.channel.id == this.interaction.channel.id, (m) => m.customId == "reason")
166 } catch (e) { continue }
167 if (out.fields) {
168 return {newReason: out.fields.getTextInputValue("reason") ?? ""};
169 } else { return { newReason: this.reason } }
pineafan377794f2022-04-18 19:01:01 +0100170 }
pineafan8b4b17f2022-02-27 20:42:52 +0000171 }
pineafan4f164f32022-02-26 22:07:12 +0000172 }
173}
174
pineafan73a7c4a2022-07-24 10:38:04 +0100175export default confirmationMessage;