|
1 | 1 | package net.javadiscord.javabot.systems.help.commands; |
2 | 2 |
|
3 | | -import net.dv8tion.jda.api.OnlineStatus; |
| 3 | +import net.dv8tion.jda.api.EmbedBuilder; |
4 | 4 | import net.dv8tion.jda.api.entities.Guild; |
5 | 5 | import net.dv8tion.jda.api.entities.Member; |
6 | 6 | import net.dv8tion.jda.api.entities.Role; |
7 | 7 | import net.dv8tion.jda.api.entities.channel.ChannelType; |
| 8 | +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; |
8 | 9 | import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; |
| 10 | +import net.dv8tion.jda.api.entities.channel.forums.ForumTag; |
| 11 | +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; |
9 | 12 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; |
| 13 | +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; |
10 | 14 | import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; |
| 15 | +import net.dv8tion.jda.api.interactions.components.buttons.Button; |
| 16 | +import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; |
| 17 | +import net.javadiscord.javabot.annotations.AutoDetectableComponentHandler; |
11 | 18 | import net.javadiscord.javabot.data.config.BotConfig; |
12 | 19 | import net.javadiscord.javabot.data.config.GuildConfig; |
13 | 20 | import net.javadiscord.javabot.data.config.guild.HelpConfig; |
14 | | -import net.javadiscord.javabot.util.ExceptionLogger; |
15 | 21 | import net.javadiscord.javabot.util.Pair; |
16 | 22 | import net.javadiscord.javabot.util.Responses; |
17 | 23 | import org.jetbrains.annotations.NotNull; |
18 | 24 | import xyz.dynxsty.dih4jda.interactions.commands.application.SlashCommand; |
| 25 | +import xyz.dynxsty.dih4jda.interactions.components.ButtonHandler; |
| 26 | +import xyz.dynxsty.dih4jda.util.ComponentIdBuilder; |
19 | 27 |
|
| 28 | +import java.awt.Color; |
20 | 29 | import java.time.OffsetDateTime; |
21 | | -import java.util.Collections; |
22 | 30 | import java.util.List; |
23 | 31 | import java.util.Map; |
24 | 32 | import java.util.Set; |
|
31 | 39 | * Handler for the /help ping sub-command that allows users to occasionally ping |
32 | 40 | * helpers. |
33 | 41 | */ |
34 | | -public class HelpPingSubcommand extends SlashCommand.Subcommand { |
| 42 | +@AutoDetectableComponentHandler("help-ping") |
| 43 | +public class HelpPingSubcommand extends SlashCommand.Subcommand implements ButtonHandler { |
35 | 44 | private static final String WRONG_CHANNEL_MSG = "This command can only be used in **help forum posts**"; |
36 | 45 | private static final long CACHE_CLEANUP_DELAY = 60L; |
37 | 46 |
|
@@ -80,38 +89,61 @@ public void execute(@NotNull SlashCommandInteractionEvent event) { |
80 | 89 | } |
81 | 90 | if (isHelpPingTimeoutElapsed(member.getIdLong(), config)) { |
82 | 91 | lastPingTimes.put(event.getMember().getIdLong(), new Pair<>(System.currentTimeMillis(), config.getGuild())); |
83 | | - Role role = config.getHelpConfig().getHelpPingRole(); |
84 | | - role.getGuild().findMembersWithRoles(role).onSuccess(members->{ |
85 | | - post.retrieveThreadMembers().queue(threadMembers -> { |
86 | | - Set<Long> memberIds = threadMembers |
87 | | - .stream() |
88 | | - .map(m->m.getIdLong()) |
89 | | - .collect(Collectors.toSet()); |
90 | | - members.removeIf(m -> |
91 | | - m.getOnlineStatus() == OnlineStatus.OFFLINE || |
92 | | - memberIds.contains(m.getIdLong())); |
93 | | - Collections.shuffle(members); |
94 | | - if(members.size()>0) { |
95 | | - post.addThreadMember(members.get(0)).queue(); |
96 | | - event.getHook().sendMessage("Successfully added a user with the help-ping role to the post.").queue(); |
97 | | - }else { |
98 | | - event.getHook().sendMessage("Unfortunately, no available member with the help-ping role has been found.").queue(); |
99 | | - } |
100 | | - }, err -> { |
101 | | - event.getHook().sendMessage("An error occured trying to find available members").queue(); |
102 | | - ExceptionLogger.capture(err, HelpPingSubcommand.class.getName()); |
103 | | - }); |
104 | | - |
105 | | - }).onError(err -> { |
106 | | - event.getHook().sendMessage("An error occured trying to find available members").queue(); |
107 | | - ExceptionLogger.capture(err, HelpPingSubcommand.class.getName()); |
108 | | - }); |
109 | | - event.deferReply(false).queue(); |
| 92 | + TextChannel notifChannel = config.getHelpConfig().getHelpNotificationChannel(); |
| 93 | + notifChannel.sendMessageEmbeds(new EmbedBuilder().setDescription(""" |
| 94 | + %s requested help in post %s |
| 95 | + |
| 96 | + Tags: |
| 97 | + %s |
| 98 | + |
| 99 | + [Post link](%s) |
| 100 | + """ |
| 101 | + .formatted( |
| 102 | + event.getUser().getAsMention(), |
| 103 | + post.getAsMention(), |
| 104 | + getTagString(post), |
| 105 | + post.getJumpUrl() |
| 106 | + )) |
| 107 | + .setAuthor(member.getEffectiveName(), null, member.getEffectiveAvatarUrl()) |
| 108 | + .setFooter(event.getUser().getId()) |
| 109 | + .setColor(Color.YELLOW) |
| 110 | + .build()) |
| 111 | + .addActionRow(createResolveButton()) |
| 112 | + .queue(); |
| 113 | + event.reply(""" |
| 114 | + Successfully requested help. |
| 115 | + |
| 116 | + Note that this does NOT gurantee that anybody here has the time and knowledge to help you. |
| 117 | + Abusing this command might result in moderative action taken against you. |
| 118 | + """) |
| 119 | + .setEphemeral(true) |
| 120 | + .queue(); |
110 | 121 | } else { |
111 | 122 | Responses.warning(event, "Sorry, but you can only use this command occasionally. Please try again later.").queue(); |
112 | 123 | } |
113 | 124 | } |
114 | 125 |
|
| 126 | + private String getTagString(ThreadChannel post) { |
| 127 | + String text = post |
| 128 | + .getAppliedTags() |
| 129 | + .stream() |
| 130 | + .map(this::getForumTagText) |
| 131 | + .map(tag -> "- " + tag) |
| 132 | + .collect(Collectors.joining("\n")); |
| 133 | + if(text.isEmpty()) { |
| 134 | + text = "- <no tags>"; |
| 135 | + } |
| 136 | + return text; |
| 137 | + } |
| 138 | + |
| 139 | + private Button createResolveButton() { |
| 140 | + return Button.of(ButtonStyle.SECONDARY, ComponentIdBuilder.build("help-ping", "resolve"), "Mark as resolved"); |
| 141 | + } |
| 142 | + |
| 143 | + private Button createUnresolveButton() { |
| 144 | + return Button.of(ButtonStyle.SECONDARY, ComponentIdBuilder.build("help-ping", "unresolve"), "Mark as unresolved"); |
| 145 | + } |
| 146 | + |
115 | 147 | /** |
116 | 148 | * Determines if a user is forbidden from sending a help-ping command due |
117 | 149 | * to their status in the server. |
@@ -161,4 +193,53 @@ private void cleanTimeoutCache() { |
161 | 193 | lastPingTimes.remove(memberId); |
162 | 194 | } |
163 | 195 | } |
| 196 | + |
| 197 | + @Override |
| 198 | + public void handleButton(ButtonInteractionEvent event, Button button) { |
| 199 | + String[] id = ComponentIdBuilder.split(event.getComponentId()); |
| 200 | + switch(id[1]) { |
| 201 | + case "resolve" -> |
| 202 | + resolveAction(event, true); |
| 203 | + case "unresolve" -> |
| 204 | + resolveAction(event, false); |
| 205 | + default -> event.reply("Unknown button").setEphemeral(true).queue(); |
| 206 | + } |
| 207 | + |
| 208 | + } |
| 209 | + |
| 210 | + private void resolveAction(ButtonInteractionEvent event, boolean resolved) { |
| 211 | + event.editMessageEmbeds( |
| 212 | + event.getMessage() |
| 213 | + .getEmbeds() |
| 214 | + .stream() |
| 215 | + .map(e->new EmbedBuilder(e) |
| 216 | + .setColor(resolved ? Color.GREEN : Color.YELLOW) |
| 217 | + .addField("marked as " + (resolved?"resolved":"unresolved") + " by", |
| 218 | + event.getUser().getAsMention(), false)) |
| 219 | + .map(this::removeOldField) |
| 220 | + .map(EmbedBuilder::build) |
| 221 | + .toList()) |
| 222 | + .setActionRow(resolved?createUnresolveButton():createResolveButton()) |
| 223 | + .queue(); |
| 224 | + } |
| 225 | + |
| 226 | + private String getForumTagText(ForumTag tag) { |
| 227 | + EmojiUnion emoji = tag.getEmoji(); |
| 228 | + StringBuilder sb=new StringBuilder(); |
| 229 | + if(emoji!=null) { |
| 230 | + sb |
| 231 | + .append(emoji.getFormatted()) |
| 232 | + .append(" "); |
| 233 | + } |
| 234 | + sb.append(tag.getName()); |
| 235 | + |
| 236 | + return sb.toString(); |
| 237 | + } |
| 238 | + |
| 239 | + private EmbedBuilder removeOldField(EmbedBuilder eb) { |
| 240 | + if(eb.getFields().size()>5) { |
| 241 | + eb.getFields().remove(0); |
| 242 | + } |
| 243 | + return eb; |
| 244 | + } |
164 | 245 | } |
0 commit comments