diff --git a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/CustomTagManager.java b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/CustomTagManager.java index ac917716d..4c2f731dc 100644 --- a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/CustomTagManager.java +++ b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/CustomTagManager.java @@ -84,13 +84,13 @@ public class CustomTagManager { Set> actions = new HashSet<>(); if (tag.isEmbed()) { if (tag.isReply()) { - actions.add(event.getHook().sendMessageEmbeds(tag.toEmbed())); + actions.add(event.replyEmbeds(tag.toEmbed())); } else { actions.add(event.getChannel().sendMessageEmbeds(tag.toEmbed())); } } else { if (tag.isReply()) { - actions.add(event.getHook().sendMessage(tag.getResponse()).setAllowedMentions(List.of())); + actions.add(event.reply(tag.getResponse()).setAllowedMentions(List.of())); } else { actions.add(event.getChannel().sendMessage(tag.getResponse()).setAllowedMentions(List.of())); } diff --git a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagListSubcommand.java b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagListSubcommand.java index 8a26655da..051b546d2 100644 --- a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagListSubcommand.java +++ b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagListSubcommand.java @@ -18,7 +18,7 @@ import java.util.stream.Collectors; /** - *

This class represents the /tags command.

+ *

This class represents the /tag list command.

*/ public class TagListSubcommand extends TagsSubcommand { private final ExecutorService asyncPool; @@ -43,11 +43,16 @@ public ReplyCallbackAction handleCustomTagsSubcommand(@NotNull SlashCommandInter asyncPool.execute(()->{ try { List tags = customTagRepository.getCustomTagsByGuildId(event.getGuild().getIdLong()); - String tagList = tags.stream().map(CustomTag::getName).map(MarkdownUtil::monospace).collect(Collectors.joining(", ")); + String tagList = tags + .stream() + .map(CustomTag::getName) + .map(MarkdownUtil::monospace) + .collect(Collectors.joining(", ")); Responses.info(event.getHook(), "Custom Tag List", String.format(tagList.length() > 0 ? tagList : "No Custom Tags created yet.")).queue(); } catch (DataAccessException e) { ExceptionLogger.capture(e, TagListSubcommand.class.getSimpleName()); + Responses.error(event.getHook(), "An error occured trying to list tags").queue(); } }); return event.deferReply(false); diff --git a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagSearchSubcommand.java b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagSearchSubcommand.java new file mode 100644 index 000000000..9461dcac2 --- /dev/null +++ b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagSearchSubcommand.java @@ -0,0 +1,70 @@ +package net.discordjug.javabot.systems.staff_commands.tags.commands; + +import java.sql.SQLException; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.stream.Collectors; + +import net.discordjug.javabot.data.config.BotConfig; +import net.discordjug.javabot.systems.staff_commands.tags.dao.CustomTagRepository; +import net.discordjug.javabot.systems.staff_commands.tags.model.CustomTag; +import net.discordjug.javabot.util.ExceptionLogger; +import net.discordjug.javabot.util.Responses; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction; +import net.dv8tion.jda.api.utils.MarkdownUtil; +import org.jetbrains.annotations.NotNull; +import org.springframework.dao.DataAccessException; + +/** + * The /tag search command which lists all tags matching a query. + */ +public class TagSearchSubcommand extends TagsSubcommand { + + private final ExecutorService asyncPool; + private final CustomTagRepository customTagRepository; + + /** + * The constructor of this class, which sets the corresponding {@link net.dv8tion.jda.api.interactions.commands.build.SlashCommandData}. + * @param botConfig The main configuration of the bot. + * @param asyncPool Thread pool for asynchronous operations. + * @param customTagRepository The repository for accessing tags in the database. + */ + public TagSearchSubcommand(BotConfig botConfig, ExecutorService asyncPool, CustomTagRepository customTagRepository) { + super(botConfig); + this.asyncPool = asyncPool; + this.customTagRepository = customTagRepository; + setCommandData( + new SubcommandData("search", "Searches for tags using a query") + .addOption(OptionType.STRING, "query", "The search query", true)); + setRequiredStaff(false); + } + + @Override + protected InteractionCallbackAction handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event) + throws SQLException { + + String query = event.getOption("query", "", OptionMapping::getAsString); + + asyncPool.execute(()->{ + try { + List tags = customTagRepository.search(event.getGuild().getIdLong(), query); + String tagList = tags + .stream() + .map(CustomTag::getName) + .map(MarkdownUtil::monospace) + .collect(Collectors.joining(", ")); + Responses.info(event.getHook(), "Custom tags containing \"" + query + "\"", + String.format(tagList.length() > 0 ? tagList : "No Custom Tags have been found.")).queue(); + } catch (DataAccessException e) { + ExceptionLogger.capture(e, TagListSubcommand.class.getSimpleName()); + Responses.error(event.getHook(), "An error occured trying to search for tags").queue(); + } + }); + return event.deferReply(false); + } + +} diff --git a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagViewSubcommand.java b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagViewSubcommand.java index d6c0304d0..a961c85e2 100644 --- a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagViewSubcommand.java +++ b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagViewSubcommand.java @@ -11,14 +11,14 @@ import net.dv8tion.jda.api.interactions.commands.OptionMapping; import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; -import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; +import net.dv8tion.jda.api.requests.RestAction; import org.jetbrains.annotations.NotNull; import java.util.Optional; /** - *

This class represents the /tag command.

+ *

This class represents the /tag view command.

*/ public class TagViewSubcommand extends TagsSubcommand implements AutoCompletable { private final CustomTagManager tagManager; @@ -38,18 +38,17 @@ public TagViewSubcommand(CustomTagManager tagManager, BotConfig botConfig) { } @Override - public ReplyCallbackAction handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event) { + public RestAction handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event) { OptionMapping nameMapping = event.getOption("name"); if (nameMapping == null) { return Responses.replyMissingArguments(event); } Optional tagOptional = tagManager.getByName(event.getGuild().getIdLong(), nameMapping.getAsString()); if (tagOptional.isPresent()) { - CustomTagManager.handleCustomTag(event, tagOptional.get()).queue(); + return CustomTagManager.handleCustomTag(event, tagOptional.get()); } else { - Responses.error(event.getHook(), "Could not find Custom Tag with name `%s`.", nameMapping.getAsString()).queue(); + return Responses.error(event, "Could not find Custom Tag with name `%s`.", nameMapping.getAsString()); } - return event.deferReply(false); } @Override diff --git a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsCommand.java b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsCommand.java index 4cfe929b4..501e73d3b 100644 --- a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsCommand.java +++ b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsCommand.java @@ -13,11 +13,12 @@ public class TagsCommand extends SlashCommand { * adds the corresponding {@link net.dv8tion.jda.api.interactions.commands.Command.Subcommand}s. * @param tagViewSubcommand /tag view * @param tagListSubcommand /tag list + * @param tagSearchSubcommand /tag search */ - public TagsCommand(TagViewSubcommand tagViewSubcommand, TagListSubcommand tagListSubcommand) { + public TagsCommand(TagViewSubcommand tagViewSubcommand, TagListSubcommand tagListSubcommand, TagSearchSubcommand tagSearchSubcommand) { setCommandData(Commands.slash("tag", "Commands for interacting with Custom Tags.") .setGuildOnly(true) ); - addSubcommands(tagViewSubcommand, tagListSubcommand); + addSubcommands(tagViewSubcommand, tagListSubcommand, tagSearchSubcommand); } } \ No newline at end of file diff --git a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsSubcommand.java b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsSubcommand.java index 4b6703890..c2fadde10 100644 --- a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsSubcommand.java +++ b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/commands/TagsSubcommand.java @@ -8,7 +8,7 @@ import net.discordjug.javabot.util.ExceptionLogger; import net.discordjug.javabot.util.Responses; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction; +import net.dv8tion.jda.api.requests.RestAction; import org.jetbrains.annotations.NotNull; @@ -45,5 +45,5 @@ protected void setRequiredStaff(boolean requireStaff) { this.requireStaff = requireStaff; } - protected abstract InteractionCallbackAction handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event) throws SQLException; + protected abstract RestAction handleCustomTagsSubcommand(@NotNull SlashCommandInteractionEvent event) throws SQLException; } diff --git a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/dao/CustomTagRepository.java b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/dao/CustomTagRepository.java index b6521a74c..9c7f4bc11 100644 --- a/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/dao/CustomTagRepository.java +++ b/src/main/java/net/discordjug/javabot/systems/staff_commands/tags/dao/CustomTagRepository.java @@ -117,9 +117,23 @@ public Optional findById(long id) throws DataAccessException { * @return A List with all custom commands. */ public List getCustomTagsByGuildId(long guildId) { - return jdbcTemplate.query("SELECT * FROM custom_tags WHERE guild_id = ?", (rs, row)->this.read(rs), + return jdbcTemplate.query("SELECT * FROM custom_tags WHERE guild_id = ? ORDER BY name", (rs, row)->this.read(rs), guildId); } + + /** + * Gets all custom commands for the given guild matching a specified query. + * A tag matches the query if the name or reply contains the query. + * + * @param guildId The id of the guild. + * @param query The search query. + * @return A List with all custom commands. + */ + public List search(long guildId, String query) { + String enhancedQuery = "%" + query + "%"; + return jdbcTemplate.query("SELECT * FROM custom_tags WHERE guild_id = ? AND (name LIKE ? OR response LIKE ?) ORDER BY name", (rs, row)->this.read(rs), + guildId, enhancedQuery, enhancedQuery); + } /** * Reads the given {@link ResultSet} and constructs a new {@link CustomTag} object.