139 lines
4.5 KiB
Python
139 lines
4.5 KiB
Python
# SPDX-License-Identifier: MIT
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, ClassVar, List, Optional, Tuple, Union, cast
|
|
|
|
from ..colour import Colour
|
|
from ..components import Container as ContainerComponent
|
|
from ..enums import ComponentType
|
|
from ..utils import copy_doc
|
|
from .item import UIComponent, ensure_ui_component
|
|
|
|
if TYPE_CHECKING:
|
|
from typing_extensions import Self
|
|
|
|
from .action_row import ActionRow, ActionRowMessageComponent
|
|
from .file import File
|
|
from .media_gallery import MediaGallery
|
|
from .section import Section
|
|
from .separator import Separator
|
|
from .text_display import TextDisplay
|
|
|
|
ContainerChildUIComponent = Union[
|
|
ActionRow[ActionRowMessageComponent],
|
|
Section,
|
|
TextDisplay,
|
|
MediaGallery,
|
|
File,
|
|
Separator,
|
|
]
|
|
|
|
__all__ = ("Container",)
|
|
|
|
|
|
class Container(UIComponent):
|
|
"""Represents a UI container.
|
|
|
|
This is visually similar to :class:`.Embed`\\s, and contains other components.
|
|
|
|
.. versionadded:: 2.11
|
|
|
|
Parameters
|
|
----------
|
|
*components: Union[:class:`~.ui.ActionRow`, :class:`~.ui.Section`, :class:`~.ui.TextDisplay`, :class:`~.ui.MediaGallery`, :class:`~.ui.File`, :class:`~.ui.Separator`]
|
|
The components in this container.
|
|
accent_colour: Optional[:class:`.Colour`]
|
|
The accent colour of the container.
|
|
spoiler: :class:`bool`
|
|
Whether the container is marked as a spoiler. Defaults to ``False``.
|
|
id: :class:`int`
|
|
The numeric identifier for the component. Must be unique within the message.
|
|
If set to ``0`` (the default) when sending a component, the API will assign
|
|
sequential identifiers to the components in the message.
|
|
|
|
Attributes
|
|
----------
|
|
children: List[Union[:class:`~.ui.ActionRow`, :class:`~.ui.Section`, :class:`~.ui.TextDisplay`, :class:`~.ui.MediaGallery`, :class:`~.ui.File`, :class:`~.ui.Separator`]]
|
|
The list of child components in this container.
|
|
accent_colour: Optional[:class:`.Colour`]
|
|
The accent colour of the container.
|
|
An alias exists under ``accent_color``.
|
|
spoiler: :class:`bool`
|
|
Whether the container is marked as a spoiler.
|
|
"""
|
|
|
|
__repr_attributes__: ClassVar[Tuple[str, ...]] = (
|
|
"children",
|
|
"accent_colour",
|
|
"spoiler",
|
|
)
|
|
|
|
def __init__(
|
|
self,
|
|
*components: ContainerChildUIComponent,
|
|
accent_colour: Optional[Colour] = None,
|
|
spoiler: bool = False,
|
|
id: int = 0,
|
|
) -> None:
|
|
self._id: int = id
|
|
# this list can be modified without any runtime checks later on,
|
|
# just assume the user knows what they're doing at that point
|
|
self.children: List[ContainerChildUIComponent] = [
|
|
ensure_ui_component(c, "components") for c in components
|
|
]
|
|
self._accent_colour: Optional[Colour] = accent_colour
|
|
self.spoiler: bool = spoiler
|
|
|
|
# these are reimplemented here to store the value in a separate attribute,
|
|
# since `Container` lazily constructs `_underlying`, unlike most components
|
|
@property
|
|
@copy_doc(UIComponent.id)
|
|
def id(self) -> int:
|
|
return self._id
|
|
|
|
@id.setter
|
|
def id(self, value: int) -> None:
|
|
self._id = value
|
|
|
|
@property
|
|
def accent_colour(self) -> Optional[Colour]:
|
|
return self._accent_colour
|
|
|
|
@accent_colour.setter
|
|
def accent_colour(self, value: Optional[Union[int, Colour]]) -> None:
|
|
if isinstance(value, int):
|
|
self._accent_colour = Colour(value)
|
|
elif value is None or isinstance(value, Colour):
|
|
self._accent_colour = value
|
|
else:
|
|
raise TypeError(
|
|
f"Expected Colour, int, or None but received {type(value).__name__} instead."
|
|
)
|
|
|
|
accent_color = accent_colour
|
|
|
|
@property
|
|
def _underlying(self) -> ContainerComponent:
|
|
return ContainerComponent._raw_construct(
|
|
type=ComponentType.container,
|
|
id=self._id,
|
|
children=[comp._underlying for comp in self.children],
|
|
accent_colour=self._accent_colour,
|
|
spoiler=self.spoiler,
|
|
)
|
|
|
|
@classmethod
|
|
def from_component(cls, container: ContainerComponent) -> Self:
|
|
from .action_row import _to_ui_component
|
|
|
|
return cls(
|
|
*cast(
|
|
"List[ContainerChildUIComponent]",
|
|
[_to_ui_component(c) for c in container.children],
|
|
),
|
|
accent_colour=container.accent_colour,
|
|
spoiler=container.spoiler,
|
|
id=container.id,
|
|
)
|