Browse Source

chore: add id attr to components and black item.py

pull/10166/head
DA-344 3 months ago
parent
commit
7601533fe9
  1. 112
      discord/components.py
  2. 5
      discord/ui/action_row.py
  3. 3
      discord/ui/item.py

112
discord/components.py

@ -177,13 +177,18 @@ class ActionRow(Component):
------------
children: List[Union[:class:`Button`, :class:`SelectMenu`, :class:`TextInput`]]
The children components that this holds, if any.
id: Optional[:class:`int`]
The ID of this component.
.. versionadded:: 2.6
"""
__slots__: Tuple[str, ...] = ('children',)
__slots__: Tuple[str, ...] = ('children', 'id')
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
def __init__(self, data: ActionRowPayload, /) -> None:
self.id: Optional[int] = data.get('id')
self.children: List[ActionRowChildComponentType] = []
for component_data in data.get('components', []):
@ -198,10 +203,13 @@ class ActionRow(Component):
return ComponentType.action_row
def to_dict(self) -> ActionRowPayload:
return {
payload: ActionRowPayload = {
'type': self.type.value,
'components': [child.to_dict() for child in self.children],
}
if self.id is not None:
payload['id'] = self.id
return payload
class Button(Component):
@ -235,6 +243,10 @@ class Button(Component):
The SKU ID this button sends you to, if available.
.. versionadded:: 2.4
id: Optional[:class:`int`]
The ID of this component.
.. versionadded:: 2.6
"""
__slots__: Tuple[str, ...] = (
@ -245,11 +257,13 @@ class Button(Component):
'label',
'emoji',
'sku_id',
'id',
)
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
def __init__(self, data: ButtonComponentPayload, /) -> None:
self.id: Optional[int] = data.get('id')
self.style: ButtonStyle = try_enum(ButtonStyle, data['style'])
self.custom_id: Optional[str] = data.get('custom_id')
self.url: Optional[str] = data.get('url')
@ -278,6 +292,9 @@ class Button(Component):
'disabled': self.disabled,
}
if self.id is not None:
payload['id'] = self.id
if self.sku_id:
payload['sku_id'] = str(self.sku_id)
@ -329,6 +346,10 @@ class SelectMenu(Component):
Whether the select is disabled or not.
channel_types: List[:class:`.ChannelType`]
A list of channel types that are allowed to be chosen in this select menu.
id: Optional[:class:`int`]
The ID of this component.
.. versionadded:: 2.6
"""
__slots__: Tuple[str, ...] = (
@ -341,6 +362,7 @@ class SelectMenu(Component):
'disabled',
'channel_types',
'default_values',
'id',
)
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
@ -357,6 +379,7 @@ class SelectMenu(Component):
self.default_values: List[SelectDefaultValue] = [
SelectDefaultValue.from_dict(d) for d in data.get('default_values', [])
]
self.id: Optional[int] = data.get('id')
def to_dict(self) -> SelectMenuPayload:
payload: SelectMenuPayload = {
@ -366,6 +389,8 @@ class SelectMenu(Component):
'max_values': self.max_values,
'disabled': self.disabled,
}
if self.id is not None:
payload['id'] = self.id
if self.placeholder:
payload['placeholder'] = self.placeholder
if self.options:
@ -531,6 +556,10 @@ class TextInput(Component):
The minimum length of the text input.
max_length: Optional[:class:`int`]
The maximum length of the text input.
id: Optional[:class:`int`]
The ID of this component.
.. versionadded:: 2.6
"""
__slots__: Tuple[str, ...] = (
@ -542,6 +571,7 @@ class TextInput(Component):
'required',
'min_length',
'max_length',
'id',
)
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
@ -555,6 +585,7 @@ class TextInput(Component):
self.required: bool = data.get('required', True)
self.min_length: Optional[int] = data.get('min_length')
self.max_length: Optional[int] = data.get('max_length')
self.id: Optional[int] = data.get('id')
@property
def type(self) -> Literal[ComponentType.text_input]:
@ -570,6 +601,9 @@ class TextInput(Component):
'required': self.required,
}
if self.id is not None:
payload['id'] = self.id
if self.placeholder:
payload['placeholder'] = self.placeholder
@ -721,11 +755,14 @@ class SectionComponent(Component):
The components on this section.
accessory: :class:`Component`
The section accessory.
id: Optional[:class:`int`]
The ID of this component.
"""
__slots__ = (
'components',
'accessory',
'id',
)
__repr_info__ = __slots__
@ -733,6 +770,7 @@ class SectionComponent(Component):
def __init__(self, data: SectionComponentPayload, state: Optional[ConnectionState]) -> None:
self.components: List[SectionComponentType] = []
self.accessory: Component = _component_factory(data['accessory'], state) # type: ignore
self.id: Optional[int] = data.get('id')
for component_data in data['components']:
component = _component_factory(component_data, state)
@ -749,6 +787,10 @@ class SectionComponent(Component):
'components': [c.to_dict() for c in self.components],
'accessory': self.accessory.to_dict(),
}
if self.id is not None:
payload['id'] = self.id
return payload
@ -772,12 +814,15 @@ class ThumbnailComponent(Component):
The description shown within this thumbnail.
spoiler: :class:`bool`
Whether this thumbnail is flagged as a spoiler.
id: Optional[:class:`int`]
The ID of this component.
"""
__slots__ = (
'media',
'spoiler',
'description',
'id',
)
__repr_info__ = __slots__
@ -790,19 +835,25 @@ class ThumbnailComponent(Component):
self.media: UnfurledMediaItem = UnfurledMediaItem._from_data(data['media'], state)
self.description: Optional[str] = data.get('description')
self.spoiler: bool = data.get('spoiler', False)
self.id: Optional[int] = data.get('id')
@property
def type(self) -> Literal[ComponentType.thumbnail]:
return ComponentType.thumbnail
def to_dict(self) -> ThumbnailComponentPayload:
return {
'media': self.media.to_dict(), # pyright: ignore[reportReturnType]
payload = {
'media': self.media.to_dict(),
'description': self.description,
'spoiler': self.spoiler,
'type': self.type.value,
}
if self.id is not None:
payload['id'] = self.id
return payload # type: ignore
class TextDisplay(Component):
"""Represents a text display from the Discord Bot UI Kit.
@ -820,24 +871,30 @@ class TextDisplay(Component):
----------
content: :class:`str`
The content that this display shows.
id: Optional[:class:`int`]
The ID of this component.
"""
__slots__ = ('content',)
__slots__ = ('content', 'id')
__repr_info__ = __slots__
def __init__(self, data: TextComponentPayload) -> None:
self.content: str = data['content']
self.id: Optional[int] = data.get('id')
@property
def type(self) -> Literal[ComponentType.text_display]:
return ComponentType.text_display
def to_dict(self) -> TextComponentPayload:
return {
payload: TextComponentPayload = {
'type': self.type.value,
'content': self.content,
}
if self.id is not None:
payload['id'] = self.id
return payload
class UnfurledMediaItem(AssetMixin):
@ -1006,24 +1063,30 @@ class MediaGalleryComponent(Component):
----------
items: List[:class:`MediaGalleryItem`]
The items this gallery has.
id: Optional[:class:`int`]
The ID of this component.
"""
__slots__ = ('items',)
__slots__ = ('items', 'id')
__repr_info__ = __slots__
def __init__(self, data: MediaGalleryComponentPayload, state: Optional[ConnectionState]) -> None:
self.items: List[MediaGalleryItem] = MediaGalleryItem._from_gallery(data['items'], state)
self.id: Optional[int] = data.get('id')
@property
def type(self) -> Literal[ComponentType.media_gallery]:
return ComponentType.media_gallery
def to_dict(self) -> MediaGalleryComponentPayload:
return {
payload: MediaGalleryComponentPayload = {
'type': self.type.value,
'items': [item.to_dict() for item in self.items],
}
if self.id is not None:
payload['id'] = self.id
return payload
class FileComponent(Component):
@ -1044,11 +1107,14 @@ class FileComponent(Component):
The unfurled attachment contents of the file.
spoiler: :class:`bool`
Whether this file is flagged as a spoiler.
id: Optional[:class:`int`]
The ID of this component.
"""
__slots__ = (
'media',
'spoiler',
'id',
)
__repr_info__ = __slots__
@ -1056,17 +1122,21 @@ class FileComponent(Component):
def __init__(self, data: FileComponentPayload, state: Optional[ConnectionState]) -> None:
self.media: UnfurledMediaItem = UnfurledMediaItem._from_data(data['file'], state)
self.spoiler: bool = data.get('spoiler', False)
self.id: Optional[int] = data.get('id')
@property
def type(self) -> Literal[ComponentType.file]:
return ComponentType.file
def to_dict(self) -> FileComponentPayload:
return {
payload: FileComponentPayload = {
'type': self.type.value,
'file': self.media.to_dict(), # type: ignore
'spoiler': self.spoiler,
}
if self.id is not None:
payload['id'] = self.id
return payload
class SeparatorComponent(Component):
@ -1087,11 +1157,14 @@ class SeparatorComponent(Component):
The spacing size of the separator.
visible: :class:`bool`
Whether this separator is visible and shows a divider.
id: Optional[:class:`int`]
The ID of this component.
"""
__slots__ = (
'spacing',
'visible',
'id',
)
__repr_info__ = __slots__
@ -1102,17 +1175,21 @@ class SeparatorComponent(Component):
) -> None:
self.spacing: SeparatorSize = try_enum(SeparatorSize, data.get('spacing', 1))
self.visible: bool = data.get('divider', True)
self.id: Optional[int] = data.get('id')
@property
def type(self) -> Literal[ComponentType.separator]:
return ComponentType.separator
def to_dict(self) -> SeparatorComponentPayload:
return {
payload: SeparatorComponentPayload = {
'type': self.type.value,
'divider': self.visible,
'spacing': self.spacing.value,
}
if self.id is not None:
payload['id'] = self.id
return payload
class Container(Component):
@ -1133,10 +1210,13 @@ class Container(Component):
This container's children.
spoiler: :class:`bool`
Whether this container is flagged as a spoiler.
id: Optional[:class:`int`]
The ID of this component.
"""
def __init__(self, data: ContainerComponentPayload, state: Optional[ConnectionState]) -> None:
self.children: List[Component] = []
self.id: Optional[int] = data.get('id')
for child in data['components']:
comp = _component_factory(child, state)
@ -1158,6 +1238,18 @@ class Container(Component):
accent_color = accent_colour
def to_dict(self) -> ContainerComponentPayload:
payload: ContainerComponentPayload = {
'type': self.type.value, # type: ignore
'spoiler': self.spoiler,
'components': [c.to_dict() for c in self.children],
}
if self.id is not None:
payload['id'] = self.id
if self._colour:
payload['accent_color'] = self._colour.value
return payload
def _component_factory(data: ComponentPayload, state: Optional[ConnectionState] = None) -> Optional[Component]:
if data['type'] == 1:

5
discord/ui/action_row.py

@ -234,10 +234,13 @@ class ActionRow(Item[V]):
for item in self._children:
components.append(item.to_component_dict())
return {
base = {
'type': self.type.value,
'components': components,
}
if self.id is not None:
base['id'] = self.id
return base
def button(
self,

3
discord/ui/item.py

@ -127,8 +127,7 @@ class Item(Generic[V]):
@property
def id(self) -> Optional[int]:
"""Optional[:class:`int`]: The ID of this component.
"""
"""Optional[:class:`int`]: The ID of this component."""
return self._id
@id.setter

Loading…
Cancel
Save