Skip to content

Commit

Permalink
fix: Clear buttons before sending if one page async iterator source (#39
Browse files Browse the repository at this point in the history
)
  • Loading branch information
DenverCoder1 authored Jun 1, 2022
1 parent 21131e3 commit b505a20
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 11 deletions.
6 changes: 3 additions & 3 deletions nextcord/ext/menus/menu_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ async def send_initial_message(
kwargs = await self._get_kwargs_from_page(page)
# filter out kwargs that are "None"
kwargs = {k: v for k, v in kwargs.items() if v is not None}
# if we're not paginating, we can remove the pagination buttons
if not self._source.is_paginating():
await self.clear()
# if there is an interaction, send an interaction response
if self.interaction is not None:
message = await self.interaction.send(ephemeral=self.ephemeral, **kwargs)
Expand All @@ -149,9 +152,6 @@ async def start(
wait=wait,
ephemeral=ephemeral,
)
# If we're not paginating, we can remove the pagination buttons
if not self._source.is_paginating():
await self.clear()

async def show_checked_page(self, page_number: int):
max_pages = self._source.get_max_pages()
Expand Down
54 changes: 46 additions & 8 deletions nextcord/ext/menus/menus.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,44 +840,82 @@ def __init__(
self.disable_buttons_after = disable_buttons_after

async def _update_view(self):
"""|coro|
Updates the :class:`nextcord.ui.View` of the menu.
Raises
--------
AssertionError
The message is None.
"""
assert self.message is not None, "No message to update"
await self.message.edit(view=self)

async def _set_all_disabled(self, disable: bool):
"""|coro|
Enables or disable all :class:`nextcord.ui.Button` components in the menu.
Enables or disables all :class:`nextcord.ui.Button` components in the menu. If the :attr:`message` is set,
it will be edited with the new :class:`~nextcord.ui.View`.
If no buttons are enabled or disabled, the message will not be edited.
Parameters
------------
disable: :class:`bool`
Whether to disable or enable the buttons.
"""
# if all buttons are already set to `disable` then we don't need to do anything
modified = False
# disable or enable all buttons
for child in self.children:
if isinstance(child, nextcord.ui.Button):
if isinstance(child, nextcord.ui.Button) and child.disabled != disable:
child.disabled = disable
await self._update_view()
modified = True
# update the view
if modified and self.message is not None:
await self._update_view()

async def enable(self):
"""|coro|
Enables all :class:`nextcord.ui.Button` components in the menu.
Enables all :class:`nextcord.ui.Button` components in the menu. If the :attr:`message` is set,
it will be edited with the new :class:`~nextcord.ui.View`.
If all buttons are already enabled, the message will not be edited.
"""
await self._set_all_disabled(False)

async def disable(self):
"""|coro|
Disables all :class:`nextcord.ui.Button` components in the menu.
Disables all :class:`nextcord.ui.Button` components in the menu. If the :attr:`message` is set,
it will be edited with the new :class:`~nextcord.ui.View`.
If all buttons are already disabled, the message will not be edited.
"""
await self._set_all_disabled(True)

async def clear(self):
"""|coro|
Removes all :class:`nextcord.ui.Button` components in the menu.
Removes all :class:`nextcord.ui.Button` components in the menu. If the :attr:`message` is set,
it will be edited with the new :class:`~nextcord.ui.View`.
If there are already no buttons in the view, the message will not be edited.
"""
self.clear_items()
await self._update_view()
# if there are no buttons, then we don't need to do anything
modified = False
# remove all buttons
# copy is required since we are removing during iteration in remove_item
# which needs to be called in order to update the view weights
for child in self.children.copy():
if isinstance(child, nextcord.ui.Button):
self.remove_item(child)
modified = True
# update the view
if modified and self.message is not None:
await self._update_view()

def stop(self):
"""Stops the internal loop and view interactions."""
Expand Down

0 comments on commit b505a20

Please sign in to comment.