|
3 | 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 | | -import net.dv8tion.jda.api.entities.Message; |
7 | | -import net.dv8tion.jda.api.entities.MessageEmbed; |
8 | 6 | import net.dv8tion.jda.api.entities.Role; |
9 | | -import net.dv8tion.jda.api.entities.User; |
10 | 7 | import net.dv8tion.jda.api.entities.channel.ChannelType; |
| 8 | +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; |
11 | 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; |
12 | 12 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; |
| 13 | +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; |
13 | 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; |
14 | 18 | import net.javadiscord.javabot.data.config.BotConfig; |
15 | 19 | import net.javadiscord.javabot.data.config.GuildConfig; |
16 | 20 | import net.javadiscord.javabot.data.config.guild.HelpConfig; |
17 | 21 | import net.javadiscord.javabot.util.Pair; |
18 | 22 | import net.javadiscord.javabot.util.Responses; |
19 | 23 | import org.jetbrains.annotations.NotNull; |
20 | 24 | import xyz.dynxsty.dih4jda.interactions.commands.application.SlashCommand; |
| 25 | +import xyz.dynxsty.dih4jda.interactions.components.ButtonHandler; |
| 26 | +import xyz.dynxsty.dih4jda.util.ComponentIdBuilder; |
21 | 27 |
|
22 | | -import java.util.EnumSet; |
| 28 | +import java.awt.Color; |
| 29 | +import java.time.OffsetDateTime; |
23 | 30 | import java.util.List; |
24 | 31 | import java.util.Map; |
25 | 32 | import java.util.Set; |
26 | 33 | import java.util.concurrent.ConcurrentHashMap; |
27 | 34 | import java.util.concurrent.ScheduledExecutorService; |
28 | 35 | import java.util.concurrent.TimeUnit; |
| 36 | +import java.util.stream.Collectors; |
29 | 37 |
|
30 | 38 | /** |
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 |
|
@@ -74,23 +83,65 @@ public void execute(@NotNull SlashCommandInteractionEvent event) { |
74 | 83 | Responses.warning(event, "Sorry, but only the person who reserved this channel, or staff and helpers, may use this command.").queue(); |
75 | 84 | return; |
76 | 85 | } |
| 86 | + if (post.getTimeCreated().isAfter(OffsetDateTime.now().minusSeconds(config.getHelpConfig().getHelpPingTimeoutSeconds()))) { |
| 87 | + Responses.warning(event, "Sorry, this command cannot be used directly after a post has been created.").queue(); |
| 88 | + return; |
| 89 | + } |
77 | 90 | if (isHelpPingTimeoutElapsed(member.getIdLong(), config)) { |
78 | 91 | lastPingTimes.put(event.getMember().getIdLong(), new Pair<>(System.currentTimeMillis(), config.getGuild())); |
79 | | - Role role = config.getHelpConfig().getHelpPingRole(); |
80 | | - event.getChannel().sendMessage(role.getAsMention()) |
81 | | - .setAllowedMentions(EnumSet.of(Message.MentionType.ROLE)) |
82 | | - .setEmbeds(buildAuthorEmbed(event.getUser())) |
83 | | - .queue(); |
84 | | - event.replyFormat("Successfully pinged " + role.getAsMention()).setEphemeral(true).queue(); |
| 92 | + TextChannel notifChannel = config.getHelpConfig().getHelpNotificationChannel(); |
| 93 | + notifChannel.sendMessageEmbeds(new EmbedBuilder().setDescription(""" |
| 94 | + %s requested help in %s |
| 95 | + |
| 96 | + Tags: |
| 97 | + %s |
| 98 | + |
| 99 | + [Click to view](%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(createAcknowledgementButton()) |
| 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(); |
85 | 121 | } else { |
86 | 122 | Responses.warning(event, "Sorry, but you can only use this command occasionally. Please try again later.").queue(); |
87 | 123 | } |
88 | 124 | } |
89 | 125 |
|
90 | | - private @NotNull MessageEmbed buildAuthorEmbed(@NotNull User author) { |
91 | | - return new EmbedBuilder() |
92 | | - .setTitle("Requested by " + author.getAsTag()) |
93 | | - .build(); |
| 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 createAcknowledgementButton() { |
| 140 | + return Button.of(ButtonStyle.SECONDARY, ComponentIdBuilder.build("help-ping", "acknowledge"), "Mark as acknowledged"); |
| 141 | + } |
| 142 | + |
| 143 | + private Button createUndoAcknowledgementButton() { |
| 144 | + return Button.of(ButtonStyle.SECONDARY, ComponentIdBuilder.build("help-ping", "unacknowledge"), "Mark as unacknowledged"); |
94 | 145 | } |
95 | 146 |
|
96 | 147 | /** |
@@ -142,4 +193,53 @@ private void cleanTimeoutCache() { |
142 | 193 | lastPingTimes.remove(memberId); |
143 | 194 | } |
144 | 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 "acknowledge" -> |
| 202 | + acknowledgeChangeAction(event, true); |
| 203 | + case "unacknowledge" -> |
| 204 | + acknowledgeChangeAction(event, false); |
| 205 | + default -> event.reply("Unknown button").setEphemeral(true).queue(); |
| 206 | + } |
| 207 | + |
| 208 | + } |
| 209 | + |
| 210 | + private void acknowledgeChangeAction(ButtonInteractionEvent event, boolean acknowledged) { |
| 211 | + event.editMessageEmbeds( |
| 212 | + event.getMessage() |
| 213 | + .getEmbeds() |
| 214 | + .stream() |
| 215 | + .map(e->new EmbedBuilder(e) |
| 216 | + .setColor(acknowledged ? Color.GRAY : Color.YELLOW) |
| 217 | + .addField("marked as " + (acknowledged?"acknowledged":"needs help") + " by", |
| 218 | + event.getUser().getAsMention(), false)) |
| 219 | + .map(this::removeOldField) |
| 220 | + .map(EmbedBuilder::build) |
| 221 | + .toList()) |
| 222 | + .setActionRow(acknowledged?createUndoAcknowledgementButton():createAcknowledgementButton()) |
| 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 | + } |
145 | 245 | } |
0 commit comments