Skip to content

Commit f6f2149

Browse files
committed
Migrate forms feature to new JDA and Java version
1 parent 2763a57 commit f6f2149

File tree

10 files changed

+554
-552
lines changed

10 files changed

+554
-552
lines changed

src/main/java/net/discordjug/javabot/systems/staff_commands/forms/FormInteractionManager.java

Lines changed: 234 additions & 233 deletions
Large diffs are not rendered by default.

src/main/java/net/discordjug/javabot/systems/staff_commands/forms/commands/AddFieldFormSubcommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
import net.discordjug.javabot.systems.staff_commands.forms.dao.FormsRepository;
77
import net.discordjug.javabot.systems.staff_commands.forms.model.FormData;
88
import net.discordjug.javabot.systems.staff_commands.forms.model.FormField;
9+
import net.dv8tion.jda.api.components.textinput.TextInputStyle;
910
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
1011
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
1112
import net.dv8tion.jda.api.interactions.AutoCompleteQuery;
1213
import net.dv8tion.jda.api.interactions.commands.Command.Choice;
1314
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
1415
import net.dv8tion.jda.api.interactions.commands.OptionType;
1516
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
16-
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
1717
import xyz.dynxsty.dih4jda.interactions.AutoCompletable;
1818
import xyz.dynxsty.dih4jda.interactions.commands.application.SlashCommand.Subcommand;
1919

Lines changed: 119 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
package net.discordjug.javabot.systems.staff_commands.forms.commands;
22

33
import java.util.ArrayList;
4+
import java.util.Collections;
45
import java.util.List;
56
import java.util.Optional;
67
import java.util.Set;
78

89
import net.discordjug.javabot.systems.staff_commands.forms.FormInteractionManager;
910
import net.discordjug.javabot.systems.staff_commands.forms.dao.FormsRepository;
1011
import net.discordjug.javabot.systems.staff_commands.forms.model.FormData;
12+
import net.dv8tion.jda.api.components.MessageTopLevelComponentUnion;
13+
import net.dv8tion.jda.api.components.actionrow.ActionRow;
14+
import net.dv8tion.jda.api.components.actionrow.ActionRowChildComponent;
15+
import net.dv8tion.jda.api.components.buttons.Button;
16+
import net.dv8tion.jda.api.components.buttons.ButtonStyle;
1117
import net.dv8tion.jda.api.entities.Message;
1218
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
1319
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
@@ -19,10 +25,6 @@
1925
import net.dv8tion.jda.api.interactions.commands.OptionType;
2026
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
2127
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
22-
import net.dv8tion.jda.api.interactions.components.ActionRow;
23-
import net.dv8tion.jda.api.interactions.components.ItemComponent;
24-
import net.dv8tion.jda.api.interactions.components.buttons.Button;
25-
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
2628
import xyz.dynxsty.dih4jda.interactions.AutoCompletable;
2729
import xyz.dynxsty.dih4jda.interactions.commands.application.SlashCommand.Subcommand;
2830
import xyz.dynxsty.dih4jda.util.ComponentIdBuilder;
@@ -32,117 +34,118 @@
3234
*/
3335
public class AttachFormSubcommand extends Subcommand implements AutoCompletable {
3436

35-
private final FormsRepository formsRepo;
36-
37-
/**
38-
* The main constructor of this subcommand.
39-
*
40-
* @param formsRepo the forms repository
41-
*/
42-
public AttachFormSubcommand(FormsRepository formsRepo) {
43-
this.formsRepo = formsRepo;
44-
setCommandData(new SubcommandData("attach", "Attach a form to a message").addOptions(
45-
new OptionData(OptionType.INTEGER, "form-id", "ID of the form to attach", true, true),
46-
new OptionData(OptionType.STRING, "message-id", "ID of the message to attach the form to", true),
47-
new OptionData(OptionType.CHANNEL, "channel",
48-
"Channel of the message. Required if the message is in a different channel"),
49-
new OptionData(OptionType.STRING, "button-label", "Label of the submit button. Default is \"Submit\""),
50-
new OptionData(OptionType.STRING, "button-style", "Submit button style. Defaults to primary", false,
51-
true)));
52-
}
53-
54-
@Override
55-
public void execute(SlashCommandInteractionEvent event) {
56-
57-
event.deferReply().setEphemeral(true).queue();
58-
59-
Optional<FormData> formOpt = formsRepo.getForm(event.getOption("form-id", OptionMapping::getAsLong));
60-
if (formOpt.isEmpty()) {
61-
event.getHook().sendMessage("A form with this ID was not found.").queue();
62-
return;
63-
}
64-
FormData form = formOpt.get();
65-
66-
if (form.isAttached()) {
67-
event.getHook()
68-
.sendMessage("The form seems to already be attached to a message. Detach it before continuing.")
69-
.queue();
70-
return;
71-
}
72-
73-
if (form.fields().isEmpty()) {
74-
event.getHook().sendMessage("You can't attach a form with no fields.").queue();
75-
return;
76-
}
77-
78-
String messageId = event.getOption("message-id", OptionMapping::getAsString);
79-
GuildChannel channel = event.getOption("channel", event.getChannel().asGuildMessageChannel(),
80-
OptionMapping::getAsChannel);
81-
82-
if (channel == null) {
83-
event.getHook().sendMessage("A channel with this ID was not found.").setEphemeral(true).queue();
84-
return;
85-
}
86-
87-
if (!(channel instanceof MessageChannel msgChannel)) {
88-
event.getHook().sendMessage("You must specify a message channel").setEphemeral(true).queue();
89-
return;
90-
}
91-
92-
String buttonLabel = event.getOption("button-label", "Submit", OptionMapping::getAsString);
93-
ButtonStyle style = event.getOption("button-style", ButtonStyle.PRIMARY, t -> {
94-
try {
95-
return ButtonStyle.valueOf(t.getAsString().toUpperCase());
96-
} catch (IllegalArgumentException e) {
97-
return ButtonStyle.PRIMARY;
98-
}
99-
});
100-
101-
msgChannel.retrieveMessageById(messageId).queue(message -> {
102-
attachFormToMessage(message, buttonLabel, style, form);
103-
formsRepo.attachForm(form, msgChannel, message);
104-
event.getHook()
105-
.sendMessage("Successfully attached the form to the [message](" + message.getJumpUrl() + ")!")
106-
.queue();
107-
}, t -> event.getHook().sendMessage("A message with this ID was not found").queue());
108-
}
109-
110-
@Override
111-
public void handleAutoComplete(CommandAutoCompleteInteractionEvent event, AutoCompleteQuery target) {
112-
switch (target.getName()) {
113-
case "form-id" -> event.replyChoices(
114-
formsRepo.getAllForms().stream().map(form -> new Choice(form.toString(), form.id())).toList())
115-
.queue();
116-
case "button-style" -> event.replyChoices(
117-
Set.of(ButtonStyle.DANGER, ButtonStyle.PRIMARY, ButtonStyle.SECONDARY, ButtonStyle.SUCCESS).stream()
118-
.map(style -> new Choice(style.name(), style.name())).toList())
119-
.queue();
120-
default -> {}
121-
}
122-
}
123-
124-
private static void attachFormToMessage(Message message, String buttonLabel, ButtonStyle style, FormData form) {
125-
List<ActionRow> rows = new ArrayList<>(message.getActionRows());
126-
127-
Button button = Button.of(style,
128-
ComponentIdBuilder.build(FormInteractionManager.FORM_COMPONENT_ID, form.id()), buttonLabel);
129-
130-
if (form.closed() || form.hasExpired()) {
131-
button = button.asDisabled();
132-
}
133-
134-
if (rows.isEmpty() || rows.get(rows.size() - 1).getActionComponents().size() >= 5) {
135-
rows.add(ActionRow.of(button));
136-
} else {
137-
ActionRow lastRow = rows.get(rows.size() - 1);
138-
ItemComponent[] components = new ItemComponent[lastRow.getComponents().size() + 1];
139-
System.arraycopy(lastRow.getComponents().toArray(new ItemComponent[0]), 0, components, 0,
140-
lastRow.getComponents().size());
141-
components[components.length - 1] = button;
142-
rows.set(rows.size() - 1, ActionRow.of(components));
143-
}
144-
145-
message.editMessageComponents(rows.toArray(new ActionRow[0])).queue();
146-
}
37+
private final FormsRepository formsRepo;
38+
39+
/**
40+
* The main constructor of this subcommand.
41+
*
42+
* @param formsRepo the forms repository
43+
*/
44+
public AttachFormSubcommand(FormsRepository formsRepo) {
45+
this.formsRepo = formsRepo;
46+
setCommandData(new SubcommandData("attach", "Attach a form to a message").addOptions(
47+
new OptionData(OptionType.INTEGER, "form-id", "ID of the form to attach", true, true),
48+
new OptionData(OptionType.STRING, "message-id", "ID of the message to attach the form to", true),
49+
new OptionData(OptionType.CHANNEL, "channel",
50+
"Channel of the message. Required if the message is in a different channel"),
51+
new OptionData(OptionType.STRING, "button-label", "Label of the submit button. Default is \"Submit\""),
52+
new OptionData(OptionType.STRING, "button-style", "Submit button style. Defaults to primary", false,
53+
true)));
54+
}
55+
56+
@Override
57+
public void execute(SlashCommandInteractionEvent event) {
58+
59+
event.deferReply().setEphemeral(true).queue();
60+
61+
Optional<FormData> formOpt = formsRepo.getForm(event.getOption("form-id", OptionMapping::getAsLong));
62+
if (formOpt.isEmpty()) {
63+
event.getHook().sendMessage("A form with this ID was not found.").queue();
64+
return;
65+
}
66+
FormData form = formOpt.get();
67+
68+
if (form.isAttached()) {
69+
event.getHook()
70+
.sendMessage("The form seems to already be attached to a message. Detach it before continuing.")
71+
.queue();
72+
return;
73+
}
74+
75+
if (form.fields().isEmpty()) {
76+
event.getHook().sendMessage("You can't attach a form with no fields.").queue();
77+
return;
78+
}
79+
80+
String messageId = event.getOption("message-id", OptionMapping::getAsString);
81+
GuildChannel channel = event.getOption("channel", event.getChannel().asGuildMessageChannel(),
82+
OptionMapping::getAsChannel);
83+
84+
if (channel == null) {
85+
event.getHook().sendMessage("A channel with this ID was not found.").setEphemeral(true).queue();
86+
return;
87+
}
88+
89+
if (!(channel instanceof MessageChannel msgChannel)) {
90+
event.getHook().sendMessage("You must specify a message channel").setEphemeral(true).queue();
91+
return;
92+
}
93+
94+
String buttonLabel = event.getOption("button-label", "Submit", OptionMapping::getAsString);
95+
net.dv8tion.jda.api.components.buttons.ButtonStyle style = event.getOption("button-style", ButtonStyle.PRIMARY,
96+
t -> {
97+
try {
98+
return ButtonStyle.valueOf(t.getAsString().toUpperCase());
99+
} catch (IllegalArgumentException e) {
100+
return ButtonStyle.PRIMARY;
101+
}
102+
});
103+
104+
msgChannel.retrieveMessageById(messageId).queue(message -> {
105+
attachFormToMessage(message, buttonLabel, style, form);
106+
formsRepo.attachForm(form, msgChannel, message);
107+
event.getHook()
108+
.sendMessage("Successfully attached the form to the [message](" + message.getJumpUrl() + ")!")
109+
.queue();
110+
}, _ -> event.getHook().sendMessage("A message with this ID was not found").queue());
111+
}
112+
113+
@Override
114+
public void handleAutoComplete(CommandAutoCompleteInteractionEvent event, AutoCompleteQuery target) {
115+
switch (target.getName()) {
116+
case "form-id" -> event.replyChoices(
117+
formsRepo.getAllForms().stream().map(form -> new Choice(form.toString(), form.id())).toList())
118+
.queue();
119+
case "button-style" -> event.replyChoices(
120+
Set.of(ButtonStyle.DANGER, ButtonStyle.PRIMARY, ButtonStyle.SECONDARY, ButtonStyle.SUCCESS).stream()
121+
.map(style -> new Choice(style.name(), style.name())).toList())
122+
.queue();
123+
default -> {}
124+
}
125+
}
126+
127+
private static void attachFormToMessage(Message message, String buttonLabel, ButtonStyle style, FormData form) {
128+
List<ActionRow> rows = new ArrayList<>(
129+
message.getComponents().stream().map(MessageTopLevelComponentUnion::asActionRow).toList());
130+
131+
Button button = Button.of(style, ComponentIdBuilder.build(FormInteractionManager.FORM_COMPONENT_ID, form.id()),
132+
buttonLabel);
133+
134+
if (form.closed() || form.hasExpired()) {
135+
button = button.asDisabled();
136+
}
137+
138+
if (rows.isEmpty() || rows.get(rows.size() - 1).getActionComponents().size() >= 5) {
139+
rows.add(ActionRow.of(button));
140+
} else {
141+
ActionRow lastRow = rows.get(rows.size() - 1);
142+
List<ActionRowChildComponent> components = new ArrayList<>(lastRow.getComponents().size() + 1);
143+
Collections.copy(components, lastRow.getComponents());
144+
components.set(components.size() - 1, button);
145+
rows.set(rows.size() - 1, ActionRow.of(components));
146+
}
147+
148+
message.editMessageComponents(rows.toArray(new ActionRow[0])).queue();
149+
}
147150

148151
}

src/main/java/net/discordjug/javabot/systems/staff_commands/forms/commands/CreateFormSubcommand.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ public CreateFormSubcommand(FormsRepository formsRepo) {
4444
public void execute(SlashCommandInteractionEvent event) {
4545

4646
event.deferReply().setEphemeral(true).queue();
47-
String expirationStr = event.getOption("expiration", null, OptionMapping::getAsString);
4847
Optional<Instant> expirationOpt;
4948
try {
5049
expirationOpt = FormInteractionManager.parseExpiration(event);

0 commit comments

Comments
 (0)