Skip to content

Commit 9568390

Browse files
feat: Add a wait_for_select method (#1142)
* feat: add a `wait_for_select` function to support new select menu types and make receiving values easier * refactor: correct typing and add information about the method * docs: add missing word * docs: add missing colon * refactor: remove duplicate code * refactor: remove duplicate code * docs: typo * docs: fix cross-reference in docstrings Co-authored-by: mAxYoLo01 <[email protected]>
1 parent 160332a commit 9568390

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

interactions/api/gateway/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,10 +386,10 @@ def _dispatch_event(self, event: str, data: dict) -> None:
386386
__args.append(_context.data.values)
387387
else:
388388
_list = [] # temp storage for items
389+
_data = self.__select_option_type_context(
390+
_context, _context.data.component_type.value
391+
) # resolved.
389392
for value in _context.data._json.get("values"):
390-
_data = self.__select_option_type_context(
391-
_context, _context.data.component_type.value
392-
) # resolved.
393393
_list.append(_data[value])
394394
__args.append(_list)
395395

interactions/client/bot.py

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
from ..api import WebSocketClient as WSClient
1414
from ..api.error import LibraryException
1515
from ..api.http.client import HTTPClient
16+
from ..api.models.channel import Channel
1617
from ..api.models.flags import Intents, Permissions
1718
from ..api.models.guild import Guild
19+
from ..api.models.member import Member
1820
from ..api.models.message import Message
1921
from ..api.models.misc import Image, Snowflake
2022
from ..api.models.presence import ClientPresence
23+
from ..api.models.role import Role
2124
from ..api.models.team import Application
2225
from ..api.models.user import User
2326
from ..base import get_logger
@@ -1596,9 +1599,10 @@ async def wait_for_component(
15961599
Waits for a component to be interacted with, and returns the resulting context.
15971600
15981601
.. note::
1599-
If you are waiting for a select menu, you can find the selected values in ``ctx.data.values``
1602+
If you are waiting for a select menu, you can find the selected values in ``ctx.data.values``.
1603+
Another possibility is using the :meth:`.Client.wait_for_select` method.
16001604
1601-
:param Union[str, interactions.Button, interactions.SelectMenu, List[Union[str, interactions.Button, interactions.SelectMenu]]] components: The component(s) to wait for
1605+
:param Union[str, Button, SelectMenu, List[Union[str, Button, SelectMenu]]] components: The component(s) to wait for
16021606
:param Union[interactions.Message, int, List[Union[interactions.Message, int]]] messages: The message(s) to check for
16031607
:param Callable check: A function or coroutine to call, which should return a truthy value if the data should be returned
16041608
:param float timeout: How long to wait for the event before raising an error
@@ -1653,6 +1657,57 @@ def _check(ctx: ComponentContext) -> bool:
16531657

16541658
return await self.wait_for("on_component", check=_check, timeout=timeout)
16551659

1660+
async def wait_for_select(
1661+
self,
1662+
components: Union[
1663+
Union[str, SelectMenu],
1664+
List[Union[str, SelectMenu]],
1665+
] = None,
1666+
messages: Union[Message, int, List[Union[Message, int]]] = None,
1667+
check: Optional[Callable[..., Union[bool, Awaitable[bool]]]] = None,
1668+
timeout: Optional[float] = None,
1669+
) -> Tuple[ComponentContext, List[Union[str, Member, User, Role, Channel]]]:
1670+
"""
1671+
Waits for a select menu to be interacted with, and returns the resulting context and a list of the selected values.
1672+
1673+
The method can be used like this:
1674+
1675+
.. code-block:: python
1676+
1677+
ctx, values = await bot.wait_for_select(custom_id)
1678+
1679+
In this case ``ctx`` will be your normal context and ``values`` will be a list of :class:`str`, :class:`.Member`, :class:`.User`, :class:`.Channel` or :class:`.Role` objects,
1680+
depending on which select type you received.
1681+
1682+
1683+
:param Union[str, SelectMenu, List[Union[str, SelectMenu]]] components: The component(s) to wait for
1684+
:param Union[interactions.Message, int, List[Union[interactions.Message, int]]] messages: The message(s) to check for
1685+
:param Callable check: A function or coroutine to call, which should return a truthy value if the data should be returned
1686+
:param float timeout: How long to wait for the event before raising an error
1687+
:return: The ComponentContext and list of selections of the dispatched event
1688+
:rtype: Tuple[ComponentContext, Union[List[str], List[Member], List[User], List[Channel], List[Role]]]
1689+
"""
1690+
1691+
def _check(_ctx: ComponentContext) -> bool:
1692+
if _ctx.data.component_type.value not in {4, 5, 6, 7, 8}:
1693+
return False
1694+
return check(_ctx) if check else True
1695+
1696+
ctx: ComponentContext = await self.wait_for_component(
1697+
components, messages, check=_check, timeout=timeout
1698+
)
1699+
1700+
if ctx.data.component_type == 4:
1701+
return ctx, ctx.data.values
1702+
1703+
_list = [] # temp storage for items
1704+
_data = self._websocket._WebSocketClient__select_option_type_context(
1705+
ctx, ctx.data.component_type.value
1706+
) # resolved.
1707+
for value in ctx.data.values:
1708+
_list.append(_data[value])
1709+
return ctx, _list
1710+
16561711
async def wait_for_modal(
16571712
self,
16581713
modals: Union[Modal, str, List[Union[Modal, str]]],

0 commit comments

Comments
 (0)