|
@ -209,6 +209,7 @@ class BaseView: |
|
|
self.__timeout_expiry: Optional[float] = None |
|
|
self.__timeout_expiry: Optional[float] = None |
|
|
self.__timeout_task: Optional[asyncio.Task[None]] = None |
|
|
self.__timeout_task: Optional[asyncio.Task[None]] = None |
|
|
self.__stopped: asyncio.Future[bool] = asyncio.get_running_loop().create_future() |
|
|
self.__stopped: asyncio.Future[bool] = asyncio.get_running_loop().create_future() |
|
|
|
|
|
self.__total_children: int = len(list(self.walk_children())) |
|
|
|
|
|
|
|
|
def _is_v2(self) -> bool: |
|
|
def _is_v2(self) -> bool: |
|
|
return False |
|
|
return False |
|
@ -346,9 +347,14 @@ class BaseView: |
|
|
raise ValueError('v2 items cannot be added to this view') |
|
|
raise ValueError('v2 items cannot be added to this view') |
|
|
|
|
|
|
|
|
item._view = self |
|
|
item._view = self |
|
|
|
|
|
added = 1 |
|
|
|
|
|
|
|
|
if getattr(item, '__discord_ui_update_view__', False): |
|
|
if getattr(item, '__discord_ui_update_view__', False): |
|
|
item._update_children_view(self) # type: ignore |
|
|
item._update_children_view(self) # type: ignore |
|
|
|
|
|
added += len(list(item.walk_children())) # type: ignore |
|
|
|
|
|
|
|
|
|
|
|
if self._is_v2() and self.__total_children + added > 40: |
|
|
|
|
|
raise ValueError('maximum number of children exceeded') |
|
|
|
|
|
|
|
|
self._children.append(item) |
|
|
self._children.append(item) |
|
|
return self |
|
|
return self |
|
@ -369,6 +375,16 @@ class BaseView: |
|
|
self._children.remove(item) |
|
|
self._children.remove(item) |
|
|
except ValueError: |
|
|
except ValueError: |
|
|
pass |
|
|
pass |
|
|
|
|
|
else: |
|
|
|
|
|
removed = 1 |
|
|
|
|
|
if getattr(item, '__discord_ui_update_view__', False): |
|
|
|
|
|
removed += len(list(item.walk_children())) # type: ignore |
|
|
|
|
|
|
|
|
|
|
|
if self.__total_children - removed < 0: |
|
|
|
|
|
self.__total_children = 0 |
|
|
|
|
|
else: |
|
|
|
|
|
self.__total_children -= removed |
|
|
|
|
|
|
|
|
return self |
|
|
return self |
|
|
|
|
|
|
|
|
def clear_items(self) -> Self: |
|
|
def clear_items(self) -> Self: |
|
@ -378,6 +394,7 @@ class BaseView: |
|
|
chaining. |
|
|
chaining. |
|
|
""" |
|
|
""" |
|
|
self._children.clear() |
|
|
self._children.clear() |
|
|
|
|
|
self.__total_children = 0 |
|
|
return self |
|
|
return self |
|
|
|
|
|
|
|
|
def get_item_by_id(self, id: int, /) -> Optional[Item[Self]]: |
|
|
def get_item_by_id(self, id: int, /) -> Optional[Item[Self]]: |
|
@ -568,6 +585,23 @@ class BaseView: |
|
|
""" |
|
|
""" |
|
|
return await self.__stopped |
|
|
return await self.__stopped |
|
|
|
|
|
|
|
|
|
|
|
def walk_children(self): |
|
|
|
|
|
"""An iterator that recursively walks through all the children of this view |
|
|
|
|
|
and it's children, if applicable. |
|
|
|
|
|
|
|
|
|
|
|
Yields |
|
|
|
|
|
------ |
|
|
|
|
|
:class:`Item` |
|
|
|
|
|
An item in the view. |
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
for child in self.children: |
|
|
|
|
|
yield child |
|
|
|
|
|
|
|
|
|
|
|
if getattr(child, '__discord_ui_update_view__', False): |
|
|
|
|
|
# if it has this attribute then it can contain children |
|
|
|
|
|
yield from child.walk_children() # type: ignore |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class View(BaseView): |
|
|
class View(BaseView): |
|
|
"""Represents a UI view. |
|
|
"""Represents a UI view. |
|
@ -723,6 +757,10 @@ class LayoutView(BaseView): |
|
|
|
|
|
|
|
|
def __init__(self, *, timeout: Optional[float] = 180.0) -> None: |
|
|
def __init__(self, *, timeout: Optional[float] = 180.0) -> None: |
|
|
super().__init__(timeout=timeout) |
|
|
super().__init__(timeout=timeout) |
|
|
|
|
|
self.__total_children: int = len(list(self.walk_children())) |
|
|
|
|
|
|
|
|
|
|
|
if self.__total_children > 40: |
|
|
|
|
|
raise ValueError('maximum number of children exceeded') |
|
|
|
|
|
|
|
|
def __init_subclass__(cls) -> None: |
|
|
def __init_subclass__(cls) -> None: |
|
|
children: Dict[str, ItemLike] = {} |
|
|
children: Dict[str, ItemLike] = {} |
|
@ -739,9 +777,6 @@ class LayoutView(BaseView): |
|
|
elif hasattr(member, '__discord_ui_model_type__') and getattr(member, '__discord_ui_parent__', None): |
|
|
elif hasattr(member, '__discord_ui_model_type__') and getattr(member, '__discord_ui_parent__', None): |
|
|
callback_children[name] = member |
|
|
callback_children[name] = member |
|
|
|
|
|
|
|
|
if len(children) > 10: |
|
|
|
|
|
raise TypeError('LayoutView cannot have more than 10 top-level children') |
|
|
|
|
|
|
|
|
|
|
|
children.update(callback_children) |
|
|
children.update(callback_children) |
|
|
cls.__view_children_items__ = children |
|
|
cls.__view_children_items__ = children |
|
|
|
|
|
|
|
@ -761,7 +796,7 @@ class LayoutView(BaseView): |
|
|
return components |
|
|
return components |
|
|
|
|
|
|
|
|
def add_item(self, item: Item[Any]) -> Self: |
|
|
def add_item(self, item: Item[Any]) -> Self: |
|
|
if len(self._children) >= 10: |
|
|
if self.__total_children >= 40: |
|
|
raise ValueError('maximum number of children exceeded') |
|
|
raise ValueError('maximum number of children exceeded') |
|
|
super().add_item(item) |
|
|
super().add_item(item) |
|
|
return self |
|
|
return self |
|
@ -798,23 +833,6 @@ class LayoutView(BaseView): |
|
|
|
|
|
|
|
|
return view |
|
|
return view |
|
|
|
|
|
|
|
|
def walk_children(self): |
|
|
|
|
|
"""An iterator that recursively walks through all the children of this view |
|
|
|
|
|
and it's children, if applicable. |
|
|
|
|
|
|
|
|
|
|
|
Yields |
|
|
|
|
|
------ |
|
|
|
|
|
:class:`Item` |
|
|
|
|
|
An item in the view. |
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
for child in self.children: |
|
|
|
|
|
yield child |
|
|
|
|
|
|
|
|
|
|
|
if getattr(child, '__discord_ui_update_view__', False): |
|
|
|
|
|
# if it has this attribute then it can contain children |
|
|
|
|
|
yield from child.walk_children() # type: ignore |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ViewStore: |
|
|
class ViewStore: |
|
|
def __init__(self, state: ConnectionState): |
|
|
def __init__(self, state: ConnectionState): |
|
|