diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 8d17ee2cb9..afe5444f91 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -19,13 +19,15 @@ "extensions": [ "vscjava.vscode-java-pack", "vscjava.vscode-gradle", - "alexcvzz.vscode-sqlite", - "richardwillis.vscode-spotless-gradle" + "alexcvzz.vscode-sqlite" ], "settings": { "[java]": { - "spotlessGradle.format.enable": true, - "editor.defaultFormatter": "richardwillis.vscode-spotless-gradle" + "java.compile.nullAnalysis.mode": "disabled", + "java.format.settings.url": "meta/formatting/google-style-eclipse.xml", + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "java.format.enabled": true } } } @@ -33,4 +35,4 @@ "postCreateCommand": { "config": "cp application/config.json.template application/config.json" } -} +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 42983f369c..72e35328b6 100644 --- a/.gitignore +++ b/.gitignore @@ -160,3 +160,15 @@ logviewer/pnpm-lock.yaml logviewer/webpack.config.js logviewer/webpack.generated.js .DS_Store + +# VisualStudioCode +.vscode/* +!.vscode/settings.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000..44d6e10323 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "vscjava.vscode-gradle", + "github.vscode-pull-request-github", + "vscjava.vscode-java-pack", + "alexcvzz.vscode-sqlite" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..5f19eba23c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + //Configure the JDK to Java 18 in settings + "java.compile.nullAnalysis.mode": "disabled", + "java.format.settings.url": "meta/formatting/google-style-eclipse.xml", + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "java.format.enabled": true, +} \ No newline at end of file diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/modmail/ModMailCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/modmail/ModMailCommand.java index 0ab3181f7a..6f3f5609f5 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/modmail/ModMailCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/modmail/ModMailCommand.java @@ -8,11 +8,16 @@ import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.InteractionHook; import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.components.ActionRow; +import net.dv8tion.jda.api.interactions.components.Modal; +import net.dv8tion.jda.api.interactions.components.text.TextInput; +import net.dv8tion.jda.api.interactions.components.text.TextInputStyle; import net.dv8tion.jda.api.requests.restaction.MessageCreateAction; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -43,7 +48,7 @@ public final class ModMailCommand extends SlashCommandAdapter { private static final Logger logger = LoggerFactory.getLogger(ModMailCommand.class); public static final String COMMAND_NAME = "modmail"; - private static final String OPTION_MESSAGE = "message"; + private static final String MESSAGE = "message"; private static final String OPTION_STAY_ANONYMOUS = "stay-anonymous"; private static final String OPTION_GUILD = "server"; private static final int COOLDOWN_DURATION_VALUE = 30; @@ -65,8 +70,6 @@ public ModMailCommand(JDA jda, Config config) { super(COMMAND_NAME, "Contact the moderators of the selected guild", CommandVisibility.GLOBAL); - OptionData messageOption = new OptionData(OptionType.STRING, OPTION_MESSAGE, - "What do you want to tell them?", true); OptionData guildOption = new OptionData(OptionType.STRING, OPTION_GUILD, "The server to contact mods from", true); OptionData anonymousOption = new OptionData(OptionType.BOOLEAN, OPTION_STAY_ANONYMOUS, @@ -79,7 +82,7 @@ public ModMailCommand(JDA jda, Config config) { guildOption.addChoices(choices); - getData().addOptions(messageOption, guildOption, anonymousOption); + getData().addOptions(guildOption, anonymousOption); modMailChannelNamePredicate = Pattern.compile(config.getModMailChannelPattern()).asMatchPredicate(); @@ -104,10 +107,34 @@ public void onSlashCommand(SlashCommandInteractionEvent event) { if (handleIsOnCooldown(userId, event)) { return; } + + TextInput body = TextInput.create(MESSAGE, "Message", TextInputStyle.PARAGRAPH) + .setPlaceholder("What do you want to tell them?") + .setMinLength(5) + .setMaxLength(1000) + .build(); + + boolean stayAnonymous = event.getOption(OPTION_STAY_ANONYMOUS).getAsBoolean(); + long guildToContact = event.getOption(OPTION_GUILD).getAsLong(); + + String componentId = + generateComponentId(String.valueOf(stayAnonymous), String.valueOf(guildToContact)); + Modal modal = Modal.create(componentId, "Send this to the moderators") + .addActionRows(ActionRow.of(body)) + .build(); + + event.replyModal(modal).queue(); + authorToLastModMailInvocation.put(userId, Instant.now()); + } + + @Override + public void onModalSubmitted(ModalInteractionEvent event, List args) { + long userId = event.getUser().getIdLong(); + event.deferReply().setEphemeral(true).queue(); - long userGuildId = event.getOption(OPTION_GUILD).getAsLong(); + long userGuildId = event.getJDA().getGuildById(args.get(1)).getIdLong(); Optional modMailAuditLog = getModMailChannel(event.getJDA(), userGuildId); if (modMailAuditLog.isEmpty()) { logger.warn( @@ -116,11 +143,10 @@ public void onSlashCommand(SlashCommandInteractionEvent event) { return; } - MessageCreateAction message = - createModMessage(event, userId, modMailAuditLog.orElseThrow()); + MessageCreateAction message = createModMessage(event, Boolean.parseBoolean(args.get(0)), + userId, modMailAuditLog.orElseThrow()); sendMessage(event, message); - } private boolean handleIsOnCooldown(long userId, SlashCommandInteractionEvent event) { @@ -141,10 +167,9 @@ private Optional getModMailChannel(JDA jda, long guildId) { .findAny(); } - private MessageCreateAction createModMessage(SlashCommandInteractionEvent event, long userId, - TextChannel modMailAuditLog) { - String userMessage = event.getOption(OPTION_MESSAGE).getAsString(); - boolean wantsToStayAnonymous = event.getOption(OPTION_STAY_ANONYMOUS).getAsBoolean(); + private MessageCreateAction createModMessage(ModalInteractionEvent event, + boolean wantsToStayAnonymous, long userId, TextChannel modMailAuditLog) { + String userMessage = event.getValue(MESSAGE).getAsString(); User user = wantsToStayAnonymous ? null : event.getUser(); MessageCreateAction message = @@ -165,7 +190,7 @@ private MessageCreateAction createModMessage(SlashCommandInteractionEvent event, return message; } - private void sendMessage(SlashCommandInteractionEvent event, MessageCreateAction message) { + private void sendMessage(ModalInteractionEvent event, MessageCreateAction message) { InteractionHook hook = event.getHook(); message.mapToResult().map(result -> { if (result.isSuccess()) {