77import net .dv8tion .jda .api .entities .User ;
88import net .dv8tion .jda .api .entities .emoji .Emoji ;
99import net .dv8tion .jda .api .entities .emoji .EmojiUnion ;
10+ import net .dv8tion .jda .api .events .interaction .command .CommandAutoCompleteInteractionEvent ;
1011import net .dv8tion .jda .api .events .interaction .command .SlashCommandInteractionEvent ;
1112import net .dv8tion .jda .api .events .interaction .component .ButtonInteractionEvent ;
13+ import net .dv8tion .jda .api .interactions .AutoCompleteQuery ;
1214import net .dv8tion .jda .api .interactions .callbacks .IReplyCallback ;
15+ import net .dv8tion .jda .api .interactions .commands .Command ;
1316import net .dv8tion .jda .api .interactions .commands .OptionType ;
1417import net .dv8tion .jda .api .interactions .commands .build .OptionData ;
1518import net .dv8tion .jda .api .interactions .commands .build .SubcommandData ;
2427import org .togetherjava .tjbot .commands .SlashCommandAdapter ;
2528import org .togetherjava .tjbot .commands .utils .MessageUtils ;
2629import org .togetherjava .tjbot .commands .utils .Pagination ;
30+ import org .togetherjava .tjbot .commands .utils .StringDistances ;
2731import org .togetherjava .tjbot .db .Database ;
2832import org .togetherjava .tjbot .db .generated .tables .records .PendingRemindersRecord ;
2933
5458public final class ReminderCommand extends SlashCommandAdapter {
5559 private static final String COMMAND_NAME = "reminder" ;
5660 private static final String LIST_SUBCOMMAND = "list" ;
61+ private static final String CANCEL_COMMAND = "cancel" ;
62+ private static final String CANCEL_ALL_COMMAND = "cancle-all" ;
63+ private static final String CANCEL_REMINDER_OPTION = "reminder" ;
5764 static final String CREATE_SUBCOMMAND = "create" ;
5865 static final String TIME_AMOUNT_OPTION = "time-amount" ;
5966 static final String TIME_UNIT_OPTION = "time-unit" ;
@@ -94,6 +101,10 @@ public ReminderCommand(Database database) {
94101 getData ().addSubcommands (
95102 new SubcommandData (CREATE_SUBCOMMAND , "creates a reminder" ).addOptions (timeAmount ,
96103 timeUnit , content ),
104+ new SubcommandData (CANCEL_COMMAND , "cancels a pending reminder" ).addOption (
105+ OptionType .STRING , CANCEL_REMINDER_OPTION , "reminder to cancel" , true ,
106+ true ),
107+ new SubcommandData (CANCEL_ALL_COMMAND , "cancels all your pending reminders" ),
97108 new SubcommandData (LIST_SUBCOMMAND , "shows all your currently pending reminders" ));
98109
99110 this .database = database ;
@@ -103,6 +114,8 @@ public ReminderCommand(Database database) {
103114 public void onSlashCommand (SlashCommandInteractionEvent event ) {
104115 switch (event .getSubcommandName ()) {
105116 case CREATE_SUBCOMMAND -> handleCreateCommand (event );
117+ case CANCEL_COMMAND -> handleCancelCommand (event );
118+ case CANCEL_ALL_COMMAND -> handleCancelAllCommand (event );
106119 case LIST_SUBCOMMAND -> handleListCommand (event );
107120 default -> throw new AssertionError (
108121 "Unexpected Subcommand: " + event .getSubcommandName ());
@@ -127,6 +140,26 @@ public void onButtonClick(ButtonInteractionEvent event, List<String> args) {
127140 event .editMessage (MessageEditData .fromCreateData (message )).queue ();
128141 }
129142
143+ @ Override
144+ public void onAutoComplete (CommandAutoCompleteInteractionEvent event ) {
145+ AutoCompleteQuery focusedOption = event .getFocusedOption ();
146+
147+ if (!focusedOption .getName ().equals (CANCEL_REMINDER_OPTION )) {
148+ throw new IllegalArgumentException (
149+ "Unexpected option, was : " + focusedOption .getName ());
150+ }
151+
152+ List <String > pendingReminders = getPendingReminders (event .getGuild (), event .getUser ())
153+ .map (PendingRemindersRecord ::getContent );
154+ List <Command .Choice > choices = StringDistances
155+ .closeMatches (focusedOption .getValue (), pendingReminders , REMINDERS_PER_PAGE )
156+ .stream ()
157+ .map (content -> new Command .Choice (content , content ))
158+ .toList ();
159+
160+ event .replyChoices (choices ).queue ();
161+ }
162+
130163 private void handleCreateCommand (SlashCommandInteractionEvent event ) {
131164 int timeAmount = Math .toIntExact (event .getOption (TIME_AMOUNT_OPTION ).getAsLong ());
132165 String timeUnit = event .getOption (TIME_UNIT_OPTION ).getAsString ();
@@ -157,6 +190,25 @@ private void handleCreateCommand(SlashCommandInteractionEvent event) {
157190 .insert ());
158191 }
159192
193+ private void handleCancelCommand (SlashCommandInteractionEvent event ) {
194+ String content = event .getOption (CANCEL_REMINDER_OPTION ).getAsString ();
195+
196+ database .write (context -> context .delete (PENDING_REMINDERS )
197+ .where (PENDING_REMINDERS .CONTENT .eq (content )
198+ .and (PENDING_REMINDERS .AUTHOR_ID .eq (event .getUser ().getIdLong ())))
199+ .execute ());
200+
201+ event .reply ("Your reminder is canceled" ).setEphemeral (true ).queue ();
202+ }
203+
204+ private void handleCancelAllCommand (SlashCommandInteractionEvent event ) {
205+ database .write (context -> context .delete (PENDING_REMINDERS )
206+ .where (PENDING_REMINDERS .AUTHOR_ID .eq (event .getUser ().getIdLong ()))
207+ .execute ());
208+
209+ event .reply ("All your reminder are canceled" ).setEphemeral (true ).queue ();
210+ }
211+
160212 private void handleListCommand (SlashCommandInteractionEvent event ) {
161213 Result <PendingRemindersRecord > pendingReminders =
162214 getPendingReminders (event .getGuild (), event .getUser ());
0 commit comments