mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 18:23:12 +00:00
816 lines
27 KiB
Python
816 lines
27 KiB
Python
"""
|
|
This type stub file was generated by pyright.
|
|
"""
|
|
|
|
import abc
|
|
import discord
|
|
from typing import Any, Callable, ClassVar, Final, Generic, List, Literal, NamedTuple, Optional, Set, TYPE_CHECKING, Tuple, TypeVar, Union, overload
|
|
from datetime import datetime
|
|
from typing_extensions import Self
|
|
from collections.abc import Sequence
|
|
from enum import Enum
|
|
from discord.ext.commands import Context
|
|
from discord.utils import MISSING
|
|
from .decorators import ensure_not_primed
|
|
from .errors import *
|
|
|
|
"""
|
|
MIT License
|
|
|
|
Copyright (c) 2021-present @defxult
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
copy of this software and associated documentation files (the "Software"),
|
|
to deal in the Software without restriction, including without limitation
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
DEALINGS IN THE SOFTWARE.
|
|
"""
|
|
if TYPE_CHECKING:
|
|
...
|
|
_DYNAMIC_EMBED_LIMIT: Final[int] = ...
|
|
_DEFAULT_STYLE: Final[str] = ...
|
|
DEFAULT_BUTTONS = ...
|
|
DEFAULT = MISSING
|
|
GB = TypeVar('GB', bound='_BaseButton')
|
|
M = TypeVar('M', bound='_BaseMenu')
|
|
class Page:
|
|
"""Represents a single "page" in the pagination process
|
|
|
|
.. added:: v3.1.0
|
|
"""
|
|
__slots__ = ...
|
|
def __init__(self, *, content: Optional[str] = ..., embed: Optional[discord.Embed] = ..., files: Optional[List[discord.File]] = ...) -> None:
|
|
...
|
|
|
|
def __repr__(self) -> str:
|
|
...
|
|
|
|
@staticmethod
|
|
def from_embeds(embeds: Sequence[discord.Embed]) -> List[Page]:
|
|
"""|static method|
|
|
|
|
Converts a sequence of embeds into a list of :class:`Page`
|
|
"""
|
|
...
|
|
|
|
|
|
|
|
class PaginationEmojis:
|
|
"""A set of basic emojis for your convenience to use for your buttons emoji
|
|
- ◀️ as `BACK_BUTTON`
|
|
- ▶️ as `NEXT_BUTTON`
|
|
- ⏪ as `FIRST_PAGE`
|
|
- ⏩ as `LAST_PAGE`
|
|
- 🔢 as `GO_TO_PAGE`
|
|
- ⏹️ as `END_SESSION`
|
|
"""
|
|
BACK_BUTTON: ClassVar[str] = ...
|
|
NEXT_BUTTON: ClassVar[str] = ...
|
|
FIRST_PAGE: ClassVar[str] = ...
|
|
LAST_PAGE: ClassVar[str] = ...
|
|
GO_TO_PAGE: ClassVar[str] = ...
|
|
END_SESSION: ClassVar[str] = ...
|
|
|
|
|
|
class _PageController:
|
|
def __init__(self, pages: List[Page]) -> None:
|
|
...
|
|
|
|
@property
|
|
def current_page(self) -> Page:
|
|
...
|
|
|
|
@property
|
|
def total_pages(self) -> int:
|
|
"""Return the total amount of pages registered to the menu"""
|
|
...
|
|
|
|
def validate_index(self) -> Page:
|
|
"""If the index is out of bounds, assign the appropriate values so the pagination process can continue and return the associated page"""
|
|
...
|
|
|
|
def skip_loop(self, action: str, amount: int) -> None:
|
|
"""Using `self.index += amount` does not work because this library is used to operating on a +-1 basis. This loop
|
|
provides a simple way to still operate on the +-1 standard.
|
|
"""
|
|
...
|
|
|
|
def skip(self, skip: _BaseButton.Skip) -> Page:
|
|
"""Return the page that the skip value was set to"""
|
|
...
|
|
|
|
def next(self) -> Page:
|
|
"""Return the next page in the pagination process"""
|
|
...
|
|
|
|
def prev(self) -> Page:
|
|
"""Return the previous page in the pagination process"""
|
|
...
|
|
|
|
def first_page(self) -> Page:
|
|
"""Return the first page in the pagination process"""
|
|
...
|
|
|
|
def last_page(self) -> Page:
|
|
"""Return the last page in the pagination process"""
|
|
...
|
|
|
|
|
|
|
|
class _MenuType(Enum):
|
|
TypeEmbed = ...
|
|
TypeEmbedDynamic = ...
|
|
TypeText = ...
|
|
|
|
|
|
MenuType = _MenuType
|
|
class _LimitDetails(NamedTuple):
|
|
limit: int
|
|
per: str
|
|
message: str
|
|
set_by_user: bool = ...
|
|
@classmethod
|
|
def default(cls) -> Self:
|
|
...
|
|
|
|
|
|
|
|
class _BaseButton(Generic[GB], metaclass=abc.ABCMeta):
|
|
Emojis: ClassVar[PaginationEmojis] = ...
|
|
def __init__(self, name: str, event: Optional[_BaseButton.Event], skip: _BaseButton.Skip) -> None:
|
|
...
|
|
|
|
@property
|
|
@abc.abstractmethod
|
|
def menu(self):
|
|
...
|
|
|
|
@property
|
|
def clicked_by(self) -> Set[discord.Member]:
|
|
"""
|
|
Returns
|
|
-------
|
|
Set[:class:`discord.Member`]: The members who clicked the button
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def total_clicks(self) -> int:
|
|
"""
|
|
Returns
|
|
-------
|
|
:class:`int`: The amount of clicks on the button
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def last_clicked(self) -> Optional[datetime]:
|
|
"""
|
|
Returns
|
|
-------
|
|
Optional[:class:`datetime.datetime`]: The time in UTC for when the button was last clicked. Can be :class:`None` if the button has not been clicked
|
|
"""
|
|
...
|
|
|
|
class Skip:
|
|
"""Initialize a skip button with the appropriate values
|
|
|
|
Parameters
|
|
----------
|
|
action: :class:`str`
|
|
Whether to go forward in the pagination process ("+") or backwards ("-")
|
|
|
|
amount: :class:`int`
|
|
The amount of pages to skip. Must be >= 1. If value is <= 0, it is implicitly set to 2
|
|
"""
|
|
def __init__(self, action: Literal['+', '-'], amount: int) -> None:
|
|
...
|
|
|
|
|
|
|
|
class Event:
|
|
"""Set a button to be disabled or removed when it has been pressed a certain amount of times. If the button is a :class:`ReactionButton`, only the "remove" event is available
|
|
|
|
Parameters
|
|
----------
|
|
event: :class:`str`
|
|
The action to take. Can either be "disable" or "remove"
|
|
|
|
value: :class:`int`
|
|
The amount set for the specified event. Must be >= 1. If value is <= 0, it is implicitly set to 1"""
|
|
_DISABLE = ...
|
|
_REMOVE = ...
|
|
def __init__(self, event_type: Literal['disable', 'remove'], value: int) -> None:
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
class _BaseMenu(metaclass=abc.ABCMeta):
|
|
TypeEmbed: Final[_MenuType] = ...
|
|
TypeEmbedDynamic: Final[_MenuType] = ...
|
|
TypeText: Final[_MenuType] = ...
|
|
_sessions_limit_details = ...
|
|
_active_sessions: List[Self]
|
|
def __init__(self, method: Union[Context, discord.Interaction], /, menu_type: _MenuType, **kwargs) -> None:
|
|
...
|
|
|
|
@abc.abstractmethod
|
|
def remove_all_buttons(self):
|
|
...
|
|
|
|
@abc.abstractmethod
|
|
def get_button(self):
|
|
...
|
|
|
|
@abc.abstractmethod
|
|
def remove_button(self):
|
|
...
|
|
|
|
@abc.abstractmethod
|
|
def add_button(self):
|
|
...
|
|
|
|
@abc.abstractmethod
|
|
def add_buttons(self):
|
|
...
|
|
|
|
@abc.abstractmethod
|
|
def stop(self):
|
|
...
|
|
|
|
@abc.abstractmethod
|
|
async def start(self):
|
|
...
|
|
|
|
@abc.abstractmethod
|
|
async def quick_start(cls):
|
|
...
|
|
|
|
@staticmethod
|
|
def separate(values: Sequence[Any]) -> Tuple[List[discord.Embed], List[str]]:
|
|
"""|static method|
|
|
|
|
Sorts all embeds and strings into a single tuple
|
|
|
|
Parameters
|
|
----------
|
|
values: Sequence[`Any`]
|
|
The values to separate
|
|
|
|
Returns
|
|
-------
|
|
Tuple[List[:class:`discord.Embed`], List[:class:`str`]]
|
|
|
|
Example
|
|
-------
|
|
>>> embeds, strings = .separate([...])
|
|
"""
|
|
...
|
|
|
|
@staticmethod
|
|
def all_embeds(values: Sequence[Any]) -> bool:
|
|
"""|static method|
|
|
|
|
Tests to see if all items in the sequence are of type :class:`discord.Embed`
|
|
|
|
Parameters
|
|
----------
|
|
values: Sequence[`Any`]
|
|
The values to test
|
|
|
|
Returns
|
|
-------
|
|
:class:`bool`: Can return `False` if the sequence is empty
|
|
"""
|
|
...
|
|
|
|
@staticmethod
|
|
def all_strings(values: Sequence[Any]) -> bool:
|
|
"""|static method|
|
|
|
|
Tests to see if all items in the sequence are of type :class:`str`
|
|
|
|
Parameters
|
|
----------
|
|
values: Sequence[`Any`]
|
|
The values to test
|
|
|
|
Returns
|
|
-------
|
|
:class:`bool`: Can return `False` if the sequence is empty
|
|
"""
|
|
...
|
|
|
|
@classmethod
|
|
def remove_limit(cls) -> None:
|
|
"""|class method|
|
|
|
|
Remove the limits currently set for menu's
|
|
"""
|
|
...
|
|
|
|
@classmethod
|
|
def get_all_dm_sessions(cls) -> List[Self]:
|
|
"""|class method|
|
|
|
|
Retrieve all active DM menu sessions
|
|
|
|
Returns
|
|
-------
|
|
A :class:`list` of active DM menu sessions that are currently running. Can be an empty list if there are no active DM sessions
|
|
"""
|
|
...
|
|
|
|
@classmethod
|
|
def get_all_sessions(cls) -> List[Self]:
|
|
"""|class method|
|
|
|
|
Retrieve all active menu sessions
|
|
|
|
Returns
|
|
-------
|
|
A :class:`list` of menu sessions that are currently running. Can be an empty list if there are no active sessions
|
|
"""
|
|
...
|
|
|
|
@classmethod
|
|
def get_session(cls, name: str) -> List[Self]:
|
|
"""|class method|
|
|
|
|
Get a menu instance by it's name
|
|
|
|
Parameters
|
|
----------
|
|
name: :class:`str`
|
|
The name of the menu to return
|
|
|
|
Returns
|
|
-------
|
|
A :class:`list` of menu sessions that are currently running that match the supplied :param:`name`. Can be an empty list if there are no active sessions that matched the :param:`name`
|
|
"""
|
|
...
|
|
|
|
@classmethod
|
|
def get_sessions_count(cls) -> int:
|
|
"""|class method|
|
|
|
|
Returns the number of active sessions
|
|
|
|
Returns
|
|
-------
|
|
:class:`int`: The amount of menu sessions that are active
|
|
"""
|
|
...
|
|
|
|
@classmethod
|
|
def set_sessions_limit(cls, limit: int, per: Literal['channel', 'guild', 'member'] = ..., message: str = ...) -> None:
|
|
"""|class method|
|
|
|
|
Sets the amount of menu sessions that can be active at the same time per guild, channel, or member. This applies to both :class:`ReactionMenu` & :class:`ViewMenu`
|
|
|
|
Parameters
|
|
----------
|
|
limit: :class:`int`
|
|
The amount of menu sessions allowed
|
|
|
|
per: :class:`str`
|
|
How menu sessions should be limited. Options: "channel", "guild", or "member"
|
|
|
|
message: :class:`str`
|
|
Message that will be sent informing users about the menu limit when the limit is reached. Can be :class:`None` for no message
|
|
|
|
Raises
|
|
------
|
|
- `IncorrectType`: The :param:`limit` parameter was not of type :class:`int`
|
|
- `MenuException`: The value of :param:`per` was not valid or the limit was not greater than or equal to one
|
|
"""
|
|
...
|
|
|
|
@classmethod
|
|
async def stop_session(cls, name: str, include_all: bool = ...) -> None:
|
|
"""|coro class method|
|
|
|
|
Stop a specific menu with the supplied name
|
|
|
|
Parameters
|
|
----------
|
|
name: :class:`str`
|
|
The menus name
|
|
|
|
include_all: :class:`bool`
|
|
If set to `True`, it stops all menu sessions with the supplied :param:`name`. If `False`, stops only the most recently started menu with the supplied :param:`name`
|
|
|
|
Raises
|
|
------
|
|
- `MenuException`: The session with the supplied name was not found
|
|
"""
|
|
...
|
|
|
|
@classmethod
|
|
async def stop_all_sessions(cls) -> None:
|
|
"""|coro class method|
|
|
|
|
Stops all menu sessions that are currently running
|
|
"""
|
|
...
|
|
|
|
@classmethod
|
|
def get_menu_from_message(cls, message_id: int, /) -> Optional[Self]:
|
|
"""|class method|
|
|
|
|
Return the menu object associated with the message with the given ID
|
|
|
|
Parameters
|
|
----------
|
|
message_id: :class:`int`
|
|
The `discord.Message.id` from the menu message
|
|
|
|
Returns
|
|
-------
|
|
The menu object. Can be :class:`None` if the menu was not found in the list of active menu sessions
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def rows(self) -> Optional[List[str]]:
|
|
"""
|
|
Returns
|
|
-------
|
|
Optional[List[:class:`str`]]: All rows that's been added to the menu. Can return `None` if the menu has not started or the `menu_type` is not `TypeEmbedDynamic`
|
|
|
|
.. added: v3.1.0
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def menu_type(self) -> str:
|
|
"""
|
|
Returns
|
|
-------
|
|
:class:`str`: The `menu_type` you set via the constructor. This will either be `TypeEmbed`, `TypeEmbedDynamic`, or `TypeText`
|
|
|
|
.. added:: v3.1.0
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def last_viewed(self) -> Optional[Page]:
|
|
"""
|
|
Returns
|
|
-------
|
|
Optional[:class:`Page`]: The last page that was viewed in the pagination process. Can be :class:`None` if the menu has not been started
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def owner(self) -> Union[discord.Member, discord.User]:
|
|
"""
|
|
Returns
|
|
-------
|
|
Union[:class:`discord.Member`, :class:`discord.User`]: The owner of the menu (the person that started the menu). If the menu was started in a DM, this will return :class:`discord.User`
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def total_pages(self) -> int:
|
|
"""
|
|
Returns
|
|
-------
|
|
:class:`int`: The amount of pages that have been added to the menu. If the `menu_type` is :attr:`TypeEmbedDynamic`, the amount of pages is not known until AFTER the menu has started.
|
|
If attempted to retrieve the value before a dynamic menu has started, this will return a value of -1
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def pages(self) -> Optional[List[Page]]:
|
|
"""
|
|
Returns
|
|
-------
|
|
Optional[List[:class:`Page`]]: The pages currently applied to the menu. Can return :class:`None` if there are no pages
|
|
|
|
Note: If the `menu_type` is :attr:`TypeEmbedDynamic`, the pages aren't known until after the menu has started
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def message(self) -> Optional[Union[discord.Message, discord.InteractionMessage]]:
|
|
"""
|
|
Returns
|
|
-------
|
|
Optional[Union[:class:`discord.Message`, :class:`discord.InteractionMessage`]]: The menu's message object. Can be :class:`None` if the menu has not been started
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def is_running(self) -> bool:
|
|
"""
|
|
Returns
|
|
-------
|
|
:class:`bool`: `True` if the menu is currently running, `False` otherwise
|
|
"""
|
|
...
|
|
|
|
@property
|
|
def in_dms(self) -> bool:
|
|
"""
|
|
Returns
|
|
-------
|
|
:class:`bool`: If the menu was started in a DM
|
|
"""
|
|
...
|
|
|
|
def randomize_embed_colors(self) -> None:
|
|
"""Randomize the color of all the embeds that have been added to the menu
|
|
|
|
Raises
|
|
------
|
|
- `MenuException`: The `menu_type` was not of `TypeEmbed`
|
|
|
|
.. added:: v3.1.0
|
|
"""
|
|
...
|
|
|
|
def set_page_director_style(self, style_id: int, separator: str = ...) -> None:
|
|
"""Set how the page numbers dictating what page you are on (in the footer of an embed/regular message) are displayed
|
|
|
|
Parameters
|
|
----------
|
|
style_id: :class:`int`
|
|
Varying formats of how the page director can be presented. The following ID's are available:
|
|
|
|
- `1` = Page 1/10
|
|
- `2` = Page 1 out of 10
|
|
- `3` = 1 out of 10
|
|
- `4` = 1 • 10
|
|
- `5` = 1 » 10
|
|
- `6` = 1 | 10
|
|
- `7` = 1 : 10
|
|
- `8` = 1 - 10
|
|
- `9` = 1 / 10
|
|
- `10` = 1 🔹 10
|
|
- `11` = 1 🔸 10
|
|
|
|
separator: :class:`str`
|
|
The separator between the page director and any text you may have in the embed footer. The default separator is ":". It should be noted that whichever separator you assign,
|
|
if you wish to have spacing between the page director and the separator, you must place the space inside the string yourself as such: " :"
|
|
|
|
Raises
|
|
------
|
|
- `MenuException`: The :param:`style_id` value was not valid
|
|
"""
|
|
...
|
|
|
|
async def wait_until_closed(self) -> None:
|
|
"""|coro|
|
|
|
|
Waits until the menu session ends using `.stop()` or when the menu times out. This should not be used inside relays
|
|
|
|
.. added:: v3.0.1
|
|
"""
|
|
...
|
|
|
|
@ensure_not_primed
|
|
def add_from_messages(self, messages: Sequence[discord.Message]) -> None:
|
|
"""Add pages to the menu using the message object itself
|
|
|
|
Parameters
|
|
----------
|
|
messages: Sequence[:class:`discord.Message`]
|
|
A sequence of discord message objects
|
|
|
|
Raises
|
|
------
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
- `MenuSettingsMismatch`: The messages provided did not have the correct values. For example, the `menu_type` was set to `TypeEmbed`, but the messages you've provided only contains text. If the `menu_type` is `TypeEmbed`, only messages with embeds should be provided
|
|
- `IncorrectType`: All messages were not of type :class:`discord.Message`
|
|
"""
|
|
...
|
|
|
|
@ensure_not_primed
|
|
async def add_from_ids(self, messageable: discord.abc.Messageable, message_ids: Sequence[int]) -> None:
|
|
"""|coro|
|
|
|
|
Add pages to the menu using the IDs of messages. This only grabs embeds (if the `menu_type` is :attr:`TypeEmbed`) or the content (if the `menu_type` is :attr:`TypeText`) from the message
|
|
|
|
Parameters
|
|
----------
|
|
messageable: :class:`discord.abc.Messageable`
|
|
A discord :class:`Messageable` object (:class:`discord.TextChannel`, :class:`commands.Context`, etc.)
|
|
|
|
message_ids: Sequence[:class:`int`]
|
|
The messages to fetch
|
|
|
|
Raises
|
|
------
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
- `MenuSettingsMismatch`: The message IDs provided did not have the correct values when fetched. For example, the `menu_type` was set to `TypeEmbed`, but the messages you've provided for the library to fetch only contains text. If the `menu_type` is `TypeEmbed`, only messages with embeds should be provided
|
|
- `MenuException`: An error occurred when attempting to fetch a message or not all :param:`message_ids` were of type int
|
|
"""
|
|
...
|
|
|
|
@ensure_not_primed
|
|
def clear_all_row_data(self) -> None:
|
|
"""Delete all the data thats been added using :meth:`add_row()`
|
|
|
|
Raises
|
|
------
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
- `MenuSettingsMismatch`: This method was called but the menus `menu_type` was not :attr:`TypeEmbedDynamic`
|
|
"""
|
|
...
|
|
|
|
@ensure_not_primed
|
|
def add_row(self, data: str) -> None:
|
|
"""Add text to the embed page by rows of data
|
|
|
|
Parameters
|
|
----------
|
|
data: :class:`str`
|
|
The data to add
|
|
|
|
Raises
|
|
------
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
- `MenuSettingsMismatch`: This method was called but the menus `menu_type` was not :attr:`TypeEmbedDynamic`
|
|
- `MissingSetting`: The kwarg "rows_requested" (int) has not been set for the menu
|
|
"""
|
|
...
|
|
|
|
@ensure_not_primed
|
|
def set_main_pages(self, *embeds: discord.Embed) -> None:
|
|
"""On a menu with a `menu_type` of :attr:`TypeEmbedDynamic`, set the pages you would like to show first. These embeds will be shown before the embeds that contain your data
|
|
|
|
Parameters
|
|
----------
|
|
*embeds: :class:`discord.Embed`
|
|
An argument list of :class:`discord.Embed` objects
|
|
|
|
Raises
|
|
------
|
|
- `MenuSettingsMismatch`: Tried to use method on a menu that was not of `menu_type` :attr:`TypeEmbedDynamic`
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
- `MenuException`: The "embeds" parameter was empty. At least one value is needed
|
|
- `IncorrectType`: All values in the argument list were not of type :class:`discord.Embed`
|
|
"""
|
|
...
|
|
|
|
@ensure_not_primed
|
|
def set_last_pages(self, *embeds: discord.Embed) -> None:
|
|
"""On a menu with a `menu_type` of :attr:`TypeEmbedDynamic`, set the pages you would like to show last. These embeds will be shown after the embeds that contain your data
|
|
|
|
Parameters
|
|
----------
|
|
*embeds: :class:`discord.Embed`
|
|
An argument list of :class:`discord.Embed` objects
|
|
|
|
Raises
|
|
------
|
|
- `MenuSettingsMismatch`: Tried to use method on a menu that was not of `menu_type` :attr:`TypeEmbedDynamic`
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
- `MenuException`: The "embeds" parameter was empty. At least one value is needed
|
|
- `IncorrectType`: All values in the argument list were not of type :class:`discord.Embed`
|
|
"""
|
|
...
|
|
|
|
@ensure_not_primed
|
|
def add_page(self, embed: Optional[discord.Embed] = ..., content: Optional[str] = ..., files: Optional[List[discord.File]] = ...) -> None:
|
|
"""Add a page to the menu
|
|
|
|
Parameters
|
|
----------
|
|
embed: Optional[:class:`discord.Embed`]
|
|
The embed of the page
|
|
|
|
content: Optional[:class:`str`]
|
|
The text that appears above an embed in a message
|
|
|
|
files: Optional[Sequence[:class:`discord.File`]]
|
|
Files you'd like to attach to the page
|
|
|
|
Raises
|
|
------
|
|
- `MenuException`: Attempted to add a page with no parameters
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
- `MenuSettingsMismatch`: The page being added does not match the menus `menu_type`
|
|
|
|
.. changes::
|
|
v3.1.0
|
|
Added parameter content
|
|
Added parameter embed
|
|
Added parameter files
|
|
Removed parameter "page"
|
|
"""
|
|
...
|
|
|
|
@overload
|
|
def add_pages(self, pages: Sequence[discord.Embed]) -> None:
|
|
...
|
|
|
|
@overload
|
|
def add_pages(self, pages: Sequence[str]) -> None:
|
|
...
|
|
|
|
@ensure_not_primed
|
|
def add_pages(self, pages: Sequence[Union[discord.Embed, str]]) -> None:
|
|
"""Add multiple pages to the menu at once
|
|
|
|
Parameters
|
|
----------
|
|
pages: Sequence[Union[:class:`discord.Embed`, :class:`str`]]
|
|
The pages to add. Can only be used when the menus `menu_type` is :attr:`TypeEmbed` (adding a :class:`discord.Embed`)
|
|
or :attr:`TypeText` (adding a :class:`str`)
|
|
|
|
Raises
|
|
------
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
- `MenuSettingsMismatch`: The page being added does not match the menus `menu_type`
|
|
"""
|
|
...
|
|
|
|
@ensure_not_primed
|
|
def remove_all_pages(self) -> None:
|
|
"""Remove all pages from the menu
|
|
|
|
Raises
|
|
------
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
"""
|
|
...
|
|
|
|
@ensure_not_primed
|
|
def remove_page(self, page_number: int) -> None:
|
|
"""Remove a page from the menu
|
|
|
|
Parameters
|
|
----------
|
|
page_number: :class:`int`
|
|
The page to remove
|
|
|
|
Raises
|
|
------
|
|
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
|
|
- `InvalidPage`: The page associated with the given page number was not valid
|
|
"""
|
|
...
|
|
|
|
def set_on_timeout(self, func: Callable[[M], None]) -> None:
|
|
"""Set the function to be called when the menu times out
|
|
|
|
Parameters
|
|
----------
|
|
func: Callable[[:type:`M`]], :class:`None`]
|
|
The function object that will be called when the menu times out. The function should contain a single positional argument
|
|
and should not return anything. The argument passed to that function is an instance of the menu.
|
|
|
|
Raises
|
|
------
|
|
- `IncorrectType`: Parameter "func" was not a callable object
|
|
"""
|
|
...
|
|
|
|
def remove_on_timeout(self) -> None:
|
|
"""Remove the timeout call to the function you have set when the menu times out"""
|
|
...
|
|
|
|
def set_relay(self, func: Callable[[NamedTuple], None], *, only: Optional[List[GB]] = ...) -> None:
|
|
"""Set a function to be called with a given set of information when a button is pressed on the menu. The information passed is `RelayPayload`, a named tuple.
|
|
The named tuple contains the following attributes:
|
|
|
|
- `member`: The :class:`discord.Member` object of the person who pressed the button. Could be :class:`discord.User` if the menu was started in a DM
|
|
- `button`: Depending on the menu instance, the :class:`ReactionButton` or :class:`ViewButton` object of the button that was pressed
|
|
|
|
Parameters
|
|
----------
|
|
func: Callable[[:class:`NamedTuple`], :class:`None`]
|
|
The function should only contain a single positional argument. Command functions (`@bot.command()`) not supported
|
|
|
|
only: Optional[List[:generic:`GB`]]
|
|
A list of buttons (`GB`) associated with the current menu instance. If the menu instance is :class:`ReactionMenu`, this should be a list of :class:`ReactionButton`
|
|
and vice-versa for :class:`ViewMenu` instances. If this is :class:`None`, all buttons on the menu will be relayed. If set, only button presses from those specified buttons will be relayed
|
|
|
|
Raises
|
|
------
|
|
- `IncorrectType`: The :param:`func` argument provided was not callable
|
|
"""
|
|
...
|
|
|
|
def remove_relay(self) -> None:
|
|
"""Remove the relay that's been set"""
|
|
...
|
|
|
|
|
|
|