22
33import xyz .dynxsty .dih4jda .util .ComponentIdBuilder ;
44import xyz .dynxsty .dih4jda .interactions .components .ButtonHandler ;
5-
5+ import xyz .dynxsty .dih4jda .interactions .components .ModalHandler ;
6+ import xyz .dynxsty .dih4jda .interactions .components .StringSelectMenuHandler ;
67import lombok .RequiredArgsConstructor ;
8+ import net .dv8tion .jda .api .Permission ;
79import net .dv8tion .jda .api .entities .Guild ;
810import net .dv8tion .jda .api .entities .Member ;
911import net .dv8tion .jda .api .entities .Message ;
12+ import net .dv8tion .jda .api .events .interaction .ModalInteractionEvent ;
1013import 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 ;
1116import net .dv8tion .jda .api .interactions .components .buttons .Button ;
1217import 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 ;
1327import net .javadiscord .javabot .annotations .AutoDetectableComponentHandler ;
1428import net .javadiscord .javabot .data .config .BotConfig ;
1529import net .javadiscord .javabot .data .config .GuildConfig ;
1630import net .javadiscord .javabot .data .h2db .DbHelper ;
1731import net .javadiscord .javabot .systems .moderation .ModerationService ;
1832import net .javadiscord .javabot .systems .moderation .warn .dao .WarnRepository ;
33+ import net .javadiscord .javabot .systems .moderation .warn .model .WarnSeverity ;
1934import net .javadiscord .javabot .systems .notification .NotificationService ;
2035
36+ import java .util .Arrays ;
37+ import java .util .List ;
2138import java .util .concurrent .ExecutorService ;
2239
40+ import javax .annotation .CheckReturnValue ;
41+ import javax .annotation .Nonnull ;
42+
2343import 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