-
Notifications
You must be signed in to change notification settings - Fork 24
Forms system #524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Forms system #524
Changes from 8 commits
a114e30
bdf0b1a
b62574d
2c97172
7db911a
e2c6372
7cb72ed
61d7e36
21d9a42
3425fa0
fdd328e
123282b
7fccf8e
385820d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,9 +76,9 @@ public class FormInteractionManager implements ButtonHandler, ModalHandler { | |
| public void closeForm(Guild guild, FormData form) { | ||
| formsRepo.closeForm(form); | ||
|
|
||
| if (form.getMessageChannel() != null && form.getMessageId() != null) { | ||
| TextChannel formChannel = guild.getTextChannelById(form.getMessageChannel()); | ||
| formChannel.retrieveMessageById(form.getMessageId()).queue(msg -> { | ||
| if (form.isAttached()) { | ||
| TextChannel formChannel = guild.getTextChannelById(form.getMessageChannel().get()); | ||
| formChannel.retrieveMessageById(form.getMessageId().get()).queue(msg -> { | ||
| mapFormMessageButtons(msg, btn -> { | ||
| String cptId = btn.getId(); | ||
| String[] split = ComponentIdBuilder.split(cptId); | ||
|
|
@@ -149,8 +149,9 @@ public void handleModal(ModalInteractionEvent event, List<ModalMapping> values) | |
| return; | ||
| } | ||
|
|
||
| channel.sendMessageEmbeds(createSubmissionEmbed(form, values, event.getMember())).queue(); | ||
| formsRepo.logSubmission(event.getUser(), form); | ||
| channel.sendMessageEmbeds(createSubmissionEmbed(form, values, event.getMember())).queue(msg -> { | ||
| formsRepo.addSubmission(event.getUser(), form, msg); | ||
| }); | ||
|
|
||
| event.getHook() | ||
| .sendMessage( | ||
|
|
@@ -190,9 +191,9 @@ public void mapFormMessageButtons(Message msg, Function<Button, Button> mapper) | |
| public void reopenForm(Guild guild, FormData form) { | ||
| formsRepo.reopenForm(form); | ||
|
|
||
| if (form.getMessageChannel() != null && form.getMessageId() != null) { | ||
| TextChannel formChannel = guild.getTextChannelById(form.getMessageChannel()); | ||
| formChannel.retrieveMessageById(form.getMessageId()).queue(msg -> { | ||
| if (form.isAttached()) { | ||
| TextChannel formChannel = guild.getTextChannelById(form.getMessageChannel().get()); | ||
| formChannel.retrieveMessageById(form.getMessageId().get()).queue(msg -> { | ||
| mapFormMessageButtons(msg, btn -> { | ||
| String cptId = btn.getId(); | ||
| String[] split = ComponentIdBuilder.split(cptId); | ||
|
|
@@ -267,7 +268,7 @@ private static MessageEmbed createSubmissionEmbed(FormData form, List<ModalMappi | |
| ModalMapping mapping = values.get(i); | ||
| FormField field = form.getFields().get(i); | ||
| String value = mapping.getAsString(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess you might want to replace markdown codeblocks with something like or truncate them - or generally prohibit that?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good point, I'll definitely do that |
||
| builder.addField(field.getLabel(), value == null ? "*Empty*" : "```\n" + value + "\n```", false); | ||
| builder.addField(field.label(), value == null ? "*Empty*" : "```\n" + value + "\n```", false); | ||
| } | ||
|
|
||
| return builder.build(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,8 +40,7 @@ public AddFieldFormSubcommand(FormsRepository formsRepo) { | |
| .addOption(OptionType.BOOLEAN, "required", | ||
| "Whether or not the user has to input data in this field. Default: false") | ||
| .addOption(OptionType.STRING, "style", "Input style. Default: SHORT", false, true) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think a choice option would be better than autocomplete for the style. |
||
| .addOption(OptionType.STRING, "value", "Initial field value") | ||
| .addOption(OptionType.INTEGER, "index", "Index to insert the field at")); | ||
| .addOption(OptionType.STRING, "value", "Initial field value")); | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -60,13 +59,7 @@ public void execute(SlashCommandInteractionEvent event) { | |
| return; | ||
| } | ||
|
|
||
| int index = event.getOption("index", -1, OptionMapping::getAsInt); | ||
| if (index < -1 || index >= form.getFields().size()) { | ||
| event.getHook().sendMessage("Field index out of bounds").queue(); | ||
| return; | ||
| } | ||
|
|
||
| formsRepo.addField(form, createFormFieldFromEvent(event), index); | ||
| formsRepo.addField(form, createFormFieldFromEvent(event)); | ||
| event.getHook().sendMessage("Added a new field to the form.").queue(); | ||
| } | ||
|
|
||
|
|
@@ -98,6 +91,6 @@ private static FormField createFormFieldFromEvent(SlashCommandInteractionEvent e | |
| }); | ||
| String value = e.getOption("value", OptionMapping::getAsString); | ||
|
|
||
| return new FormField(label, max, min, placeholder, required, style.name(), value); | ||
| return new FormField(label, max, min, placeholder, required, style, value, 0); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,8 +48,9 @@ public void execute(SlashCommandInteractionEvent event) { | |
| FormData form = formOpt.get(); | ||
| formsRepo.deleteForm(form); | ||
|
|
||
| if (form.getMessageChannel() != null && form.getMessageId() != null) { | ||
| if (form.isAttached()) { | ||
| DetachFormSubcommand.detachFromMessage(form, event.getGuild()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think it's better to detach and delete a form automatically if it's attached or to show an error message to the user?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good point. I assumed the form should be detached automatically when the user deletes it. |
||
| // TODO send a warning | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This TODO comment should be implemented before this PR is merged (and then you also wouldn't need the detaching here) ;)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, that's the plan. |
||
| } | ||
|
|
||
| event.getHook().sendMessage("Form deleted!").queue(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,7 +54,7 @@ public void execute(SlashCommandInteractionEvent event) { | |
| } | ||
| FormData form = formOpt.get(); | ||
|
|
||
| if (form.getMessageChannel() == null && form.getMessageId() == null) { | ||
| if (!form.isAttached()) { | ||
| event.getHook().sendMessage("This form doesn't seem to be attached to a message").queue(); | ||
| return; | ||
| } | ||
|
|
@@ -80,8 +80,9 @@ public void handleAutoComplete(CommandAutoCompleteInteractionEvent event, AutoCo | |
| * @param guild guild this form is contained in | ||
| */ | ||
| public static void detachFromMessage(FormData form, Guild guild) { | ||
| TextChannel formChannel = guild.getTextChannelById(form.getMessageChannel()); | ||
| formChannel.retrieveMessageById(form.getMessageId()).queue(msg -> { | ||
| if(!form.isAttached()) return; | ||
| TextChannel formChannel = guild.getTextChannelById(form.getMessageChannel().get()); | ||
| formChannel.retrieveMessageById(form.getMessageId().get()).queue(msg -> { | ||
| List<ActionRow> components = msg.getActionRows().stream().map(row -> { | ||
| ItemComponent[] cpts = row.getComponents().stream().filter(cpt -> { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, I don't think there's a good reason to use arrays here. |
||
| if (cpt instanceof Button btn) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,11 +80,10 @@ private EmbedBuilder createFormDetailsEmbed(FormData form, Guild guild) { | |
| addCodeblockField(builder, "State", form.isClosed() ? "Closed" : form.hasExpired() ? "Expired" : "Open", false); | ||
|
|
||
| builder.addField("Attached in", | ||
| form.getMessageChannel() == null ? "*Not attached*" : "<#" + form.getMessageChannel() + ">", true); | ||
| form.isAttached() ? "<#" + form.getMessageChannel().get() + ">" : "*Not attached*", true); | ||
| builder.addField("Attached to", | ||
| form.getMessageChannel() == null || form.getMessageId() == null ? "*Not attached*" | ||
| : String.format("[Link](https://discord.com/channels/%s/%s/%s)", guild.getId(), | ||
| form.getMessageChannel(), form.getMessageId()), | ||
| form.isAttached() ? String.format("[Link](https://discord.com/channels/%s/%s/%s)", guild.getId(), | ||
| form.getMessageChannel().get(), form.getMessageId().get()) : "*Not attached*", | ||
| true); | ||
|
|
||
| builder.addField("Submissions channel", "<#" + form.getSubmitChannel() + ">", true); | ||
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,7 +52,7 @@ public void execute(SlashCommandInteractionEvent event) { | |
| return; | ||
| } | ||
|
|
||
| if (form.getMessageChannel() != null && form.getMessageId() != null && form.getFields().size() <= 1) { | ||
| if (form.isAttached() && form.getFields().size() <= 1) { | ||
| event.getHook().sendMessage( | ||
| "Can't remove the last field from an attached form. Detach the form before removing the field") | ||
| .queue(); | ||
|
|
@@ -61,7 +61,7 @@ public void execute(SlashCommandInteractionEvent event) { | |
|
|
||
| formsRepo.removeField(form, index); | ||
|
|
||
| event.getHook().sendMessage("Removed field `" + form.getFields().get(index).getLabel() + "` from the form.") | ||
| event.getHook().sendMessage("Removed field `" + form.getFields().get(index).label() + "` from the form.") | ||
| .queue(); | ||
| } | ||
|
|
||
|
|
@@ -79,7 +79,7 @@ public void handleAutoComplete(CommandAutoCompleteInteractionEvent event, AutoCo | |
| List<Choice> choices = new ArrayList<>(); | ||
| List<FormField> fields = form.get().getFields(); | ||
| for (int i = 0; i < fields.size(); i++) { | ||
| choices.add(new Choice(fields.get(i).getLabel(), i)); | ||
| choices.add(new Choice(fields.get(i).label(), i)); | ||
| } | ||
| event.replyChoices(choices).queue(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, reminder to use |
||
| return; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
|
|
||
| import net.discordjug.javabot.systems.staff_commands.forms.dao.FormsRepository; | ||
| import net.discordjug.javabot.systems.staff_commands.forms.model.FormData; | ||
| import net.dv8tion.jda.api.entities.User; | ||
| import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; | ||
| import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; | ||
| import net.dv8tion.jda.api.interactions.AutoCompleteQuery; | ||
|
|
@@ -29,11 +30,9 @@ public class SubmissionsDeleteFormSubcommand extends Subcommand implements AutoC | |
| */ | ||
| public SubmissionsDeleteFormSubcommand(FormsRepository formsRepo) { | ||
| this.formsRepo = formsRepo; | ||
| setCommandData( | ||
| new SubcommandData("submissions-delete", "Deletes submissions of an user in the form").addOptions( | ||
| new OptionData(OptionType.INTEGER, "form-id", "The ID of a form to get submissions for", true, | ||
| true), | ||
| new OptionData(OptionType.STRING, "user-id", "User to delete submissions of", true, true))); | ||
| setCommandData(new SubcommandData("submissions-delete", "Deletes submissions of a user in the form") | ||
| .addOptions(new OptionData(OptionType.INTEGER, "form-id", "The ID of a form to get submissions for", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. get submissions for is misleading.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, it's just another oversight of mine. I did a lot of copy-pasting when creating the commands, and it seems I forgot to change the parameter description here |
||
| true, true), new OptionData(OptionType.USER, "user", "User to delete submissions of", true))); | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -45,7 +44,7 @@ public void execute(SlashCommandInteractionEvent event) { | |
| return; | ||
| } | ||
|
|
||
| String user = event.getOption("user-id", OptionMapping::getAsString); | ||
| User user = event.getOption("user", OptionMapping::getAsUser); | ||
| FormData form = formOpt.get(); | ||
|
|
||
| int count = formsRepo.deleteSubmissions(form, user); | ||
|
|
@@ -54,24 +53,8 @@ public void execute(SlashCommandInteractionEvent event) { | |
|
|
||
| @Override | ||
| public void handleAutoComplete(CommandAutoCompleteInteractionEvent event, AutoCompleteQuery target) { | ||
| switch (target.getName()) { | ||
| case "user-id" -> { | ||
| Long formId = event.getOption("form-id", OptionMapping::getAsLong); | ||
| if (formId != null) { | ||
| Optional<FormData> form = formsRepo.getForm(formId); | ||
| if (form.isPresent()) { | ||
| event.replyChoices(formsRepo.getAllSubmissions(form.get()).keySet().stream() | ||
| .map(user -> new Choice(user.getUsername(), Long.toString(user.getId()))).toList()) | ||
| .queue(); | ||
| return; | ||
| } | ||
| } | ||
| event.replyChoices().queue(); | ||
| } | ||
| case "form-id" -> event.replyChoices( | ||
| formsRepo.getAllForms().stream().map(form -> new Choice(form.toString(), form.getId())).toList()) | ||
| .queue(); | ||
| default -> {} | ||
| } | ||
| event.replyChoices( | ||
| formsRepo.getAllForms().stream().map(form -> new Choice(form.toString(), form.getId())).toList()) | ||
| .queue(); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both the submission and the confirmation should be sent only if the message has been sent successfully. If it hasn't, there should be an error message sent to the user saying there was an error with the submission and a log message.
My guess is that the most likely reason this could happen would be hitting the message character limit or similar.