Created
March 22, 2022 07:01
-
-
Save quackbarc/31e5cd789d232ad0d263511bb1a506e8 to your computer and use it in GitHub Desktop.
some paginators for discord.py 2.0.0@45d498c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Callable, List, Optional | |
import discord | |
class Paginator(discord.ui.View): | |
r"""A dynamic paginator that uses a callback to generate embeds. | |
This should be passed in as a regular view to methods like | |
:meth:`discord.abc.Messageable.send`. | |
Parameters | |
----------- | |
callback: Callable[[:class:`int`], List[:class:`discord.Embed`]] | |
The callback that takes in a page number and returns a list of | |
:class:`discord.Embed`\s. | |
pages: :class:`int` | |
The page count, i.e. the last page the callback can generate. | |
Attributes | |
----------- | |
page: :class:`int` | |
The current page on the paginator. | |
""" | |
def __init__(self, | |
callback: Callable[[int], List[discord.Embed]], | |
pages: int, | |
**kwargs): | |
super().__init__(**kwargs) | |
self.pages = pages | |
self.callback = callback | |
self.page = 1 | |
self._update_buttons() | |
def _update_buttons(self): | |
self.prev_button.disabled = self.page <= 1 | |
self.next_button.disabled = self.page >= self.pages | |
def get_page(self, page: int) -> List[discord.Embed]: | |
"""Returns a page generated by the callback. Technically | |
an alias for `Paginator.callback()`. | |
Useful for getting an embed before deploying a View. | |
""" | |
return self.callback(page) | |
@discord.ui.button(label="previous") | |
async def prev_button(self, _, interaction): | |
self.page = max(self.page - 1, 1) | |
self._update_buttons() | |
embs = self.callback(self.page) | |
await interaction.response.edit_message(embeds=embs, view=self) | |
@discord.ui.button(label="next") | |
async def next_button(self, _, interaction): | |
self.page = min(self.page + 1, self.pages) | |
self._update_buttons() | |
embs = self.callback(self.page) | |
await interaction.response.edit_message(embeds=embs, view=self) | |
class StaticPaginator(Paginator): | |
"""A simple paginator that takes in lines instead of a callback. | |
A line limit and base embed may be passed in for customization. | |
Parameters | |
----------- | |
lines: List[:class:`str`] | |
The list of strings to iterate through in the paginator, | |
joined in the output embed's description with newlines. | |
line_limit: Optional[:class:`int`] | |
The amount of lines to display per page. Defaults to 15. | |
base_embed: Optional[:class:`discord.Embed`] | |
The template for the resulting embed. Only the description will | |
be replaced. | |
""" | |
def __init__(self, | |
lines: List[str], | |
*, | |
line_limit: Optional[int] = 15, | |
base_embed: Optional[discord.Embed] = None, | |
**kwargs): | |
self.lines = lines | |
self.line_limit = line_limit | |
self.base_embed = base_embed or discord.Embed() | |
import math | |
pages: int = math.ceil(len(lines) / self.line_limit) # type: ignore | |
def callback(page: int) -> List[discord.Embed]: | |
m = (page-1) * self.line_limit # type: ignore | |
n = page * self.line_limit # type: ignore | |
emb = self.base_embed.copy() | |
emb.description = "\n".join(self.lines[m:n]) | |
return [emb] | |
super().__init__(callback, pages, **kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment