Merge pull request 'feat: add Prev/Next navigation buttons to /refractor status' (#127) from feat/refractor-pagination-buttons into main
All checks were successful
Build Docker Image / build (push) Successful in 3m8s

This commit is contained in:
cal 2026-03-25 22:43:29 +00:00
commit dea6316201

View File

@ -129,6 +129,82 @@ def paginate(items: list, page: int, page_size: int = PAGE_SIZE) -> tuple:
return items[start : start + page_size], total_pages
class RefractorPaginationView(discord.ui.View):
"""Prev/Next buttons for refractor status pagination."""
def __init__(
self,
team: dict,
page: int,
total_pages: int,
total_count: int,
params: list,
owner_id: int,
timeout: float = 120.0,
):
super().__init__(timeout=timeout)
self.team = team
self.page = page
self.total_pages = total_pages
self.total_count = total_count
self.base_params = params
self.owner_id = owner_id
self._update_buttons()
def _update_buttons(self):
self.prev_btn.disabled = self.page <= 1
self.next_btn.disabled = self.page >= self.total_pages
async def _fetch_and_update(self, interaction: discord.Interaction):
offset = (self.page - 1) * PAGE_SIZE
params = [(k, v) for k, v in self.base_params if k != "offset"]
params.append(("offset", offset))
data = await db_get("refractor/cards", params=params)
items = data.get("items", []) if isinstance(data, dict) else []
self.total_count = (
data.get("count", self.total_count)
if isinstance(data, dict)
else self.total_count
)
self.total_pages = max(1, (self.total_count + PAGE_SIZE - 1) // PAGE_SIZE)
self.page = min(self.page, self.total_pages)
lines = [format_refractor_entry(state) for state in items]
embed = discord.Embed(
title=f"{self.team['sname']} Refractor Status",
description="\n\n".join(lines) if lines else "No cards found.",
color=0x6F42C1,
)
embed.set_footer(
text=f"Page {self.page}/{self.total_pages} · {self.total_count} card(s) total"
)
self._update_buttons()
await interaction.response.edit_message(embed=embed, view=self)
@discord.ui.button(label="◀ Prev", style=discord.ButtonStyle.blurple)
async def prev_btn(
self, interaction: discord.Interaction, button: discord.ui.Button
):
if interaction.user.id != self.owner_id:
return
self.page = max(1, self.page - 1)
await self._fetch_and_update(interaction)
@discord.ui.button(label="Next ▶", style=discord.ButtonStyle.blurple)
async def next_btn(
self, interaction: discord.Interaction, button: discord.ui.Button
):
if interaction.user.id != self.owner_id:
return
self.page = min(self.total_pages, self.page + 1)
await self._fetch_and_update(interaction)
async def on_timeout(self):
self.prev_btn.disabled = True
self.next_btn.disabled = True
class Refractor(commands.Cog):
"""Refractor progress tracking slash commands."""
@ -237,8 +313,7 @@ class Refractor(commands.Cog):
total_pages = max(1, (total_count + PAGE_SIZE - 1) // PAGE_SIZE)
page = min(page, total_pages)
page_items = items
lines = [format_refractor_entry(state) for state in page_items]
lines = [format_refractor_entry(state) for state in items]
embed = discord.Embed(
title=f"{team['sname']} Refractor Status",
@ -249,7 +324,18 @@ class Refractor(commands.Cog):
text=f"Page {page}/{total_pages} · {total_count} card(s) total"
)
await interaction.edit_original_response(embed=embed)
if total_pages > 1:
view = RefractorPaginationView(
team=team,
page=page,
total_pages=total_pages,
total_count=total_count,
params=params,
owner_id=interaction.user.id,
)
await interaction.edit_original_response(embed=embed, view=view)
else:
await interaction.edit_original_response(embed=embed)
async def setup(bot):