Add initial support for buttons and components

This commit is contained in:
Rapptz
2021-04-25 04:57:29 -04:00
parent f42e922696
commit 98570793e4
17 changed files with 1195 additions and 14 deletions

View File

@ -37,6 +37,7 @@ from .emoji import Emoji
from .partial_emoji import PartialEmoji
from .enums import MessageType, ChannelType, try_enum
from .errors import InvalidArgument, HTTPException
from .components import _component_factory
from .embeds import Embed
from .member import Member
from .flags import MessageFlags
@ -56,6 +57,8 @@ if TYPE_CHECKING:
Reaction as ReactionPayload,
)
from .types.components import Component as ComponentPayload
from .types.member import Member as MemberPayload
from .types.user import User as UserPayload
from .types.embed import Embed as EmbedPayload
@ -581,6 +584,10 @@ class Message(Hashable):
A list of stickers given to the message.
.. versionadded:: 1.6
components: List[:class:`Component`]
A list of components in the message.
.. versionadded:: 2.0
"""
__slots__ = (
@ -613,6 +620,7 @@ class Message(Hashable):
'application',
'activity',
'stickers',
'components',
)
if TYPE_CHECKING:
@ -643,7 +651,8 @@ class Message(Hashable):
self.tts = data['tts']
self.content = data['content']
self.nonce = data.get('nonce')
self.stickers = [Sticker(data=data, state=state) for data in data.get('stickers', [])]
self.stickers = [Sticker(data=d, state=state) for d in data.get('stickers', [])]
self.components = [_component_factory(d) for d in data.get('components', [])]
try:
ref = data['message_reference']
@ -837,6 +846,9 @@ class Message(Hashable):
if role is not None:
self.role_mentions.append(role)
def _handle_components(self, components: List[ComponentPayload]):
self.components = [_component_factory(d) for d in components]
def _rebind_channel_reference(self, new_channel: Union[TextChannel, DMChannel, GroupChannel]) -> None:
self.channel = new_channel
@ -1134,6 +1146,11 @@ class Message(Hashable):
are used instead.
.. versionadded:: 1.4
view: Optional[:class:`~discord.ui.View`]
The updated view to update this message with. If ``None`` is passed then
the view is removed.
.. versionadded:: 2.0
Raises
-------
@ -1191,10 +1208,24 @@ class Message(Hashable):
else:
fields['attachments'] = [a.to_dict() for a in attachments]
try:
view = fields.pop('view')
except KeyError:
# To check for the view afterwards
view = None
else:
if view:
fields['components'] = view.to_components()
else:
fields['components'] = []
if fields:
data = await self._state.http.edit_message(self.channel.id, self.id, **fields)
self._update(data)
if view:
self._state.store_view(view, self.id)
if delete_after is not None:
await self.delete(delay=delete_after)