From bdb00bd3bc82700765a362b734e8f4a5aecdc79b Mon Sep 17 00:00:00 2001 From: Shindou Date: Wed, 9 Mar 2022 17:28:19 +0800 Subject: [PATCH] Add support for ephemeral middlewares. --- .../command/facade/NexusMiddlewareEvent.java | 41 +++++++++++++++++++ .../responders/NexusResponderRepository.java | 24 +++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/main/java/pw/mihou/nexus/features/command/facade/NexusMiddlewareEvent.java b/src/main/java/pw/mihou/nexus/features/command/facade/NexusMiddlewareEvent.java index 63398f2b..d0a4fcc3 100644 --- a/src/main/java/pw/mihou/nexus/features/command/facade/NexusMiddlewareEvent.java +++ b/src/main/java/pw/mihou/nexus/features/command/facade/NexusMiddlewareEvent.java @@ -14,6 +14,7 @@ public interface NexusMiddlewareEvent extends NexusCommandEvent { * A middleware-only function that tells Discord that the response will be * taking more than three-seconds because the middleware has to process tasks * that can take more than three-second limit. + * @return The future to determine whether the response was accepted or not. */ default CompletableFuture askDelayedResponse() { return CompletableFuture.allOf( @@ -21,6 +22,46 @@ default CompletableFuture askDelayedResponse() { ); } + /** + * A middleware-only function that tells Discord that the response will be + * taking more than three-seconds because the middleware has to process tasks + * that can take more than three-second limit. + * @return The future to determine whether the response was accepted or not. + */ + default CompletableFuture askDelayedResponseAsEphemeral() { + return CompletableFuture.allOf( + getNexus().getResponderRepository().peekEphemeral(getBaseEvent().getInteraction()) + ); + } + + /** + * A middleware-only function that tells Discord that the response will be + * taking more than three-seconds because the middleware has to process tasks + * that can take more than three-second limit. + * + * @param predicate The predicate to determine whether the response should be ephemeral or not. + * @return The future to determine whether the response was accepted or not. + */ + default CompletableFuture askDelayedResponseAsEphemeralIf(boolean predicate) { + if (predicate) { + return askDelayedResponseAsEphemeral(); + } + + return askDelayedResponse(); + } + + /** + * A middleware-only function that tells Discord that the response will be + * taking more than three-seconds because the middleware has to process tasks + * that can take more than three-second limit. + * + * @param predicate The predicate to determine whether the response should be ephemeral or not. + * @return The future to determine whether the response was accepted or not. + */ + default CompletableFuture askDelayedResponseAsEphemeralIf(Predicate predicate) { + return askDelayedResponseAsEphemeralIf(predicate.test(null)); + } + /** * Tells the command interceptor handler to move forward with the next * middleware if there is any, otherwise executes the command code. diff --git a/src/main/java/pw/mihou/nexus/features/command/responders/NexusResponderRepository.java b/src/main/java/pw/mihou/nexus/features/command/responders/NexusResponderRepository.java index f70aebf4..dad434f2 100644 --- a/src/main/java/pw/mihou/nexus/features/command/responders/NexusResponderRepository.java +++ b/src/main/java/pw/mihou/nexus/features/command/responders/NexusResponderRepository.java @@ -35,6 +35,30 @@ public CompletableFuture peek(Interaction in }); } + /** + * Gets the current {@link InteractionOriginalResponseUpdater} for the specific interaction + * if available from another middleware otherwise requests for a new {@link InteractionOriginalResponseUpdater} + * that can be used instead. + *

+ * Not to be confused with {@link NexusResponderRepository#get(Interaction)} which deliberately + * destroys the interaction that is being stored after being requested. This is intended for middlewares to + * prevent Discord's Interaction has failed while processing a heavy task. + * + * @param interaction The interaction to reference. + * @return The {@link InteractionOriginalResponseUpdater} if present otherwise requests for one. + */ + public CompletableFuture peekEphemeral(Interaction interaction) { + if (responders.containsKey(interaction.getId())) { + return CompletableFuture.completedFuture(responders.get(interaction.getId())); + } + + return interaction.respondLater(true) + .thenApply(responseUpdater -> { + responders.put(interaction.getId(), responseUpdater); + return responseUpdater; + }); + } + /** * Gets the current {@link InteractionOriginalResponseUpdater} for the specific interaction if * available from another middleware otherwise requests for a new {@link InteractionOriginalResponseUpdater}