Skip to content

Commit 17fe73f

Browse files
authored
Merge pull request #411 from danthe1st/improve-mod-buttons
Improve mod report menu
2 parents 8e2a3f9 + e0bd2bd commit 17fe73f

File tree

2 files changed

+118
-21
lines changed

2 files changed

+118
-21
lines changed

src/main/java/net/javadiscord/javabot/systems/moderation/report/ReportManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ private ActionRow setComponents(long targetId, long threadId) {
175175
return ActionRow.of(
176176
Button.secondary(ComponentIdBuilder.build("resolve-report", threadId), "Mark as resolved"),
177177
Button.danger(String.format(InteractionUtils.BAN_TEMPLATE, targetId), "Ban"),
178-
Button.danger(String.format(InteractionUtils.KICK_TEMPLATE, targetId), "Kick")
178+
Button.danger(String.format(InteractionUtils.KICK_TEMPLATE, targetId), "Kick"),
179+
Button.primary(String.format(InteractionUtils.WARN_TEMPLATE, targetId), "Warn")
179180
);
180181
}
181182

src/main/java/net/javadiscord/javabot/util/InteractionUtils.java

Lines changed: 116 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,52 @@
22

33
import xyz.dynxsty.dih4jda.util.ComponentIdBuilder;
44
import xyz.dynxsty.dih4jda.interactions.components.ButtonHandler;
5-
5+
import xyz.dynxsty.dih4jda.interactions.components.ModalHandler;
6+
import xyz.dynxsty.dih4jda.interactions.components.StringSelectMenuHandler;
67
import lombok.RequiredArgsConstructor;
8+
import net.dv8tion.jda.api.Permission;
79
import net.dv8tion.jda.api.entities.Guild;
810
import net.dv8tion.jda.api.entities.Member;
911
import net.dv8tion.jda.api.entities.Message;
12+
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
1013
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
14+
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
15+
import net.dv8tion.jda.api.interactions.components.ActionRow;
1116
import net.dv8tion.jda.api.interactions.components.buttons.Button;
1217
import net.dv8tion.jda.api.interactions.components.buttons.ButtonInteraction;
18+
import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
19+
import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
20+
import net.dv8tion.jda.api.interactions.components.text.TextInput;
21+
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
22+
import net.dv8tion.jda.api.interactions.modals.Modal;
23+
import net.dv8tion.jda.api.interactions.modals.ModalInteraction;
24+
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
25+
import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction;
26+
import net.dv8tion.jda.api.requests.restaction.interactions.ModalCallbackAction;
1327
import net.javadiscord.javabot.annotations.AutoDetectableComponentHandler;
1428
import net.javadiscord.javabot.data.config.BotConfig;
1529
import net.javadiscord.javabot.data.config.GuildConfig;
1630
import net.javadiscord.javabot.data.h2db.DbHelper;
1731
import net.javadiscord.javabot.systems.moderation.ModerationService;
1832
import net.javadiscord.javabot.systems.moderation.warn.dao.WarnRepository;
33+
import net.javadiscord.javabot.systems.moderation.warn.model.WarnSeverity;
1934
import net.javadiscord.javabot.systems.notification.NotificationService;
2035

36+
import java.util.Arrays;
37+
import java.util.List;
2138
import java.util.concurrent.ExecutorService;
2239

40+
import javax.annotation.CheckReturnValue;
41+
import javax.annotation.Nonnull;
42+
2343
import org.jetbrains.annotations.NotNull;
2444

2545
/**
2646
* Utility class that contains several methods for managing utility interactions, such as ban, kick, warn, etc.
2747
*/
2848
@AutoDetectableComponentHandler("utils")
2949
@RequiredArgsConstructor
30-
public class InteractionUtils implements ButtonHandler {
50+
public class InteractionUtils implements ButtonHandler, ModalHandler, StringSelectMenuHandler {
3151
/**
3252
* Template Interaction ID for deleting the original Message.
3353
*/
@@ -60,12 +80,13 @@ public class InteractionUtils implements ButtonHandler {
6080
* of the message, a staff member, or the owner.
6181
*
6282
* @param interaction The button interaction.
83+
* @return the {@link ReplyCallbackAction} for responding to the request
6384
*/
64-
private void delete(@NotNull ButtonInteraction interaction) {
85+
@CheckReturnValue
86+
private InteractionCallbackAction<?> delete(@NotNull ButtonInteraction interaction) {
6587
Member member = interaction.getMember();
6688
if (member == null) {
67-
Responses.warning(interaction.getHook(), "Could not get member.").queue();
68-
return;
89+
return Responses.warning(interaction, "Could not get member.");
6990
}
7091
GuildConfig config = botConfig.get(interaction.getGuild());
7192
Message msg = interaction.getMessage();
@@ -75,50 +96,125 @@ private void delete(@NotNull ButtonInteraction interaction) {
7596
member.isOwner()
7697
) {
7798
msg.delete().queue();
99+
return interaction.deferEdit();
78100
} else {
79-
Responses.warning(interaction.getHook(), "You don't have permission to delete this message.").queue();
101+
return Responses.warning(interaction, "You don't have permission to delete this message.");
80102
}
81103
}
82104

83-
private void kick(ButtonInteraction interaction, @NotNull Guild guild, String memberId) {
105+
private void kick(ModalInteraction interaction, @NotNull Guild guild, String memberId, String reason) {
106+
if(!interaction.getMember().hasPermission(Permission.KICK_MEMBERS)) {
107+
Responses.error(interaction.getHook(), "Missing permissions").queue();
108+
return;
109+
}
110+
ModerationService service = new ModerationService(notificationService, botConfig, interaction, warnRepository, asyncPool);
111+
guild.retrieveMemberById(memberId).queue(
112+
member -> {
113+
service.kick(member.getUser(), reason, interaction.getMember(), interaction.getMessageChannel(), false);
114+
interaction.getMessage().editMessageComponents(ActionRow.of(Button.danger(interaction.getModalId(), "Kicked by "+interaction.getUser().getAsTag()).asDisabled())).queue();
115+
}, error -> Responses.error(interaction.getHook(), "Could not find member: " + error.getMessage()).queue()
116+
);
117+
}
118+
119+
private void warn(ModalInteraction interaction, @NotNull Guild guild, String memberId, WarnSeverity severity, String reason) {
120+
if(!interaction.getMember().hasPermission(Permission.MODERATE_MEMBERS)) {
121+
Responses.error(interaction.getHook(), "Missing permissions").queue();
122+
return;
123+
}
84124
ModerationService service = new ModerationService(notificationService, botConfig, interaction, warnRepository, asyncPool);
85125
guild.retrieveMemberById(memberId).queue(
86126
member -> {
87-
service.kick(member.getUser(), "None", interaction.getMember(), interaction.getMessageChannel(), false);
88-
interaction.editButton(interaction.getButton().withLabel("Kicked by " + interaction.getUser().getAsTag()).asDisabled()).queue();
127+
service.warn(member.getUser(), severity, reason, interaction.getMember(), interaction.getMessageChannel(), false);
128+
interaction.getHook().editOriginalComponents(ActionRow.of(Button.primary(interaction.getModalId(), "Warned by "+interaction.getUser().getAsTag()).asDisabled())).queue();
89129
}, error -> Responses.error(interaction.getHook(), "Could not find member: " + error.getMessage()).queue()
90130
);
91131
}
92132

93-
private void ban(ButtonInteraction interaction, @NotNull Guild guild, String memberId) {
133+
private void ban(ModalInteraction interaction, @NotNull Guild guild, String memberId, String reason) {
134+
if(!interaction.getMember().hasPermission(Permission.BAN_MEMBERS)) {
135+
Responses.error(interaction.getHook(), "Missing permissions").queue();
136+
return;
137+
}
94138
ModerationService service = new ModerationService(notificationService, botConfig, interaction, warnRepository, asyncPool);
95139
guild.getJDA().retrieveUserById(memberId).queue(
96140
user -> {
97-
service.ban(user, "None", interaction.getMember(), interaction.getMessageChannel(), false);
98-
interaction.editButton(interaction.getButton().withLabel("Banned by " + interaction.getUser().getAsTag()).asDisabled()).queue();
141+
service.ban(user, reason, interaction.getMember(), interaction.getMessageChannel(), false);
142+
interaction.getMessage().editMessageComponents(ActionRow.of(Button.danger(interaction.getModalId(), "Banned by "+interaction.getUser().getAsTag()).asDisabled())).queue();
99143
}, error -> Responses.error(interaction.getHook(), "Could not find member: " + error.getMessage()).queue()
100144
);
101145
}
102146

103-
private void unban(ButtonInteraction interaction, long memberId) {
147+
private void unban(ModalInteraction interaction, long memberId, String reason) {
148+
if(!interaction.getMember().hasPermission(Permission.BAN_MEMBERS)) {
149+
Responses.error(interaction.getHook(), "Missing permissions").queue();
150+
return;
151+
}
104152
ModerationService service = new ModerationService(notificationService, botConfig, interaction, warnRepository, asyncPool);
105-
service.unban(memberId, "None", interaction.getMember(), interaction.getMessageChannel(), false);
106-
interaction.editButton(interaction.getButton().withLabel("Unbanned by " + interaction.getUser().getAsTag()).asDisabled()).queue();
153+
service.unban(memberId, reason, interaction.getMember(), interaction.getMessageChannel(), false);
154+
interaction.getMessage().editMessageComponents(ActionRow.of(Button.secondary(interaction.getModalId(), "Unbanned by "+interaction.getUser().getAsTag()).asDisabled())).queue();
107155
}
108156

109157
@Override
110158
public void handleButton(@NotNull ButtonInteractionEvent event, @NotNull Button button) {
111-
event.deferEdit().queue();
112159
String[] id = ComponentIdBuilder.split(event.getComponentId());
113160
if (event.getGuild() == null) {
114161
Responses.error(event.getHook(), "This button may only be used in context of a server.").queue();
115162
return;
116163
}
164+
165+
(switch (id[1]) {
166+
case "delete" -> delete(event.getInteraction());
167+
case "kick" -> generateModal(event, "Kick user");
168+
case "ban" -> generateModal(event, "Ban user");
169+
case "unban" -> generateModal(event, "Unban user");
170+
case "warn" -> event.replyComponents(ActionRow.of(StringSelectMenu.create(event.getComponentId())
171+
.addOptions(Arrays.stream(WarnSeverity.values())
172+
.map(severity -> SelectOption.of(severity.toString(), severity.name()))
173+
.toArray(SelectOption[]::new))
174+
.build())).setEphemeral(true);
175+
default -> event.reply("Invalid action");
176+
}).queue();
177+
}
178+
179+
private ModalCallbackAction generateModal(ButtonInteractionEvent event, String title) {
180+
return event.replyModal(Modal.create(event.getComponentId(), title)
181+
.addActionRow(TextInput.create("reason", "Reason", TextInputStyle.SHORT).setRequired(true).build())
182+
.build());
183+
}
184+
185+
@Override
186+
public void handleModal(@Nonnull ModalInteractionEvent event, @Nonnull List<ModalMapping> mappings) {
187+
event.deferEdit().queue();
188+
String[] id = ComponentIdBuilder.split(event.getModalId());
189+
if (event.getGuild() == null) {
190+
Responses.error(event.getHook(), "This button may only be used in context of a server.").queue();
191+
return;
192+
}
193+
String reason = "None";
194+
WarnSeverity severity=WarnSeverity.MEDIUM;
195+
196+
for (ModalMapping mapping : mappings) {
197+
if ("reason".equals(mapping.getId())) {
198+
reason = mapping.getAsString();
199+
}
200+
if ("severity".equals(mapping.getId())) {
201+
severity=WarnSeverity.valueOf(mapping.getAsString());
202+
}
203+
}
204+
117205
switch (id[1]) {
118-
case "delete" -> delete(event.getInteraction());
119-
case "kick" -> kick(event.getInteraction(), event.getGuild(), id[2]);
120-
case "ban" -> ban(event.getInteraction(), event.getGuild(), id[2]);
121-
case "unban" -> unban(event.getInteraction(), Long.parseLong(id[2]));
206+
case "kick" -> kick(event.getInteraction(), event.getGuild(), id[2], reason);
207+
case "ban" -> ban(event.getInteraction(), event.getGuild(), id[2], reason);
208+
case "warn" -> warn(event.getInteraction(), event.getGuild(), id[2], severity, reason);
209+
case "unban" -> unban(event.getInteraction(), Long.parseLong(id[2]), reason);
122210
}
123211
}
212+
213+
@Override
214+
public void handleStringSelectMenu(@Nonnull StringSelectInteractionEvent event, @Nonnull List<String> options) {
215+
event.replyModal(Modal.create(event.getComponentId()+":"+options.get(0), "Warn user")
216+
.addActionRow(TextInput.create("reason", "Reason", TextInputStyle.SHORT).setRequired(true).build())
217+
.build())
218+
.queue();
219+
}
124220
}

0 commit comments

Comments
 (0)