Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Modal.children to be a property, allow instantiating with list of InputText components #1311

Merged
merged 4 commits into from
May 8, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions discord/ui/modal.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class Modal:

Parameters
----------
children: :class:`InputText`
The initial InputText fields that are displayed in the modal dialog.
title: :class:`str`
The title of the modal dialog.
Must be 45 characters or fewer.
Expand All @@ -37,15 +39,15 @@ class Modal:
Must be 100 characters or fewer.
"""

def __init__(self, title: str, custom_id: Optional[str] = None) -> None:
def __init__(self, *children: InputText, title: str, custom_id: Optional[str] = None) -> None:
if not isinstance(custom_id, str) and custom_id is not None:
raise TypeError(f"expected custom_id to be str, not {custom_id.__class__.__name__}")
self._custom_id: Optional[str] = custom_id or os.urandom(16).hex()
if len(str(title)) > 45:
if len(title) > 45:
raise ValueError("title must be 45 characters or fewer")
self._title = title
self.children: List[InputText] = []
self._weights = _ModalWeights(self.children)
self._children: List[InputText] = list(children)
self._weights = _ModalWeights(self._children)
loop = asyncio.get_running_loop()
self._stopped: asyncio.Future[bool] = loop.create_future()

Expand All @@ -62,6 +64,19 @@ def title(self, value: str):
raise TypeError(f"expected title to be str, not {value.__class__.__name__}")
self._title = value

@property
def children(self) -> List[InputText]:
"""The child components associated with the modal dialog."""
return self._children

@children.setter
def children(self, value: List[InputText]):
for item in value:
if not isinstance(item, InputText):
raise TypeError(f"all Modal children must be InputText, not {item.__class__.__name__}")
self._weights = _ModalWeights(self._children)
self._children = value

@property
def custom_id(self) -> str:
"""The ID of the modal dialog that gets received during an interaction."""
Expand Down Expand Up @@ -92,7 +107,7 @@ def to_components(self) -> List[Dict[str, Any]]:
def key(item: InputText) -> int:
return item._rendered_row or 0

children = sorted(self.children, key=key)
children = sorted(self._children, key=key)
components: List[Dict[str, Any]] = []
for _, group in groupby(children, key=key):
children = [item.to_component_dict() for item in group]
Expand All @@ -117,14 +132,14 @@ def add_item(self, item: InputText):
The item to add to the modal dialog
"""

if len(self.children) > 5:
if len(self._children) > 5:
raise ValueError("You can only have up to 5 items in a modal dialog.")

if not isinstance(item, InputText):
raise TypeError(f"expected InputText not {item.__class__!r}")

self._weights.add_item(item)
self.children.append(item)
self._children.append(item)

def remove_item(self, item: InputText):
"""Removes an InputText component from the modal dialog.
Expand All @@ -135,7 +150,7 @@ def remove_item(self, item: InputText):
The item to remove from the modal dialog.
"""
try:
self.children.remove(item)
self._children.remove(item)
except ValueError:
pass

Expand Down