Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ These changes are available on the `master` branch, but have not yet been releas
([#2417](https://github.com/Pycord-Development/pycord/pull/2417))
- Fixed parameter `embed=None` causing `AttributeError` on `PartialMessage.edit`.
([#2446](https://github.com/Pycord-Development/pycord/pull/2446))
- Fixed paginator to revert state if a page update callback fails.
([#2448](https://github.com/Pycord-Development/pycord/pull/2448))

### Changed

Expand Down
93 changes: 50 additions & 43 deletions discord/ext/pages/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
from typing import List

import discord
from discord.errors import DiscordException
from discord.ext.bridge import BridgeContext
from discord.ext.commands import Context
from discord.file import File
from discord.member import Member
from discord.user import User

Expand Down Expand Up @@ -103,26 +105,25 @@ async def callback(self, interaction: discord.Interaction):
interaction: :class:`discord.Interaction`
The interaction created by clicking the navigation button.
"""
new_page = self.paginator.current_page
if self.button_type == "first":
self.paginator.current_page = 0
new_page = 0
elif self.button_type == "prev":
if self.paginator.loop_pages and self.paginator.current_page == 0:
self.paginator.current_page = self.paginator.page_count
new_page = self.paginator.page_count
else:
self.paginator.current_page -= 1
new_page -= 1
elif self.button_type == "next":
if (
self.paginator.loop_pages
and self.paginator.current_page == self.paginator.page_count
):
self.paginator.current_page = 0
new_page = 0
else:
self.paginator.current_page += 1
new_page += 1
elif self.button_type == "last":
self.paginator.current_page = self.paginator.page_count
await self.paginator.goto_page(
page_number=self.paginator.current_page, interaction=interaction
)
new_page = self.paginator.page_count
await self.paginator.goto_page(page_number=new_page, interaction=interaction)


class Page:
Expand Down Expand Up @@ -656,6 +657,20 @@ async def cancel(
else:
await self.message.edit(view=self)

def _goto_page(self, page_number: int = 0) -> tuple[Page, list[File] | None]:
self.current_page = page_number
self.update_buttons()

page = self.pages[page_number]
page = self.get_page_content(page)

if page.custom_view:
self.update_custom_view(page.custom_view)

files = page.update_files()

return page, files

async def goto_page(
self, page_number: int = 0, *, interaction: discord.Interaction | None = None
) -> None:
Expand All @@ -680,42 +695,34 @@ async def goto_page(
:class:`~discord.Message`
The message associated with the paginator.
"""
self.update_buttons()
self.current_page = page_number
if self.show_indicator:
try:
self.buttons["page_indicator"][
"object"
].label = f"{self.current_page + 1}/{self.page_count + 1}"
except KeyError:
pass

page = self.pages[page_number]
page = self.get_page_content(page)
old_page = self.current_page
page, files = self._goto_page(page_number)

if page.custom_view:
self.update_custom_view(page.custom_view)

files = page.update_files()
try:
if interaction:
await interaction.response.defer() # needed to force webhook message edit route for files kwarg support
await interaction.followup.edit_message(
message_id=self.message.id,
content=page.content,
embeds=page.embeds,
attachments=[],
files=files or [],
view=self,
)
else:
await self.message.edit(
content=page.content,
embeds=page.embeds,
attachments=[],
files=files or [],
view=self,
)
except DiscordException:
# Something went wrong, and the paginator couldn't be updated.
# Revert our changes and propagate the error.
self._goto_page(old_page)
raise

if interaction:
await interaction.response.defer() # needed to force webhook message edit route for files kwarg support
await interaction.followup.edit_message(
message_id=self.message.id,
content=page.content,
embeds=page.embeds,
attachments=[],
files=files or [],
view=self,
)
else:
await self.message.edit(
content=page.content,
embeds=page.embeds,
attachments=[],
files=files or [],
view=self,
)
if self.trigger_on_display:
await self.page_action(interaction=interaction)

Expand Down