use of org.javacord.api.listener.message.MessageCreateListener in project Javacord by BtoBastian.
the class TextChannel method typeContinuouslyAfter.
/**
* Displays the "xyz is typing..." message continuously, starting delayed.
* The message is continuously displayed if not quit using the returned {@code AutoCloseable}.
* Sending a message will make the message go away shortly, but it will return immediately if not cancelled using
* the {@code AutoCloseable}. This can be used in a try-with-resources block like
* <code>try (NonThrowingAutoCloseable typingIndicator = textChannel.typeContinuouslyAfter(500,
* TimeUnit.MILLISECONDS, ExceptionLogger.getConsumer(RatelimitException.class)))
* { /* do lengthy stuff */ } sendReply();</code>.
*
* <p>The typing indicator will be shown delayed. This can be useful if the task you do can be finished in very
* short time which could cause the typing indicator and the response message being sent at the same time and the
* typing indicator could be shown for 10 seconds even if the message was sent already. With the delay this is
* compensated, because if the returned {@code AutoCloseable} is closed before the delay is over, no typing
* indicator will be sent at all.
*
* <p>Any occurring exceptions including ratelimit exceptions are given to the provided {@code exceptionHandler} or
* ignored if it is {@code null}.
*
* @param exceptionHandler The handler that exceptions are given to.
* @param delay The delay to wait until the first typing indicator is sent.
* @param timeUnit The time unit of the delay value.
* @return An auto-closable to stop sending the typing indicator.
* @see #type()
* @see #typeContinuously()
* @see #typeContinuously(Consumer)
* @see #typeContinuouslyAfter(long, TimeUnit)
*/
default NonThrowingAutoCloseable typeContinuouslyAfter(long delay, TimeUnit timeUnit, Consumer<Throwable> exceptionHandler) {
// the delegate that does the actual type indicator sending and error handling
Runnable typeRunnable = () -> {
try {
CompletableFuture<?> typeFuture = type();
if (exceptionHandler != null) {
typeFuture.exceptionally(throwable -> {
exceptionHandler.accept(throwable);
return null;
});
}
} catch (Throwable t) {
ExceptionLogger.getConsumer().accept(t);
}
};
DiscordApi api = getApi();
// schedule regular type indicator sending
Future<?> typingIndicator = api.getThreadPool().getScheduler().scheduleWithFixedDelay(typeRunnable, TimeUnit.NANOSECONDS.convert(delay, timeUnit), 8_000_000_000L, TimeUnit.NANOSECONDS);
// prevent messages from other commands to interrupt the typing indicator too long
ListenerManager<MessageCreateListener> typingInterruptedListenerManager = api.addMessageCreateListener(event -> {
if (event.getMessage().getAuthor().isYourself()) {
typeRunnable.run();
}
});
// auto-closable to cancel the continuously typing indicator
return () -> {
typingInterruptedListenerManager.remove();
typingIndicator.cancel(true);
};
}
Aggregations