-
-
Notifications
You must be signed in to change notification settings - Fork 3
Velen Pagination Helper
Velen also offers a helper class that helps you paginate items easily with the Paginate<T>
class. All you need is to add a single line, as seen below:
new Paginate<?>(someList).paginate(MessageCreateEvent, PaginateEvent<?>(){...},
Duration);
An example implementation of the above is:
VelenCommand.of("paginate", "Tests pagination.", velen, (event, message, user, args) -> {
List<String> testList = Arrays.asList("Test 0", "Test 1", "Test 2", "Test 3", "Test 4");
// Create a Pagination object (you can also save the pagination object to reuse later).
new Paginate<>(testList).paginate(event, new PaginateEvent<String>() {
private EmbedBuilder embed(String currentItem, int arrow, int maximum) {
// Remember to always add +1 to arrow for these types of stuff since
// arrow returns the raw position which means it starts at 0 instead of 1.
return new EmbedBuilder().setTitle("Item [" + (arrow + 1) + "/" + maximum + "]")
.setDescription(currentItem).setColor(Color.BLUE);
}
private EmbedBuilder embed(String currentItem) {
return new EmbedBuilder().setTitle("Item")
.setDescription(currentItem).setColor(Color.BLUE);
}
@Override
public MessageBuilder onInit(MessageCreateEvent event, String currentItem,
int arrow, Paginator<String> paginator) {
// This is the initial message that will be sent on start of pagination.
return new MessageBuilder().setEmbed(embed(currentItem, arrow, paginator.size()));
}
@Override
public void onPaginate(MessageCreateEvent event, Message paginateMessage, String currentItem,
int arrow, Paginator<String> paginator) {
// This is what will be executed when you paginate next or backwards.
paginateMessage.edit(embed(currentItem, arrow, paginator.size()));
}
@Override
public MessageBuilder onEmptyPaginator(MessageCreateEvent event) {
// This is sent when the paginator has no items.
return new MessageBuilder().setContent("There are currently no items!");
}
@Override
public void onSelect(MessageCreateEvent event, Message paginateMessage, String itemSelected,
int arrow, Paginator<String> paginator) {
// Similar to onPaginate except this is sent whenever the user
// has selected a page that they want.
paginateMessage.edit(embed(itemSelected));
}
}, Duration.ofMinutes(5));
}).attach();
Similar to VelenEvent
, you can also place the handler onto its own class. An example of such can be
seen below:
This is the handler class for pagination.
class ExamplePaginateEvent implements PaginateEvent<String> {
private EmbedBuilder embed(String currentItem, int arrow, int maximum) {
return new EmbedBuilder().setTitle("Item [" + (arrow + 1) + "/" + maximum + "]")
.setDescription(currentItem).setColor(Color.BLUE);
}
private EmbedBuilder embed(String currentItem) {
return new EmbedBuilder().setTitle("Item")
.setDescription(currentItem).setColor(Color.BLUE);
}
@Override
public MessageBuilder onInit(MessageCreateEvent event, String currentItem,
int arrow, Paginator<String> paginator) {
return new MessageBuilder().setEmbed(embed(currentItem, arrow, paginator.size()));
}
@Override
public void onPaginate(MessageCreateEvent event, Message paginateMessage, String currentItem,
int arrow, Paginator<String> paginator) {
paginateMessage.edit(embed(currentItem, arrow, paginator.size()));
}
@Override
public MessageBuilder onEmptyPaginator(MessageCreateEvent event) {
return new MessageBuilder().setContent("There are currently no items!");
}
@Override
public void onSelect(MessageCreateEvent event, Message paginateMessage, String itemSelected,
int arrow, Paginator<String> paginator) {
paginateMessage.edit(embed(itemSelected));
}
}
The main class where you register all your Velen commands.
VelenCommand.of("paginate", "Tests pagination.", velen, (event, message, user, args) -> {
List<String> testList = Arrays.asList("Test 0", "Test 1", "Test 2", "Test 3", "Test 4");
new Paginate<>(testList).paginate(event, new ExamplePaginateEvent(), Duration.ofMinutes(5));
}).attach();
Optionally, you can customize the emojis (unicode or Javacord Emoji objects) that will be used, for example (this example will use Unicode):
new Paginate<>(items, "➡", "⬅", "👍", "👎").paginate(...);
With v1.1.0, Velen now officially supports pagination with buttons. There are two types of pagination on Velen as usual which is called Normal
and Simple
with the Simple
lacking a Select
reaction (or button), an example implementation of both types for buttons is shown below.
To explain a little bit more simply, to create a Paginate
event on Velen, all you need is to add this line:
new Paginate<?>(someList).paginateWithButtons(Unique Identifier, MessageCreateEvent, PaginateButtonEvent<?> () {...},
Duration);
You can set the Duration to Duration.ofSeconds(0)
to stop Velen from automatically removing the button listeners
when the duration time has passed (this is to free up unused listeners).
VelenCommand.of("paginate", "Paginates through a list of string.", velen, (event, message, user, args) -> {
List<String> list = Arrays.asList("sparkling beauty.", "dangerous assassin.", "cute but deadly.", "sparkling star.");
new Paginate<String>(list).paginateWithButtons("someKindOfUniqueThingHere", event, new PaginateButtonEvent<String> () {
@Override
public MessageBuilder onInit(MessageCreateEvent event, String currentItem, int arrow, Paginator<String> paginator) {
return new MessageBuilder().setEmbed(paginateEmbed(currentItem, arrow, paginator.size()));
}
@Override
public void onPaginate(InteractionImmediateResponseBuilder responder,
MessageCreateEvent event, Message paginateMessage,
String currentItem, int arrow, Paginator<String> paginator) {
paginateMessage.edit(paginateEmbed(currentItem, arrow, paginator.size()));
// This is a required line (especially if you are editing the message not through
// the responder).
responder.respond();
}
@Override
public MessageBuilder onEmptyPaginator(MessageCreateEvent event) {
return new MessageBuilder()
.setContent("**ERR**:: There are no items found.");
}
@Override
public void onSelect(InteractionImmediateResponseBuilder responder,
MessageCreateEvent event, Message paginateMessage,
String itemSelected, int arrow, Paginator<String> paginator) {
paginateMessage.delete();
responder.setContent("You are now a " + itemSelected).respond();
}
private EmbedBuilder paginateEmbed(String currentItem, int arrow, int maximum) {
return new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Class [" + (arrow + 1) + "/" + maximum + "]")
.setDescription("You are selecting the class: " + currentItem);
}
}, Duration.ofMinutes(5));
}).attach();
VelenCommand.of("paginate", "Paginates through a list of string.", velen, (event, message, user, args) -> {
List<String> list = Arrays.asList("sparkling beauty.", "dangerous assassin.", "cute but deadly.", "sparkling star.");
// The emojis (unicode) on the params is simply setting the
// cancel reaction to a trash can.
new Paginate<String>(list, "➡", "⬅", "👍", "\uD83D\uDDD1").paginateWithButtons("someKindOfUniqueThingHere", event, new PaginateButtonSimpleEvent<String>() {
@Override
public MessageBuilder onInit(MessageCreateEvent event, String currentItem, int arrow, Paginator<String> paginator) {
return new MessageBuilder().setEmbed(paginateEmbed(currentItem, arrow, paginator.size()));
}
@Override
public void onPaginate(InteractionImmediateResponseBuilder responder,
MessageCreateEvent event, Message paginateMessage,
String currentItem, int arrow, Paginator<String> paginator) {
paginateMessage.edit(paginateEmbed(currentItem, arrow, paginator.size()));
// This is a required line (especially if you are editing the message not through
// the responder).
responder.respond();
}
@Override
public MessageBuilder onEmptyPaginator(MessageCreateEvent event) {
return new MessageBuilder()
.setContent("**ERR**:: There are no items found.");
}
private EmbedBuilder paginateEmbed(String currentItem, int arrow, int maximum) {
return new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Class [" + (arrow + 1) + "/" + maximum +"]")
.setDescription("You are looking at the class: " + currentItem);
}
}, Duration.ofMinutes(5));
}).attach();
Q: Paginating with buttons somehow gives This interaction failed even though the message was changed, etc...
A: This is because you are not adding the line: responder.respond()
or something similar which is needed to tell
Discord that you responded to the event (Velen, by default, does not add it since we don't want to reduce your rate-limit
by sending a duplicate empty response).
Q: The buttons aren't removed when Duration of removeAfter
has passed...
A: This is a known-issue as Javacord (or maybe I haven't found it) has no way of removing components from the message for some reason.