11package org .togetherjava .tjbot .commands .tags ;
22
33import net .dv8tion .jda .api .EmbedBuilder ;
4+ import net .dv8tion .jda .api .events .interaction .command .CommandAutoCompleteInteractionEvent ;
45import net .dv8tion .jda .api .events .interaction .command .SlashCommandInteractionEvent ;
6+ import net .dv8tion .jda .api .interactions .AutoCompleteQuery ;
7+ import net .dv8tion .jda .api .interactions .commands .Command ;
58import net .dv8tion .jda .api .interactions .commands .OptionMapping ;
69import net .dv8tion .jda .api .interactions .commands .OptionType ;
10+ import net .dv8tion .jda .api .interactions .commands .build .OptionData ;
711import net .dv8tion .jda .api .requests .restaction .interactions .ReplyCallbackAction ;
812
913import org .togetherjava .tjbot .commands .CommandVisibility ;
1014import org .togetherjava .tjbot .commands .SlashCommandAdapter ;
15+ import org .togetherjava .tjbot .commands .utils .StringDistances ;
1116
1217import java .time .Instant ;
13- import java .util .Objects ;
18+ import java .util .Collection ;
1419
1520/**
1621 * Implements the {@code /tag} command which lets the bot respond content of a tag that has been
2126 */
2227public final class TagCommand extends SlashCommandAdapter {
2328 private final TagSystem tagSystem ;
24-
29+ private static final int MAX_SUGGESTIONS = 5 ;
2530 static final String ID_OPTION = "id" ;
2631 static final String REPLY_TO_USER_OPTION = "reply-to" ;
2732
@@ -35,16 +40,16 @@ public TagCommand(TagSystem tagSystem) {
3540
3641 this .tagSystem = tagSystem ;
3742
38- // TODO Think about adding an ephemeral selection menu with pagination support
39- // if the user calls this without id or similar
40- getData (). addOption ( OptionType . STRING , ID_OPTION , "The id of the tag to display" , true )
41- . addOption (OptionType .USER , REPLY_TO_USER_OPTION ,
42- "Optionally, the user who you want to reply to" , false );
43+ getData (). addOptions (
44+ new OptionData ( OptionType . STRING , ID_OPTION , "The id of the tag to display" , true ,
45+ true ),
46+ new OptionData (OptionType .USER , REPLY_TO_USER_OPTION ,
47+ "Optionally, the user who you want to reply to" , false ) );
4348 }
4449
4550 @ Override
4651 public void onSlashCommand (SlashCommandInteractionEvent event ) {
47- String id = Objects . requireNonNull ( event .getOption (ID_OPTION ) ).getAsString ();
52+ String id = event .getOption (ID_OPTION ).getAsString ();
4853 OptionMapping replyToUserOption = event .getOption (REPLY_TO_USER_OPTION );
4954
5055 if (tagSystem .handleIsUnknownTag (id , event )) {
@@ -63,4 +68,22 @@ public void onSlashCommand(SlashCommandInteractionEvent event) {
6368 }
6469 message .queue ();
6570 }
71+
72+ @ Override
73+ public void onAutoComplete (CommandAutoCompleteInteractionEvent event ) {
74+ AutoCompleteQuery focusedOption = event .getFocusedOption ();
75+
76+ if (!focusedOption .getName ().equals (ID_OPTION )) {
77+ throw new IllegalArgumentException (
78+ "Unexpected option, was: " + focusedOption .getName ());
79+ }
80+
81+ Collection <Command .Choice > choices = StringDistances
82+ .closeMatches (focusedOption .getValue (), tagSystem .getAllIds (), MAX_SUGGESTIONS )
83+ .stream ()
84+ .map (id -> new Command .Choice (id , id ))
85+ .toList ();
86+
87+ event .replyChoices (choices ).queue ();
88+ }
6689}
0 commit comments