|
3 | 3 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; |
4 | 4 | import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; |
5 | 5 | import net.dv8tion.jda.api.events.interaction.component.SelectMenuInteractionEvent; |
| 6 | +import net.dv8tion.jda.api.interactions.commands.CommandInteractionPayload; |
| 7 | +import net.dv8tion.jda.api.interactions.commands.OptionMapping; |
6 | 8 | import net.dv8tion.jda.api.interactions.commands.build.CommandData; |
7 | 9 | import net.dv8tion.jda.api.interactions.commands.build.Commands; |
| 10 | +import net.dv8tion.jda.api.interactions.commands.build.OptionData; |
8 | 11 | import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; |
9 | 12 | import org.jetbrains.annotations.NotNull; |
| 13 | +import org.jetbrains.annotations.Range; |
| 14 | +import org.jetbrains.annotations.Unmodifiable; |
10 | 15 | import org.togetherjava.tjbot.commands.componentids.ComponentId; |
11 | 16 | import org.togetherjava.tjbot.commands.componentids.ComponentIdGenerator; |
12 | 17 | import org.togetherjava.tjbot.commands.componentids.Lifespan; |
13 | 18 |
|
14 | 19 | import java.util.Arrays; |
15 | 20 | import java.util.List; |
16 | 21 | import java.util.Objects; |
| 22 | +import java.util.function.Function; |
| 23 | +import java.util.stream.IntStream; |
17 | 24 |
|
18 | 25 | /** |
19 | 26 | * Adapter implementation of a {@link SlashCommand}. The minimal setup only requires implementation |
@@ -68,9 +75,9 @@ public abstract class SlashCommandAdapter implements SlashCommand { |
68 | 75 | * Creates a new adapter with the given data. |
69 | 76 | * |
70 | 77 | * @param name the name of this command, requirements for this are documented in |
71 | | - * {@link CommandData#CommandData(String, String)} |
| 78 | + * {@link SlashCommandData#setName(String)} |
72 | 79 | * @param description the description of this command, requirements for this are documented in |
73 | | - * {@link CommandData#CommandData(String, String)} |
| 80 | + * {@link SlashCommandData#setDescription(String)} |
74 | 81 | * @param visibility the visibility of the command |
75 | 82 | */ |
76 | 83 | protected SlashCommandAdapter(@NotNull String name, @NotNull String description, |
@@ -157,4 +164,58 @@ public void onSelectionMenu(@NotNull SelectMenuInteractionEvent event, |
157 | 164 | return Objects.requireNonNull(componentIdGenerator) |
158 | 165 | .generate(new ComponentId(getName(), Arrays.asList(args)), lifespan); |
159 | 166 | } |
| 167 | + |
| 168 | + /** |
| 169 | + * Copies the given option multiple times. |
| 170 | + * <p> |
| 171 | + * The generated options are all not required (optional) and have ascending number suffixes on |
| 172 | + * their name. For example, if the name of the given option is {@code "foo"}, calling this with |
| 173 | + * an amount of {@code 5} would result in a list of options like: |
| 174 | + * <ul> |
| 175 | + * <li>{@code "foo1"}</li> |
| 176 | + * <li>{@code "foo2"}</li> |
| 177 | + * <li>{@code "foo3"}</li> |
| 178 | + * <li>{@code "foo4"}</li> |
| 179 | + * <li>{@code "foo5"}</li> |
| 180 | + * </ul> |
| 181 | + * <p> |
| 182 | + * This can be useful to offer a variable amount of input options for a user, similar to |
| 183 | + * <i>varargs</i>. |
| 184 | + * <p> |
| 185 | + * After generation, the user input can conveniently be parsed back using |
| 186 | + * {@link #getMultipleOptionsByNamePrefix(CommandInteractionPayload, String)}. |
| 187 | + * |
| 188 | + * @param optionData the original option to copy |
| 189 | + * @param amount how often to copy the option |
| 190 | + * @return the generated list of options |
| 191 | + */ |
| 192 | + @Unmodifiable |
| 193 | + protected static @NotNull List<OptionData> generateMultipleOptions( |
| 194 | + @NotNull OptionData optionData, @Range(from = 1, to = 25) int amount) { |
| 195 | + String baseName = optionData.getName(); |
| 196 | + |
| 197 | + Function<String, OptionData> nameToOption = |
| 198 | + name -> new OptionData(optionData.getType(), name, optionData.getDescription()); |
| 199 | + |
| 200 | + return IntStream.rangeClosed(1, amount) |
| 201 | + .mapToObj(i -> baseName + i) |
| 202 | + .map(nameToOption) |
| 203 | + .toList(); |
| 204 | + } |
| 205 | + |
| 206 | + /** |
| 207 | + * Gets all options from the given event whose name start with the given prefix. |
| 208 | + * |
| 209 | + * @param event the event to extract options from |
| 210 | + * @param namePrefix the name prefix to search for |
| 211 | + * @return all options with the given prefix |
| 212 | + */ |
| 213 | + @Unmodifiable |
| 214 | + protected static @NotNull List<OptionMapping> getMultipleOptionsByNamePrefix( |
| 215 | + @NotNull CommandInteractionPayload event, @NotNull String namePrefix) { |
| 216 | + return event.getOptions() |
| 217 | + .stream() |
| 218 | + .filter(option -> option.getName().startsWith(namePrefix)) |
| 219 | + .toList(); |
| 220 | + } |
160 | 221 | } |
0 commit comments