142 lines
4.6 KiB
Markdown
142 lines
4.6 KiB
Markdown
# dpy_paginator
|
|
|
|
Button-navigated paginator for discord.py. A `discord.ui.View` that paginates mixed
|
|
content (strings, embeds, files, attachments, or dicts of mixed content with custom
|
|
buttons) behind previous / jump / next navigation, with an optional cache button.
|
|
|
|
## Install
|
|
|
|
`requirements.txt`:
|
|
|
|
```
|
|
dpy_paginator @ git+ssh://git@git.rethinkstudios.io/rethink-public/dpy_paginator.git@v0.1.0
|
|
```
|
|
|
|
Direct:
|
|
|
|
```bash
|
|
pip install "dpy_paginator @ git+ssh://git@git.rethinkstudios.io/rethink-public/dpy_paginator.git@v0.1.0"
|
|
```
|
|
|
|
Requires `discord.py` (pulled transitively).
|
|
|
|
## Basic usage
|
|
|
|
Plain pages — just navigation:
|
|
|
|
```python
|
|
from dpy_paginator import ButtonPaginator
|
|
|
|
pages = [discord.Embed(title=f"Page {i}") for i in range(5)]
|
|
await ButtonPaginator(pages, author_id=ctx.author.id).start(ctx)
|
|
```
|
|
|
|
`start()` accepts an `Interaction` or any `Messageable` (a `Context`, channel, etc.).
|
|
|
|
## Emojis
|
|
|
|
Navigation uses plain Unicode by default — no setup, no emoji upload required. Pass
|
|
`emojis=` to override with custom application/guild emojis the bot can use:
|
|
|
|
```python
|
|
ButtonPaginator(pages, emojis={
|
|
"previous": "<:icon_back:123...>",
|
|
"next": "<:icon_next:123...>",
|
|
"cache": "<:icon_cache:123...>",
|
|
})
|
|
```
|
|
|
|
Unset keys fall back to the Unicode defaults.
|
|
|
|
## Page types
|
|
|
|
A page may be a `str`, `discord.Embed`, `discord.File`/`Attachment`, a sequence of
|
|
those, or a `dict`. A dict page can carry `content`, `embed`/`embeds`,
|
|
`file`/`files`, and a `buttons` list of custom button configs.
|
|
|
|
## Custom per-page buttons
|
|
|
|
Each page can declare its own buttons. They render alongside the navigation row and
|
|
are rebuilt from the page dict on every render — so mutating a page's button config
|
|
and re-rendering updates the button live.
|
|
|
|
```python
|
|
async def callback_reorder(interaction, button, data, paginator):
|
|
await interaction.response.send_message(f"Reordering {data['email']}", ephemeral=True)
|
|
|
|
pages = []
|
|
for session in sessions:
|
|
pages.append({
|
|
"content": session["_id"],
|
|
"embed": build_embed(session),
|
|
"buttons": [
|
|
{
|
|
"label": "Reorder",
|
|
"style": discord.ButtonStyle.green,
|
|
"emoji": some_emoji, # optional, your own emoji
|
|
"disabled": False,
|
|
"data": {"email": session["_id"]},
|
|
"callback": callback_reorder,
|
|
}
|
|
],
|
|
})
|
|
|
|
paginator = ButtonPaginator(
|
|
pages, cache=None, timeout=900, delete_message_after=True,
|
|
mentions_allowed=discord.AllowedMentions.none(), ephemeral=True,
|
|
page_text="Session {} of {}",
|
|
)
|
|
await paginator.start(interaction)
|
|
```
|
|
|
|
Button config keys: `label`, `style`, `emoji`, `disabled`, `data` (arbitrary, passed
|
|
to the callback), `callback`. The callback signature is
|
|
`async def cb(interaction, button, data, paginator)`. With no callback, the button
|
|
echoes its `data`.
|
|
|
|
## Cache button (mention priming)
|
|
|
|
Discord clients render `<@id>` as a raw id until the user object is cached locally.
|
|
The cache button fixes that: pass `cache=[...]` with one entry per page, where each
|
|
entry is a string of the user mentions on that page (`"<@111> <@222> <@333>"`).
|
|
|
|
When clicked, the button posts the page's mentions in a throwaway ephemeral message
|
|
(rendering the `<@id>` tags primes the viewer's client — `allowed_mentions` is
|
|
`none()` so no actual ping fires), waits `cache_sleep` seconds (default 1.0) for the
|
|
client to resolve them, then re-renders the current page — so the mentions now
|
|
display as names without the user having to flip pages manually.
|
|
|
|
```python
|
|
pages, cache = [], []
|
|
for group in groups:
|
|
pages.append(build_embed(group))
|
|
cache.append(" ".join(f"<@{uid}>" for uid in group["user_ids"]))
|
|
|
|
await ButtonPaginator(pages, cache=cache, cache_sleep=1.0).start(ctx)
|
|
```
|
|
|
|
Omit `cache` or pass `None`/`[]` and the button never appears. When set, `cache`
|
|
must have one entry per rendered page.
|
|
|
|
## Constructor options
|
|
|
|
- `pages` — sequence of page content
|
|
- `cache` — optional per-page cache strings (enables the cache button)
|
|
- `author_id` — restrict interaction to this user
|
|
- `timeout` — seconds before the view stops (default 180)
|
|
- `delete_message_after` — delete the message on timeout
|
|
- `per_page` — entries per page (default 1)
|
|
- `mentions_allowed` — `AllowedMentions` for sends (default `.all()`)
|
|
- `ephemeral` — send/edit ephemerally
|
|
- `page_text` — format string for the jump button label
|
|
- `emojis` — override navigation emojis
|
|
|
|
## Subclassing
|
|
|
|
Override `format_page(page)` to transform pages before rendering (e.g. wrap raw data
|
|
in an embed). It may be sync or async.
|
|
|
|
## Versioning
|
|
|
|
Tagged `vX.Y.Z`. Pin the tag in `requirements.txt`.
|