Browse Source

Add support for selects

pull/10109/head
dolfies 4 years ago
parent
commit
7473797acb
  1. 62
      discord/components.py

62
discord/components.py

@ -260,14 +260,15 @@ class Button(Component):
'component_type': 2, 'component_type': 2,
'custom_id': self.custom_id, 'custom_id': self.custom_id,
}, },
'guild_id': message.guild and str(message.guild.id),
'message_flags': message.flags.value, 'message_flags': message.flags.value,
'message_id': str(message.id), 'message_id': str(message.id),
'nonce': str(time_snowflake(datetime.utcnow())), 'nonce': str(time_snowflake(datetime.utcnow())),
'type': 3, # Should be an enum but eh 'type': 3, # Should be an enum but eh
} }
await state.http.interact(payload) if message.guild:
payload['guild_id'] = str(message.guild.id)
await state.http.interact(payload)
try: try:
i = await state.client.wait_for( i = await state.client.wait_for(
'interaction', 'interaction',
@ -275,7 +276,7 @@ class Button(Component):
timeout=5, timeout=5,
) )
except TimeoutError as exc: except TimeoutError as exc:
raise InvalidData('Did not receive a response from Discord.') from exc raise InvalidData('Did not receive a response from Discord') from exc
return i return i
@ -295,14 +296,14 @@ class SelectMenu(Component):
The placeholder text that is shown if nothing is selected, if any. The placeholder text that is shown if nothing is selected, if any.
min_values: :class:`int` min_values: :class:`int`
The minimum number of items that must be chosen for this select menu. The minimum number of items that must be chosen for this select menu.
Defaults to 1 and must be between 1 and 25.
max_values: :class:`int` max_values: :class:`int`
The maximum number of items that must be chosen for this select menu. The maximum number of items that must be chosen for this select menu.
Defaults to 1 and must be between 1 and 25.
options: List[:class:`SelectOption`] options: List[:class:`SelectOption`]
A list of options that can be selected in this menu. A list of options that can be selected in this menu.
disabled: :class:`bool` disabled: :class:`bool`
Whether the select is disabled or not. Whether the select is disabled or not.
hash: :class:`str`
Unknown.
message: :class:`Message` message: :class:`Message`
The originating message, if any. The originating message, if any.
""" """
@ -314,6 +315,7 @@ class SelectMenu(Component):
'max_values', 'max_values',
'options', 'options',
'disabled', 'disabled',
'hash',
) )
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__ __repr_info__: ClassVar[Tuple[str, ...]] = __slots__
@ -327,6 +329,7 @@ class SelectMenu(Component):
self.max_values: int = data.get('max_values', 1) self.max_values: int = data.get('max_values', 1)
self.options: List[SelectOption] = [SelectOption.from_dict(option) for option in data.get('options', [])] self.options: List[SelectOption] = [SelectOption.from_dict(option) for option in data.get('options', [])]
self.disabled: bool = data.get('disabled', False) self.disabled: bool = data.get('disabled', False)
self.hash: str = data.get('hash', '')
def to_dict(self) -> SelectMenuPayload: def to_dict(self) -> SelectMenuPayload:
payload: SelectMenuPayload = { payload: SelectMenuPayload = {
@ -343,6 +346,55 @@ class SelectMenu(Component):
return payload return payload
async def choose(self, *options: SelectOption):
"""|coro|
Chooses the given options from the select menu.
Raises
-------
InvalidData
Didn't receive a response from Discord.
Doesn't mean the interaction failed.
NotFound
The originating message was not found.
HTTPException
Choosing the options failed.
Returns
--------
:class:`Interaction`
The interaction that was created.
"""
message = self.message
state = message._state
payload = {
'application_id': str(message.application_id),
'channel_id': str(message.channel.id),
'data': {
'component_type': 3,
'custom_id': self.custom_id,
'values': [op.value for op in options]
},
'message_flags': message.flags.value,
'message_id': str(message.id),
'nonce': str(time_snowflake(datetime.utcnow())),
'type': 3, # Should be an enum but eh
}
if message.guild:
payload['guild_id'] = str(message.guild.id)
await state.http.interact(payload)
try:
i = await state.client.wait_for(
'interaction',
check=lambda d: d.nonce == payload['nonce'],
timeout=5,
)
except TimeoutError as exc:
raise InvalidData('Did not receive a response from Discord') from exc
return i
class SelectOption: class SelectOption:
"""Represents a select menu's option. """Represents a select menu's option.

Loading…
Cancel
Save