From 774dbfd87a60fa1407cba93363f40041a8c098ff Mon Sep 17 00:00:00 2001 From: Taz03 Date: Wed, 19 Oct 2022 12:39:39 +0530 Subject: [PATCH 01/27] added subcommands --- .../commands/reminder/RemindCommand.java | 22 ++++++++++++++++--- .../commands/reminder/RemindCommandTest.java | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java index 97ab7d02cd..375a52055d 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java @@ -8,6 +8,7 @@ import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; import org.togetherjava.tjbot.commands.CommandVisibility; import org.togetherjava.tjbot.commands.SlashCommandAdapter; import org.togetherjava.tjbot.db.Database; @@ -15,6 +16,8 @@ import java.time.*; import java.time.temporal.TemporalAmount; import java.util.List; +import java.util.Map; +import java.util.function.Consumer; import static org.togetherjava.tjbot.db.generated.Tables.PENDING_REMINDERS; @@ -33,7 +36,9 @@ * Pending reminders are processed and send by {@link RemindRoutine}. */ public final class RemindCommand extends SlashCommandAdapter { - private static final String COMMAND_NAME = "remind"; + private static final String COMMAND_NAME = "reminder"; + private static final String LIST_SUBCOMMAND = "list"; + static final String ADD_SUBCOMMAND = "add"; static final String TIME_AMOUNT_OPTION = "time-amount"; static final String TIME_UNIT_OPTION = "time-unit"; static final String CONTENT_OPTION = "content"; @@ -46,6 +51,7 @@ public final class RemindCommand extends SlashCommandAdapter { static final int MAX_PENDING_REMINDERS_PER_USER = 100; private final Database database; + private final Map> subcommandHandler = Map.of(ADD_SUBCOMMAND, this::handleAddCommand, LIST_SUBCOMMAND, this::handleListCommand); /** * Creates an instance of the command. @@ -65,14 +71,20 @@ public RemindCommand(Database database) { "period to remind you in, the unit of time (e.g. 5 [weeks])", true); TIME_UNITS.forEach(unit -> timeUnit.addChoice(unit, unit)); - getData().addOptions(timeUnit, timeAmount) - .addOption(OptionType.STRING, CONTENT_OPTION, "what to remind you about", true); + getData().addSubcommands( + new SubcommandData(ADD_SUBCOMMAND, "adds a reminder").addOptions(timeAmount, timeUnit), + new SubcommandData(LIST_SUBCOMMAND, "lists all reminders") + ); this.database = database; } @Override public void onSlashCommand(SlashCommandInteractionEvent event) { + subcommandHandler.get(event.getSubcommandName()).accept(event); + } + + private void handleAddCommand(SlashCommandInteractionEvent event) { int timeAmount = Math.toIntExact(event.getOption(TIME_AMOUNT_OPTION).getAsLong()); String timeUnit = event.getOption(TIME_UNIT_OPTION).getAsString(); String content = event.getOption(CONTENT_OPTION).getAsString(); @@ -102,6 +114,10 @@ public void onSlashCommand(SlashCommandInteractionEvent event) { .insert()); } + private void handleListCommand(SlashCommandInteractionEvent event) { + + } + private static Instant parseWhen(int whenAmount, String whenUnit) { TemporalAmount period = switch (whenUnit) { case "second", "seconds" -> Duration.ofSeconds(whenAmount); diff --git a/application/src/test/java/org/togetherjava/tjbot/commands/reminder/RemindCommandTest.java b/application/src/test/java/org/togetherjava/tjbot/commands/reminder/RemindCommandTest.java index 9867efb6b0..cc0ea70c07 100644 --- a/application/src/test/java/org/togetherjava/tjbot/commands/reminder/RemindCommandTest.java +++ b/application/src/test/java/org/togetherjava/tjbot/commands/reminder/RemindCommandTest.java @@ -43,6 +43,7 @@ private SlashCommandInteractionEvent triggerSlashCommand(int timeAmount, String private SlashCommandInteractionEvent triggerSlashCommand(int timeAmount, String timeUnit, String content, Member author) { SlashCommandInteractionEvent event = jdaTester.createSlashCommandInteractionEvent(command) + .setSubcommand(RemindCommand.ADD_SUBCOMMAND) .setOption(RemindCommand.TIME_AMOUNT_OPTION, timeAmount) .setOption(RemindCommand.TIME_UNIT_OPTION, timeUnit) .setOption(RemindCommand.CONTENT_OPTION, content) From 2d19690709440e5eb7ccb901a8b7ec2ce6b1d169 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Thu, 20 Oct 2022 14:49:49 +0530 Subject: [PATCH 02/27] reading db --- .../tjbot/commands/reminder/RemindCommand.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java index 375a52055d..6f0f22be28 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java @@ -9,9 +9,12 @@ import net.dv8tion.jda.api.interactions.commands.build.OptionData; import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import org.jooq.Result; +import org.jooq.SelectWhereStep; import org.togetherjava.tjbot.commands.CommandVisibility; import org.togetherjava.tjbot.commands.SlashCommandAdapter; import org.togetherjava.tjbot.db.Database; +import org.togetherjava.tjbot.db.generated.tables.records.PendingRemindersRecord; import java.time.*; import java.time.temporal.TemporalAmount; @@ -72,7 +75,7 @@ public RemindCommand(Database database) { TIME_UNITS.forEach(unit -> timeUnit.addChoice(unit, unit)); getData().addSubcommands( - new SubcommandData(ADD_SUBCOMMAND, "adds a reminder").addOptions(timeAmount, timeUnit), + new SubcommandData(ADD_SUBCOMMAND, "adds a reminder").addOptions(timeAmount, timeUnit, new OptionData(OptionType.STRING, CONTENT_OPTION, "what to remind you about", true)), new SubcommandData(LIST_SUBCOMMAND, "lists all reminders") ); @@ -115,7 +118,15 @@ private void handleAddCommand(SlashCommandInteractionEvent event) { } private void handleListCommand(SlashCommandInteractionEvent event) { - + Result pendingReminders = database.read(context -> { + try (SelectWhereStep select = context.selectFrom(PENDING_REMINDERS)) { + return select.where(PENDING_REMINDERS.AUTHOR_ID.eq(event.getUser().getIdLong())).fetch(); + } + }); + + for (PendingRemindersRecord pendingReminder : pendingReminders) { + + } } private static Instant parseWhen(int whenAmount, String whenUnit) { From 8e7a9a0081563f2bf9e7a168ad49cb4d112ec1e4 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Sat, 22 Oct 2022 20:50:49 +0530 Subject: [PATCH 03/27] added reminder list --- .../togetherjava/tjbot/commands/Features.java | 4 +- .../commands/reminder/RemindRoutine.java | 4 +- ...emindCommand.java => ReminderCommand.java} | 43 +++++++++++++------ .../tjbot/commands/reminder/package-info.java | 2 +- ...mandTest.java => ReminderCommandTest.java} | 18 ++++---- 5 files changed, 43 insertions(+), 28 deletions(-) rename application/src/main/java/org/togetherjava/tjbot/commands/reminder/{RemindCommand.java => ReminderCommand.java} (82%) rename application/src/test/java/org/togetherjava/tjbot/commands/reminder/{RemindCommandTest.java => ReminderCommandTest.java} (90%) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/Features.java b/application/src/main/java/org/togetherjava/tjbot/commands/Features.java index 581296a77d..d6f08a617f 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/Features.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/Features.java @@ -17,8 +17,8 @@ import org.togetherjava.tjbot.commands.moderation.scam.ScamHistoryPurgeRoutine; import org.togetherjava.tjbot.commands.moderation.scam.ScamHistoryStore; import org.togetherjava.tjbot.commands.moderation.temp.TemporaryModerationRoutine; -import org.togetherjava.tjbot.commands.reminder.RemindCommand; import org.togetherjava.tjbot.commands.reminder.RemindRoutine; +import org.togetherjava.tjbot.commands.reminder.ReminderCommand; import org.togetherjava.tjbot.commands.system.BotCore; import org.togetherjava.tjbot.commands.system.LogLevelCommand; import org.togetherjava.tjbot.commands.tags.TagCommand; @@ -120,7 +120,7 @@ public static Collection createFeatures(JDA jda, Database database, Con features.add(new TopHelpersCommand(database)); features.add(new RoleSelectCommand()); features.add(new NoteCommand(actionsStore)); - features.add(new RemindCommand(database)); + features.add(new ReminderCommand(database)); features.add(new QuarantineCommand(actionsStore, config)); features.add(new UnquarantineCommand(actionsStore, config)); features.add(new WhoIsCommand()); diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindRoutine.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindRoutine.java index db09fe8ea4..b5bedd5906 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindRoutine.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindRoutine.java @@ -28,11 +28,11 @@ /** * Routine that processes and sends pending reminders. *

- * Reminders can be set by using {@link RemindCommand}. + * Reminders can be set by using {@link ReminderCommand}. */ public final class RemindRoutine implements Routine { static final Logger logger = LoggerFactory.getLogger(RemindRoutine.class); - private static final Color AMBIENT_COLOR = Color.decode("#F7F492"); + static final Color AMBIENT_COLOR = Color.decode("#F7F492"); private static final int SCHEDULE_INTERVAL_SECONDS = 30; private final Database database; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java similarity index 82% rename from application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java rename to application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index 6f0f22be28..8afcef5435 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/RemindCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -1,5 +1,6 @@ package org.togetherjava.tjbot.commands.reminder; +import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.ISnowflake; import net.dv8tion.jda.api.entities.User; @@ -7,19 +8,20 @@ import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.OptionData; - import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; -import org.jooq.Result; import org.jooq.SelectWhereStep; + import org.togetherjava.tjbot.commands.CommandVisibility; import org.togetherjava.tjbot.commands.SlashCommandAdapter; import org.togetherjava.tjbot.db.Database; import org.togetherjava.tjbot.db.generated.tables.records.PendingRemindersRecord; +import java.awt.*; import java.time.*; import java.time.temporal.TemporalAmount; import java.util.List; import java.util.Map; +import java.util.function.BiFunction; import java.util.function.Consumer; import static org.togetherjava.tjbot.db.generated.Tables.PENDING_REMINDERS; @@ -38,7 +40,7 @@ *

* Pending reminders are processed and send by {@link RemindRoutine}. */ -public final class RemindCommand extends SlashCommandAdapter { +public final class ReminderCommand extends SlashCommandAdapter { private static final String COMMAND_NAME = "reminder"; private static final String LIST_SUBCOMMAND = "list"; static final String ADD_SUBCOMMAND = "add"; @@ -54,14 +56,15 @@ public final class RemindCommand extends SlashCommandAdapter { static final int MAX_PENDING_REMINDERS_PER_USER = 100; private final Database database; - private final Map> subcommandHandler = Map.of(ADD_SUBCOMMAND, this::handleAddCommand, LIST_SUBCOMMAND, this::handleListCommand); + private final Map> subcommandHandler = Map + .of(ADD_SUBCOMMAND, this::handleAddCommand, LIST_SUBCOMMAND, this::handleListCommand); /** * Creates an instance of the command. * * @param database to store and fetch the reminders from */ - public RemindCommand(Database database) { + public ReminderCommand(Database database) { super(COMMAND_NAME, "Reminds you after a given time period has passed (e.g. in 5 weeks)", CommandVisibility.GUILD); @@ -75,9 +78,11 @@ public RemindCommand(Database database) { TIME_UNITS.forEach(unit -> timeUnit.addChoice(unit, unit)); getData().addSubcommands( - new SubcommandData(ADD_SUBCOMMAND, "adds a reminder").addOptions(timeAmount, timeUnit, new OptionData(OptionType.STRING, CONTENT_OPTION, "what to remind you about", true)), - new SubcommandData(LIST_SUBCOMMAND, "lists all reminders") - ); + new SubcommandData(ADD_SUBCOMMAND, "adds a reminder").addOptions(timeAmount, + timeUnit, + new OptionData(OptionType.STRING, CONTENT_OPTION, + "what to remind you about", true)), + new SubcommandData(LIST_SUBCOMMAND, "lists all reminders")); this.database = database; } @@ -118,15 +123,25 @@ private void handleAddCommand(SlashCommandInteractionEvent event) { } private void handleListCommand(SlashCommandInteractionEvent event) { - Result pendingReminders = database.read(context -> { - try (SelectWhereStep select = context.selectFrom(PENDING_REMINDERS)) { - return select.where(PENDING_REMINDERS.AUTHOR_ID.eq(event.getUser().getIdLong())).fetch(); + BiFunction getDescription = (channelId, remindAt) -> """ + Channel: <#%s> + Remind at: """.formatted(channelId, remindAt.getEpochSecond()); + + EmbedBuilder remindersEmbed = new EmbedBuilder().setTitle("Reminders").setColor(RemindRoutine.AMBIENT_COLOR); + + database.read(context -> { + try (SelectWhereStep select = + context.selectFrom(PENDING_REMINDERS)) { + return select + .where(PENDING_REMINDERS.GUILD_ID.eq(event.getGuild().getIdLong()) + .and(PENDING_REMINDERS.AUTHOR_ID.eq(event.getUser().getIdLong()))) + .fetch(); } + }).forEach(reminder -> { + remindersEmbed.addField(reminder.getContent(), getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), true); }); - for (PendingRemindersRecord pendingReminder : pendingReminders) { - - } + event.replyEmbeds(remindersEmbed.build()).setEphemeral(true).queue(); } private static Instant parseWhen(int whenAmount, String whenUnit) { diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/package-info.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/package-info.java index 5aafa9946f..482666ae56 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/package-info.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/package-info.java @@ -1,6 +1,6 @@ /** * This packages offers all the functionality for the remind-command. The core class is - * {@link org.togetherjava.tjbot.commands.reminder.RemindCommand}. + * {@link org.togetherjava.tjbot.commands.reminder.ReminderCommand}. */ @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault diff --git a/application/src/test/java/org/togetherjava/tjbot/commands/reminder/RemindCommandTest.java b/application/src/test/java/org/togetherjava/tjbot/commands/reminder/ReminderCommandTest.java similarity index 90% rename from application/src/test/java/org/togetherjava/tjbot/commands/reminder/RemindCommandTest.java rename to application/src/test/java/org/togetherjava/tjbot/commands/reminder/ReminderCommandTest.java index cc0ea70c07..09852c233a 100644 --- a/application/src/test/java/org/togetherjava/tjbot/commands/reminder/RemindCommandTest.java +++ b/application/src/test/java/org/togetherjava/tjbot/commands/reminder/ReminderCommandTest.java @@ -22,7 +22,7 @@ import static org.mockito.Mockito.verify; import static org.togetherjava.tjbot.db.generated.tables.PendingReminders.PENDING_REMINDERS; -final class RemindCommandTest { +final class ReminderCommandTest { private SlashCommand command; private JdaTester jdaTester; private RawReminderTestHelper rawReminders; @@ -30,7 +30,7 @@ final class RemindCommandTest { @BeforeEach void setUp() { Database database = Database.createMemoryDatabase(PENDING_REMINDERS); - command = new RemindCommand(database); + command = new ReminderCommand(database); jdaTester = new JdaTester(); rawReminders = new RawReminderTestHelper(database, jdaTester); } @@ -43,10 +43,10 @@ private SlashCommandInteractionEvent triggerSlashCommand(int timeAmount, String private SlashCommandInteractionEvent triggerSlashCommand(int timeAmount, String timeUnit, String content, Member author) { SlashCommandInteractionEvent event = jdaTester.createSlashCommandInteractionEvent(command) - .setSubcommand(RemindCommand.ADD_SUBCOMMAND) - .setOption(RemindCommand.TIME_AMOUNT_OPTION, timeAmount) - .setOption(RemindCommand.TIME_UNIT_OPTION, timeUnit) - .setOption(RemindCommand.CONTENT_OPTION, content) + .setSubcommand(ReminderCommand.ADD_SUBCOMMAND) + .setOption(ReminderCommand.TIME_AMOUNT_OPTION, timeAmount) + .setOption(ReminderCommand.TIME_UNIT_OPTION, timeUnit) + .setOption(ReminderCommand.CONTENT_OPTION, content) .setUserWhoTriggered(author) .build(); @@ -83,7 +83,7 @@ void doesNotSupportDatesTooFarInFuture() { void userIsLimitedIfTooManyPendingReminders() { // GIVEN a user with too many reminders still pending Instant remindAt = Instant.now().plus(100, ChronoUnit.DAYS); - for (int i = 0; i < RemindCommand.MAX_PENDING_REMINDERS_PER_USER; i++) { + for (int i = 0; i < ReminderCommand.MAX_PENDING_REMINDERS_PER_USER; i++) { rawReminders.insertReminder("foo " + i, remindAt); } @@ -93,7 +93,7 @@ void userIsLimitedIfTooManyPendingReminders() { // THEN rejects and responds accordingly, no new reminder was created verify(event) .reply(startsWith("You have reached the maximum amount of pending reminders per user")); - assertEquals(RemindCommand.MAX_PENDING_REMINDERS_PER_USER, + assertEquals(ReminderCommand.MAX_PENDING_REMINDERS_PER_USER, rawReminders.readReminders().size()); } @@ -104,7 +104,7 @@ void userIsNotLimitedIfOtherUserHasTooManyPendingReminders() { // and a second user with no reminders yet Member firstUser = jdaTester.createMemberSpy(1); Instant remindAt = Instant.now().plus(100, ChronoUnit.DAYS); - for (int i = 0; i < RemindCommand.MAX_PENDING_REMINDERS_PER_USER; i++) { + for (int i = 0; i < ReminderCommand.MAX_PENDING_REMINDERS_PER_USER; i++) { rawReminders.insertReminder("foo " + i, remindAt, firstUser); } From ba358aa00ca9f6b58106677094c1dc08acc1230e Mon Sep 17 00:00:00 2001 From: Taz03 Date: Sat, 22 Oct 2022 20:53:38 +0530 Subject: [PATCH 04/27] spotless --- .../tjbot/commands/reminder/ReminderCommand.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index 8afcef5435..7ccebf23dc 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -127,7 +127,8 @@ private void handleListCommand(SlashCommandInteractionEvent event) { Channel: <#%s> Remind at: """.formatted(channelId, remindAt.getEpochSecond()); - EmbedBuilder remindersEmbed = new EmbedBuilder().setTitle("Reminders").setColor(RemindRoutine.AMBIENT_COLOR); + EmbedBuilder remindersEmbed = + new EmbedBuilder().setTitle("Reminders").setColor(RemindRoutine.AMBIENT_COLOR); database.read(context -> { try (SelectWhereStep select = @@ -138,7 +139,8 @@ private void handleListCommand(SlashCommandInteractionEvent event) { .fetch(); } }).forEach(reminder -> { - remindersEmbed.addField(reminder.getContent(), getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), true); + remindersEmbed.addField(reminder.getContent(), + getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), true); }); event.replyEmbeds(remindersEmbed.build()).setEphemeral(true).queue(); From 2aa512d5d09df8ce33e8f76cf6813e060d620f5e Mon Sep 17 00:00:00 2001 From: Taz03 Date: Sat, 22 Oct 2022 21:00:42 +0530 Subject: [PATCH 05/27] code fixes --- .../tjbot/commands/reminder/ReminderCommand.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index 7ccebf23dc..49995fe56b 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -16,7 +16,6 @@ import org.togetherjava.tjbot.db.Database; import org.togetherjava.tjbot.db.generated.tables.records.PendingRemindersRecord; -import java.awt.*; import java.time.*; import java.time.temporal.TemporalAmount; import java.util.List; @@ -138,10 +137,9 @@ private void handleListCommand(SlashCommandInteractionEvent event) { .and(PENDING_REMINDERS.AUTHOR_ID.eq(event.getUser().getIdLong()))) .fetch(); } - }).forEach(reminder -> { - remindersEmbed.addField(reminder.getContent(), - getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), true); - }); + }) + .forEach(reminder -> remindersEmbed.addField(reminder.getContent(), + getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), true)); event.replyEmbeds(remindersEmbed.build()).setEphemeral(true).queue(); } From efec86d7cd6fb7632eac92362030cf3b422aa097 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Sat, 22 Oct 2022 21:26:53 +0530 Subject: [PATCH 06/27] not inline --- .../togetherjava/tjbot/commands/reminder/ReminderCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index 49995fe56b..efcd876a76 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -139,7 +139,7 @@ private void handleListCommand(SlashCommandInteractionEvent event) { } }) .forEach(reminder -> remindersEmbed.addField(reminder.getContent(), - getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), true)); + getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), false)); event.replyEmbeds(remindersEmbed.build()).setEphemeral(true).queue(); } From f7f20903843ec9f4ecc88cc75c2d7e82868f760e Mon Sep 17 00:00:00 2001 From: Taz03 Date: Mon, 24 Oct 2022 17:35:30 +0530 Subject: [PATCH 07/27] CR --- .../commands/reminder/ReminderCommand.java | 46 +++++++++---------- .../tjbot/commands/utils/MessageUtils.java | 3 ++ .../reminder/ReminderCommandTest.java | 2 +- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index efcd876a76..ed9e87c0b7 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -9,12 +9,12 @@ import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.OptionData; import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; -import org.jooq.SelectWhereStep; +import net.dv8tion.jda.api.utils.TimeFormat; import org.togetherjava.tjbot.commands.CommandVisibility; import org.togetherjava.tjbot.commands.SlashCommandAdapter; +import org.togetherjava.tjbot.commands.utils.MessageUtils; import org.togetherjava.tjbot.db.Database; -import org.togetherjava.tjbot.db.generated.tables.records.PendingRemindersRecord; import java.time.*; import java.time.temporal.TemporalAmount; @@ -26,14 +26,14 @@ import static org.togetherjava.tjbot.db.generated.Tables.PENDING_REMINDERS; /** - * Implements the '/remind' command which can be used to automatically send reminders to oneself at - * a future date. + * Implements the '/reminder' command which can be used to automatically send reminders to oneself + * at a future date. *

* Example usage: * *

  * {@code
- * /remind time-amount: 5 time-unit: weeks content: Hello World!
+ * /reminder create time-amount: 5 time-unit: weeks content: Hello World!
  * }
  * 
*

@@ -42,7 +42,7 @@ public final class ReminderCommand extends SlashCommandAdapter { private static final String COMMAND_NAME = "reminder"; private static final String LIST_SUBCOMMAND = "list"; - static final String ADD_SUBCOMMAND = "add"; + static final String CREATE_SUBCOMMAND = "create"; static final String TIME_AMOUNT_OPTION = "time-amount"; static final String TIME_UNIT_OPTION = "time-unit"; static final String CONTENT_OPTION = "content"; @@ -56,7 +56,7 @@ public final class ReminderCommand extends SlashCommandAdapter { private final Database database; private final Map> subcommandHandler = Map - .of(ADD_SUBCOMMAND, this::handleAddCommand, LIST_SUBCOMMAND, this::handleListCommand); + .of(CREATE_SUBCOMMAND, this::handleAddCommand, LIST_SUBCOMMAND, this::handleListCommand); /** * Creates an instance of the command. @@ -77,11 +77,11 @@ public ReminderCommand(Database database) { TIME_UNITS.forEach(unit -> timeUnit.addChoice(unit, unit)); getData().addSubcommands( - new SubcommandData(ADD_SUBCOMMAND, "adds a reminder").addOptions(timeAmount, + new SubcommandData(CREATE_SUBCOMMAND, "creates a reminder").addOptions(timeAmount, timeUnit, new OptionData(OptionType.STRING, CONTENT_OPTION, "what to remind you about", true)), - new SubcommandData(LIST_SUBCOMMAND, "lists all reminders")); + new SubcommandData(LIST_SUBCOMMAND, "shows all your currently pending reminders")); this.database = database; } @@ -123,21 +123,19 @@ private void handleAddCommand(SlashCommandInteractionEvent event) { private void handleListCommand(SlashCommandInteractionEvent event) { BiFunction getDescription = (channelId, remindAt) -> """ - Channel: <#%s> - Remind at: """.formatted(channelId, remindAt.getEpochSecond()); - - EmbedBuilder remindersEmbed = - new EmbedBuilder().setTitle("Reminders").setColor(RemindRoutine.AMBIENT_COLOR); - - database.read(context -> { - try (SelectWhereStep select = - context.selectFrom(PENDING_REMINDERS)) { - return select - .where(PENDING_REMINDERS.GUILD_ID.eq(event.getGuild().getIdLong()) - .and(PENDING_REMINDERS.AUTHOR_ID.eq(event.getUser().getIdLong()))) - .fetch(); - } - }) + Channel: %s + Remind at: %s""".formatted(MessageUtils.mentionChannelById(channelId), + TimeFormat.DEFAULT.format(remindAt)); + + EmbedBuilder remindersEmbed = new EmbedBuilder().setTitle("Pending reminders") + .setColor(RemindRoutine.AMBIENT_COLOR); + + database + .read(context -> context.selectFrom(PENDING_REMINDERS) + .where(PENDING_REMINDERS.GUILD_ID.eq(event.getGuild().getIdLong()) + .and(PENDING_REMINDERS.AUTHOR_ID.eq(event.getUser().getIdLong()))) + .fetch()) + .sortAsc(PENDING_REMINDERS.REMIND_AT) .forEach(reminder -> remindersEmbed.addField(reminder.getContent(), getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), false)); diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java index 4768006d75..1c1569ca28 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java @@ -109,4 +109,7 @@ public static String abbreviate(String text, int maxLength) { return text.substring(0, maxLength - ABBREVIATION.length()) + ABBREVIATION; } + public static String mentionChannelById(long channelId) { + return "<#%s>".formatted(channelId); + } } diff --git a/application/src/test/java/org/togetherjava/tjbot/commands/reminder/ReminderCommandTest.java b/application/src/test/java/org/togetherjava/tjbot/commands/reminder/ReminderCommandTest.java index 09852c233a..a628b1042a 100644 --- a/application/src/test/java/org/togetherjava/tjbot/commands/reminder/ReminderCommandTest.java +++ b/application/src/test/java/org/togetherjava/tjbot/commands/reminder/ReminderCommandTest.java @@ -43,7 +43,7 @@ private SlashCommandInteractionEvent triggerSlashCommand(int timeAmount, String private SlashCommandInteractionEvent triggerSlashCommand(int timeAmount, String timeUnit, String content, Member author) { SlashCommandInteractionEvent event = jdaTester.createSlashCommandInteractionEvent(command) - .setSubcommand(ReminderCommand.ADD_SUBCOMMAND) + .setSubcommand(ReminderCommand.CREATE_SUBCOMMAND) .setOption(ReminderCommand.TIME_AMOUNT_OPTION, timeAmount) .setOption(ReminderCommand.TIME_UNIT_OPTION, timeUnit) .setOption(ReminderCommand.CONTENT_OPTION, content) From 7cf93704d0bcdfdab9dcf3738964d2b649cd139e Mon Sep 17 00:00:00 2001 From: Taz03 Date: Mon, 24 Oct 2022 17:57:44 +0530 Subject: [PATCH 08/27] handled no pending reminders case --- .../togetherjava/tjbot/commands/reminder/ReminderCommand.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index ed9e87c0b7..24cd5d9bc1 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -139,6 +139,10 @@ private void handleListCommand(SlashCommandInteractionEvent event) { .forEach(reminder -> remindersEmbed.addField(reminder.getContent(), getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), false)); + if (remindersEmbed.getFields().isEmpty()) { + remindersEmbed.setDescription("No pending reminders"); + } + event.replyEmbeds(remindersEmbed.build()).setEphemeral(true).queue(); } From c76faf4fcec61b8429c07d730dc126742c47e6f0 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Mon, 24 Oct 2022 18:08:14 +0530 Subject: [PATCH 09/27] added java docs --- .../org/togetherjava/tjbot/commands/utils/MessageUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java index 1c1569ca28..b45dfa058a 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java @@ -109,6 +109,12 @@ public static String abbreviate(String text, int maxLength) { return text.substring(0, maxLength - ABBREVIATION.length()) + ABBREVIATION; } + /** + * Mentions a guild channel by its id + * + * @param channelId the channel id to mention + * @return channel mention + */ public static String mentionChannelById(long channelId) { return "<#%s>".formatted(channelId); } From 7a59051e77a281a27000c8a58ea48e30dc6e6589 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Mon, 24 Oct 2022 23:33:23 +0530 Subject: [PATCH 10/27] used orderBy instead of sorted --- .../togetherjava/tjbot/commands/reminder/ReminderCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index 24cd5d9bc1..af1f4bcff0 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -134,8 +134,8 @@ private void handleListCommand(SlashCommandInteractionEvent event) { .read(context -> context.selectFrom(PENDING_REMINDERS) .where(PENDING_REMINDERS.GUILD_ID.eq(event.getGuild().getIdLong()) .and(PENDING_REMINDERS.AUTHOR_ID.eq(event.getUser().getIdLong()))) + .orderBy(PENDING_REMINDERS.CREATED_AT.asc()) .fetch()) - .sortAsc(PENDING_REMINDERS.REMIND_AT) .forEach(reminder -> remindersEmbed.addField(reminder.getContent(), getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), false)); From c384ac9cf294bb8976f17eef6eb2fd43d2a70791 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Tue, 25 Oct 2022 12:08:27 +0530 Subject: [PATCH 11/27] CR --- .../commands/reminder/ReminderCommand.java | 26 +++++++++++-------- .../tjbot/commands/utils/MessageUtils.java | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index af1f4bcff0..8f0b14711a 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -19,9 +19,7 @@ import java.time.*; import java.time.temporal.TemporalAmount; import java.util.List; -import java.util.Map; import java.util.function.BiFunction; -import java.util.function.Consumer; import static org.togetherjava.tjbot.db.generated.Tables.PENDING_REMINDERS; @@ -55,8 +53,6 @@ public final class ReminderCommand extends SlashCommandAdapter { static final int MAX_PENDING_REMINDERS_PER_USER = 100; private final Database database; - private final Map> subcommandHandler = Map - .of(CREATE_SUBCOMMAND, this::handleAddCommand, LIST_SUBCOMMAND, this::handleListCommand); /** * Creates an instance of the command. @@ -74,13 +70,13 @@ public ReminderCommand(Database database) { .setRequiredRange(MIN_TIME_AMOUNT, MAX_TIME_AMOUNT); OptionData timeUnit = new OptionData(OptionType.STRING, TIME_UNIT_OPTION, "period to remind you in, the unit of time (e.g. 5 [weeks])", true); + OptionData content = + new OptionData(OptionType.STRING, CONTENT_OPTION, "what to remind you about", true); TIME_UNITS.forEach(unit -> timeUnit.addChoice(unit, unit)); getData().addSubcommands( new SubcommandData(CREATE_SUBCOMMAND, "creates a reminder").addOptions(timeAmount, - timeUnit, - new OptionData(OptionType.STRING, CONTENT_OPTION, - "what to remind you about", true)), + timeUnit, content), new SubcommandData(LIST_SUBCOMMAND, "shows all your currently pending reminders")); this.database = database; @@ -88,10 +84,15 @@ public ReminderCommand(Database database) { @Override public void onSlashCommand(SlashCommandInteractionEvent event) { - subcommandHandler.get(event.getSubcommandName()).accept(event); + switch (event.getSubcommandName()) { + case CREATE_SUBCOMMAND -> handleCreateCommand(event); + case LIST_SUBCOMMAND -> handleListCommand(event); + default -> throw new AssertionError( + "Unexpected Subcommand: " + event.getSubcommandName()); + } } - private void handleAddCommand(SlashCommandInteractionEvent event) { + private void handleCreateCommand(SlashCommandInteractionEvent event) { int timeAmount = Math.toIntExact(event.getOption(TIME_AMOUNT_OPTION).getAsLong()); String timeUnit = event.getOption(TIME_UNIT_OPTION).getAsString(); String content = event.getOption(CONTENT_OPTION).getAsString(); @@ -130,10 +131,13 @@ private void handleListCommand(SlashCommandInteractionEvent event) { EmbedBuilder remindersEmbed = new EmbedBuilder().setTitle("Pending reminders") .setColor(RemindRoutine.AMBIENT_COLOR); + long guildId = event.getGuild().getIdLong(); + long userId = event.getUser().getIdLong(); + database .read(context -> context.selectFrom(PENDING_REMINDERS) - .where(PENDING_REMINDERS.GUILD_ID.eq(event.getGuild().getIdLong()) - .and(PENDING_REMINDERS.AUTHOR_ID.eq(event.getUser().getIdLong()))) + .where(PENDING_REMINDERS.GUILD_ID.eq(guildId) + .and(PENDING_REMINDERS.AUTHOR_ID.eq(userId))) .orderBy(PENDING_REMINDERS.CREATED_AT.asc()) .fetch()) .forEach(reminder -> remindersEmbed.addField(reminder.getContent(), diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java index b45dfa058a..4e4e918d84 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java @@ -116,6 +116,6 @@ public static String abbreviate(String text, int maxLength) { * @return channel mention */ public static String mentionChannelById(long channelId) { - return "<#%s>".formatted(channelId); + return "<#%d>".formatted(channelId); } } From 3eda02d19672ff63b50e501d04298cec5fe18e89 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Tue, 25 Oct 2022 12:10:34 +0530 Subject: [PATCH 12/27] improved docs --- .../org/togetherjava/tjbot/commands/utils/MessageUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java index 4e4e918d84..32dde2d083 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java @@ -110,7 +110,8 @@ public static String abbreviate(String text, int maxLength) { } /** - * Mentions a guild channel by its id + * Mentions a guild channel by its id Clone of JDAs Channel#getAsMention, but unfortunately + * channel instances can not be created out of just an ID, unlike User#fromId * * @param channelId the channel id to mention * @return channel mention From 7ef1316ed9352a7914f3155a10682ea3bf0ab804 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Tue, 25 Oct 2022 12:12:19 +0530 Subject: [PATCH 13/27] improved docs --- .../org/togetherjava/tjbot/commands/utils/MessageUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java index 32dde2d083..a8ae9e47f2 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java @@ -113,8 +113,8 @@ public static String abbreviate(String text, int maxLength) { * Mentions a guild channel by its id Clone of JDAs Channel#getAsMention, but unfortunately * channel instances can not be created out of just an ID, unlike User#fromId * - * @param channelId the channel id to mention - * @return channel mention + * @param channelId the ID of the channel to mention + * @return the channel as formatted string which Discord interprets as clickable mention */ public static String mentionChannelById(long channelId) { return "<#%d>".formatted(channelId); From 08ffca339cb780ab36fa0a78950539b9b7ccd248 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Wed, 26 Oct 2022 09:21:52 +0530 Subject: [PATCH 14/27] CR --- .../commands/reminder/ReminderCommand.java | 29 +++++++++++++------ .../tjbot/commands/utils/MessageUtils.java | 5 ++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index 8f0b14711a..5f78568a8d 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -10,11 +10,13 @@ import net.dv8tion.jda.api.interactions.commands.build.OptionData; import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; import net.dv8tion.jda.api.utils.TimeFormat; +import org.jooq.Result; import org.togetherjava.tjbot.commands.CommandVisibility; import org.togetherjava.tjbot.commands.SlashCommandAdapter; import org.togetherjava.tjbot.commands.utils.MessageUtils; import org.togetherjava.tjbot.db.Database; +import org.togetherjava.tjbot.db.generated.tables.records.PendingRemindersRecord; import java.time.*; import java.time.temporal.TemporalAmount; @@ -134,22 +136,31 @@ private void handleListCommand(SlashCommandInteractionEvent event) { long guildId = event.getGuild().getIdLong(); long userId = event.getUser().getIdLong(); - database - .read(context -> context.selectFrom(PENDING_REMINDERS) - .where(PENDING_REMINDERS.GUILD_ID.eq(guildId) - .and(PENDING_REMINDERS.AUTHOR_ID.eq(userId))) - .orderBy(PENDING_REMINDERS.CREATED_AT.asc()) - .fetch()) - .forEach(reminder -> remindersEmbed.addField(reminder.getContent(), - getDescription.apply(reminder.getChannelId(), reminder.getRemindAt()), false)); + Result pendingReminders = getReminders(guildId, userId); - if (remindersEmbed.getFields().isEmpty()) { + if (pendingReminders.isEmpty()) { remindersEmbed.setDescription("No pending reminders"); + } else { + pendingReminders.forEach(reminder -> { + String content = reminder.getContent(); + long channelId = reminder.getChannelId(); + Instant remindAt = reminder.getRemindAt(); + + remindersEmbed.addField(content, getDescription.apply(channelId, remindAt), false); + }); } event.replyEmbeds(remindersEmbed.build()).setEphemeral(true).queue(); } + private Result getReminders(long guildId, long userId) { + return database.read(context -> context.selectFrom(PENDING_REMINDERS) + .where(PENDING_REMINDERS.GUILD_ID.eq(guildId) + .and(PENDING_REMINDERS.AUTHOR_ID.eq(userId))) + .orderBy(PENDING_REMINDERS.REMIND_AT.asc()) + .fetch()); + } + private static Instant parseWhen(int whenAmount, String whenUnit) { TemporalAmount period = switch (whenUnit) { case "second", "seconds" -> Duration.ofSeconds(whenAmount); diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java index a8ae9e47f2..74733330cd 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java @@ -110,12 +110,13 @@ public static String abbreviate(String text, int maxLength) { } /** - * Mentions a guild channel by its id Clone of JDAs Channel#getAsMention, but unfortunately - * channel instances can not be created out of just an ID, unlike User#fromId + * Mentions a guild channel by its id. * * @param channelId the ID of the channel to mention * @return the channel as formatted string which Discord interprets as clickable mention */ + // Clone of JDAs Channel#getAsMention, but unfortunately channel instances can not be created + // out of just an ID, unlike User#fromId public static String mentionChannelById(long channelId) { return "<#%d>".formatted(channelId); } From 972f7c6e4dd10a7323180a9b41d393beac146cbe Mon Sep 17 00:00:00 2001 From: Taz03 Date: Thu, 27 Oct 2022 13:56:19 +0530 Subject: [PATCH 15/27] improved javadocs --- .../tjbot/commands/reminder/ReminderCommand.java | 8 ++++++++ .../togetherjava/tjbot/commands/utils/MessageUtils.java | 8 +++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index 5f78568a8d..c514264fd5 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -35,6 +35,10 @@ * {@code * /reminder create time-amount: 5 time-unit: weeks content: Hello World! * } + * + * {@code + * /reminder list + * } * *

* Pending reminders are processed and send by {@link RemindRoutine}. @@ -52,6 +56,10 @@ public final class ReminderCommand extends SlashCommandAdapter { private static final List TIME_UNITS = List.of("minutes", "hours", "days", "weeks", "months", "years"); private static final Period MAX_TIME_PERIOD = Period.ofYears(3); + private static final int MAX_PAGE_LENGTH = 10; + private static final int MAX_REMINDER_TITLE_LENGTH = 256; + private static final String PREVIOUS_BUTTON_LABEL = "⬅"; + private static final String NEXT_BUTTON_LABEL = "➡"; static final int MAX_PENDING_REMINDERS_PER_USER = 100; private final Database database; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java index 74733330cd..95f16a85a6 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java @@ -110,14 +110,16 @@ public static String abbreviate(String text, int maxLength) { } /** - * Mentions a guild channel by its id. + * Mentions a guild channel by its id. If the given channelId is unknown the formatted text will + * say `#deleted-channel` in discord * * @param channelId the ID of the channel to mention * @return the channel as formatted string which Discord interprets as clickable mention */ - // Clone of JDAs Channel#getAsMention, but unfortunately channel instances can not be created - // out of just an ID, unlike User#fromId public static String mentionChannelById(long channelId) { + // Clone of JDAs Channel#getAsMention, but unfortunately channel instances can not be + // created + // out of just an ID, unlike User#fromId return "<#%d>".formatted(channelId); } } From 60302de5eda59e134854ca2efecbda5b44bf55cb Mon Sep 17 00:00:00 2001 From: Taz03 Date: Thu, 27 Oct 2022 13:59:37 +0530 Subject: [PATCH 16/27] improved javadocs --- .../org/togetherjava/tjbot/commands/utils/MessageUtils.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java index 95f16a85a6..e12cdc977a 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/utils/MessageUtils.java @@ -111,15 +111,14 @@ public static String abbreviate(String text, int maxLength) { /** * Mentions a guild channel by its id. If the given channelId is unknown the formatted text will - * say `#deleted-channel` in discord + * say `#deleted-channel` in discord. * * @param channelId the ID of the channel to mention * @return the channel as formatted string which Discord interprets as clickable mention */ public static String mentionChannelById(long channelId) { // Clone of JDAs Channel#getAsMention, but unfortunately channel instances can not be - // created - // out of just an ID, unlike User#fromId + // created out of just an ID, unlike User#fromId return "<#%d>".formatted(channelId); } } From 65afb6ec5cc59eb9d2a2571935a261d3a8b08b11 Mon Sep 17 00:00:00 2001 From: Taz03 Date: Fri, 28 Oct 2022 21:18:51 +0530 Subject: [PATCH 17/27] added paginaiton --- .../commands/reminder/ReminderCommand.java | 120 ++++++++++++++---- 1 file changed, 98 insertions(+), 22 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java index c514264fd5..694292ff40 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/reminder/ReminderCommand.java @@ -5,11 +5,16 @@ import net.dv8tion.jda.api.entities.ISnowflake; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.OptionData; import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import net.dv8tion.jda.api.interactions.components.buttons.Button; import net.dv8tion.jda.api.utils.TimeFormat; +import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.api.utils.messages.MessageCreateData; +import net.dv8tion.jda.api.utils.messages.MessageEditData; import org.jooq.Result; import org.togetherjava.tjbot.commands.CommandVisibility; @@ -20,6 +25,7 @@ import java.time.*; import java.time.temporal.TemporalAmount; +import java.util.ArrayList; import java.util.List; import java.util.function.BiFunction; @@ -102,6 +108,21 @@ public void onSlashCommand(SlashCommandInteractionEvent event) { } } + @Override + public void onButtonClick(ButtonInteractionEvent event, List args) { + int pageNumber = Integer.parseInt(args.get(0)); + int pageTurnBy = Integer.parseInt(args.get(1)); + + Result pendingReminders = + getPendingReminders(event.getGuild(), event.getUser()); + int pageToShow = pageNumber + pageTurnBy; + + event + .editMessage( + MessageEditData.fromCreateData(createListMessage(pendingReminders, pageToShow))) + .queue(); + } + private void handleCreateCommand(SlashCommandInteractionEvent event) { int timeAmount = Math.toIntExact(event.getOption(TIME_AMOUNT_OPTION).getAsLong()); String timeUnit = event.getOption(TIME_UNIT_OPTION).getAsString(); @@ -133,40 +154,95 @@ private void handleCreateCommand(SlashCommandInteractionEvent event) { } private void handleListCommand(SlashCommandInteractionEvent event) { - BiFunction getDescription = (channelId, remindAt) -> """ - Channel: %s - Remind at: %s""".formatted(MessageUtils.mentionChannelById(channelId), - TimeFormat.DEFAULT.format(remindAt)); + Result pendingReminders = + getPendingReminders(event.getGuild(), event.getUser()); - EmbedBuilder remindersEmbed = new EmbedBuilder().setTitle("Pending reminders") - .setColor(RemindRoutine.AMBIENT_COLOR); + event.reply(createListMessage(pendingReminders, 1)).setEphemeral(true).queue(); + } - long guildId = event.getGuild().getIdLong(); - long userId = event.getUser().getIdLong(); + private Result getPendingReminders(Guild guild, User user) { + return database.read(context -> context.selectFrom(PENDING_REMINDERS) + .where(PENDING_REMINDERS.GUILD_ID.eq(guild.getIdLong()) + .and(PENDING_REMINDERS.AUTHOR_ID.eq(user.getIdLong()))) + .orderBy(PENDING_REMINDERS.REMIND_AT.asc()) + .fetch()); + } - Result pendingReminders = getReminders(guildId, userId); + private MessageCreateData createListMessage(Result pendingReminders, + int pageToShow) { + int totalPages = (int) Math.ceil(pendingReminders.size() / (double) MAX_PAGE_LENGTH); + + EmbedBuilder remindersEmbed = new EmbedBuilder().setTitle("Pending reminders") + .setColor(RemindRoutine.AMBIENT_COLOR); + MessageCreateBuilder listMessage = new MessageCreateBuilder(); if (pendingReminders.isEmpty()) { remindersEmbed.setDescription("No pending reminders"); } else { - pendingReminders.forEach(reminder -> { - String content = reminder.getContent(); - long channelId = reminder.getChannelId(); - Instant remindAt = reminder.getRemindAt(); + if (totalPages > 1) { + remindersEmbed.setFooter("Page: " + pageToShow + "/" + totalPages); - remindersEmbed.addField(content, getDescription.apply(channelId, remindAt), false); - }); + getRemindersPage(pendingReminders, pageToShow) + .forEach(reminder -> addReminderAsField(reminder, remindersEmbed)); + + listMessage.addActionRow(createPageTurnButtons(pageToShow, totalPages)); + } else { + pendingReminders.forEach(reminder -> addReminderAsField(reminder, remindersEmbed)); + } } - event.replyEmbeds(remindersEmbed.build()).setEphemeral(true).queue(); + return listMessage.addEmbeds(remindersEmbed.build()).build(); } - private Result getReminders(long guildId, long userId) { - return database.read(context -> context.selectFrom(PENDING_REMINDERS) - .where(PENDING_REMINDERS.GUILD_ID.eq(guildId) - .and(PENDING_REMINDERS.AUTHOR_ID.eq(userId))) - .orderBy(PENDING_REMINDERS.REMIND_AT.asc()) - .fetch()); + private List