Pagination View
This commit is contained in:
parent
a3850a2646
commit
93fe4ebfce
120
src/utils.py
120
src/utils.py
@ -3,8 +3,10 @@
|
||||
import aiohttp
|
||||
import logging
|
||||
import async_timeout
|
||||
from typing import Callable
|
||||
|
||||
from discord import Interaction, Embed, Colour
|
||||
from discord import Interaction, Embed, Colour, ButtonStyle, Button
|
||||
from discord.ui import View, button
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -53,6 +55,111 @@ class FollowupIcons:
|
||||
assigned = "https://img.icons8.com/fluency-systems-filled/48/4598DA/hashtag-large.png"
|
||||
|
||||
|
||||
class PaginationView(View):
|
||||
def __init__(
|
||||
self, inter: Interaction, embed: Embed, getdata: Callable,
|
||||
formatdata: Callable, maxpage: int, initpage: int=1
|
||||
):
|
||||
self.inter = inter
|
||||
self.embed = embed
|
||||
self.getdata = getdata
|
||||
self.formatdata = formatdata
|
||||
self.maxpage = maxpage
|
||||
self.index = initpage
|
||||
super().__init__(timeout=100)
|
||||
|
||||
async def check_user_is_author(self, inter: Interaction) -> bool:
|
||||
"""Ensure the user is the author of the original command."""
|
||||
|
||||
if inter.user == self.inter.user:
|
||||
return True
|
||||
|
||||
await inter.response.defer()
|
||||
await (
|
||||
Followup(None, "Only the author can interact with this.")
|
||||
.error()
|
||||
.send(inter, ephemeral=True)
|
||||
)
|
||||
return False
|
||||
|
||||
async def on_timeout(self):
|
||||
"""Erase the controls on timeout."""
|
||||
|
||||
message = await self.inter.original_response()
|
||||
await message.edit(view=None)
|
||||
|
||||
@staticmethod
|
||||
def calc_total_pages(results: int, max_pagesize: int) -> int:
|
||||
result = ((results - 1) // max_pagesize) + 1
|
||||
log.debug("total pages calculated: %s", result)
|
||||
return result
|
||||
|
||||
@button(emoji="◀️", style=ButtonStyle.blurple)
|
||||
async def backward(self, inter: Interaction, button: Button):
|
||||
self.index -= 1
|
||||
await inter.response.defer()
|
||||
self.inter = inter
|
||||
await self.navigate()
|
||||
|
||||
@button(emoji="▶️", style=ButtonStyle.blurple)
|
||||
async def forward(self, inter: Interaction, button: Button):
|
||||
self.index += 1
|
||||
await inter.response.defer()
|
||||
self.inter = inter
|
||||
await self.navigate()
|
||||
|
||||
@button(emoji="⏭️", style=ButtonStyle.blurple)
|
||||
async def start_or_end(self, inter: Interaction, button: Button):
|
||||
if self.index <= self.maxpage // 2:
|
||||
self.index = self.maxpage
|
||||
else:
|
||||
self.index = 1
|
||||
|
||||
await inter.response.defer()
|
||||
self.inter = inter
|
||||
await self.navigate()
|
||||
|
||||
async def navigate(self):
|
||||
log.debug("navigating to page: %s", self.index)
|
||||
|
||||
self.update_buttons()
|
||||
paged_embed = await self.create_paged_embed()
|
||||
await self.inter.edit_original_response(embed=paged_embed, view=self)
|
||||
|
||||
async def create_paged_embed(self) -> Embed:
|
||||
embed = self.embed.copy()
|
||||
data = await self.getdata(self.index)
|
||||
|
||||
for item in data:
|
||||
key, value = self.formatdata(item)
|
||||
embed.add_field(name=key, value=value, inline=False)
|
||||
|
||||
if self.maxpage != 1:
|
||||
embed.set_footer(text=f"Page {self.index}/{self.maxpage}")
|
||||
|
||||
return embed
|
||||
|
||||
def update_buttons(self):
|
||||
if self.index >= self.maxpage:
|
||||
self.children[2].emoji = "⏮️"
|
||||
else:
|
||||
self.children[2].emoji = "⏭️"
|
||||
|
||||
self.children[0].disabled = self.index == 1
|
||||
self.children[1].disabled = self.index == self.maxpage
|
||||
|
||||
async def send(self):
|
||||
embed = await self.create_paged_embed()
|
||||
|
||||
if self.maxpage == 1:
|
||||
await self.inter.edit_original_response(embed=embed)
|
||||
return
|
||||
|
||||
self.update_buttons()
|
||||
await self.inter.edit_original_response(embed=embed, view=self)
|
||||
|
||||
|
||||
|
||||
class Followup:
|
||||
"""Wrapper for a discord embed to follow up an interaction."""
|
||||
|
||||
@ -66,10 +173,10 @@ class Followup:
|
||||
description=description
|
||||
)
|
||||
|
||||
async def send(self, inter: Interaction, message: str = None):
|
||||
async def send(self, inter: Interaction, message: str = None, ephemeral: bool = False):
|
||||
""""""
|
||||
|
||||
await inter.followup.send(content=message, embed=self._embed)
|
||||
await inter.followup.send(content=message, embed=self._embed, ephemeral=ephemeral)
|
||||
|
||||
def fields(self, inline: bool = False, **fields: dict):
|
||||
""""""
|
||||
@ -86,6 +193,13 @@ class Followup:
|
||||
|
||||
return self
|
||||
|
||||
def footer(self, text: str, icon_url: str = None):
|
||||
""""""
|
||||
|
||||
self._embed.set_footer(text=text, icon_url=icon_url)
|
||||
|
||||
return self
|
||||
|
||||
def error(self):
|
||||
""""""
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user