All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.freya022.botcommands.api.pagination.BasicPagination Maven / Gradle / Ivy

Go to download

A Kotlin-first (and Java) framework that makes creating Discord bots a piece of cake, using the JDA library.

There is a newer version: 3.0.0-alpha.18
Show newest version
package io.github.freya022.botcommands.api.pagination;

import io.github.freya022.botcommands.api.components.Components;
import io.github.freya022.botcommands.api.components.data.InteractionConstraints;
import io.github.freya022.botcommands.api.core.Logging;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.interactions.components.ActionComponent;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import net.dv8tion.jda.api.utils.messages.MessageEditBuilder;
import net.dv8tion.jda.api.utils.messages.MessageEditData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * @param  Type of the implementor
 */
public abstract class BasicPagination> {
	private static final Logger LOGGER = Logging.getLogger();
	private static final ScheduledExecutorService TIMEOUT_SERVICE = Executors.newSingleThreadScheduledExecutor();

	protected final InteractionConstraints constraints;
	@Nullable protected final TimeoutInfo timeout;

	protected final MessageEditBuilder messageBuilder = new MessageEditBuilder();
	protected final PaginatorComponents components = new PaginatorComponents();

	private final Set usedIds = new HashSet<>();

	@Nullable private ScheduledFuture timeoutFuture;
	@Nullable private Message message;

	private boolean timeoutPassed = false;

	protected final Components componentsService;

	protected BasicPagination(@NotNull Components componentsService, @NotNull InteractionConstraints constraints, @Nullable TimeoutInfo timeout) {
		this.componentsService = componentsService;
		this.constraints = constraints;
		this.timeout = timeout;
	}

	/**
	 * Returns the {@link MessageEditData} for this current page
	 * 
You can use this message edit data in order to edit a currently active pagination instance, * be aware that this will only replace the fields that already currently exist, * if you want to replace the whole message you need to call {@link MessageEditBuilder#setReplace(boolean)} in your {@link PaginatorSupplier paginator supplier} *
You need to use {@link MessageCreateData#fromEditData(MessageEditData)} in order to send the initial message * * @return The {@link MessageEditData} for this current page */ public abstract MessageEditData get(); /** * Sets the {@link Message} associated to this paginator *
This is an optional operation and will only provide the {@link Message} object through the {@link PaginationTimeoutConsumer} you have set in your paginator builder *
This message instance is not updated, this should only help you get the message's ID and not what's inside it * * @param message The {@link Message} object associated to this paginator * @see BasicPaginationBuilder#setTimeout(long, TimeUnit, PaginationTimeoutConsumer) */ public void setMessage(@NotNull Message message) { this.message = message; } protected void onPreGet() { if (timeoutPassed && timeout != null) { LOGGER.warn("Timeout has already been cleaned up by pagination is still used ! Make sure you called BasicPagination#cleanup in the timeout consumer, timeout consumer at: {}", timeout.onTimeout().getClass().getNestHost()); } messageBuilder.clear(); components.clear(); restartTimeout(); } /** * Restarts the timeout of this pagination instance *
This means the timeout will be scheduled again, as if you called {@link #get()}, but without changing the actual content */ @SuppressWarnings("unchecked") public void restartTimeout() { if (timeout != null) { if (timeoutFuture != null) { timeoutFuture.cancel(false); } //Can't supply instance on by calling super constructor // Also don't want to do an abstract T getThis() timeoutFuture = TIMEOUT_SERVICE.schedule(() -> { timeoutPassed = true; timeout.onTimeout().accept((T) this, message); }, timeout.timeout(), timeout.unit()); } } protected void onPostGet() { for (ActionRow row : components.getActionRows()) { for (ActionComponent component : row.getActionComponents()) { final String id = component.getId(); if (id == null) continue; usedIds.add(id); } } } /** * Cancels the timeout action for this pagination instance *
The timeout will be enabled back if the page changes */ public void cancelTimeout() { if (timeoutFuture != null) { timeoutFuture.cancel(false); } } /** * Cleans up the button IDs used in this paginator *
This will remove every stored button IDs, even then buttons you included yourself */ public void cleanup() { componentsService.deleteComponentsById(usedIds); usedIds.clear(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy