mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-05-16 18:59:09 +00:00
Add support for default_values field on selects
This commit is contained in:
parent
9f8f9bf56b
commit
c5ecc42c72
@ -25,7 +25,7 @@ DEALINGS IN THE SOFTWARE.
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import ClassVar, List, Literal, Optional, TYPE_CHECKING, Tuple, Union, overload
|
from typing import ClassVar, List, Literal, Optional, TYPE_CHECKING, Tuple, Union, overload
|
||||||
from .enums import try_enum, ComponentType, ButtonStyle, TextStyle, ChannelType
|
from .enums import try_enum, ComponentType, ButtonStyle, TextStyle, ChannelType, SelectDefaultValueType
|
||||||
from .utils import get_slots, MISSING
|
from .utils import get_slots, MISSING
|
||||||
from .partial_emoji import PartialEmoji, _EmojiTag
|
from .partial_emoji import PartialEmoji, _EmojiTag
|
||||||
|
|
||||||
@ -40,8 +40,10 @@ if TYPE_CHECKING:
|
|||||||
ActionRow as ActionRowPayload,
|
ActionRow as ActionRowPayload,
|
||||||
TextInput as TextInputPayload,
|
TextInput as TextInputPayload,
|
||||||
ActionRowChildComponent as ActionRowChildComponentPayload,
|
ActionRowChildComponent as ActionRowChildComponentPayload,
|
||||||
|
SelectDefaultValues as SelectDefaultValuesPayload,
|
||||||
)
|
)
|
||||||
from .emoji import Emoji
|
from .emoji import Emoji
|
||||||
|
from .abc import Snowflake
|
||||||
|
|
||||||
ActionRowChildComponentType = Union['Button', 'SelectMenu', 'TextInput']
|
ActionRowChildComponentType = Union['Button', 'SelectMenu', 'TextInput']
|
||||||
|
|
||||||
@ -53,6 +55,7 @@ __all__ = (
|
|||||||
'SelectMenu',
|
'SelectMenu',
|
||||||
'SelectOption',
|
'SelectOption',
|
||||||
'TextInput',
|
'TextInput',
|
||||||
|
'SelectDefaultValue',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -263,6 +266,7 @@ class SelectMenu(Component):
|
|||||||
'options',
|
'options',
|
||||||
'disabled',
|
'disabled',
|
||||||
'channel_types',
|
'channel_types',
|
||||||
|
'default_values',
|
||||||
)
|
)
|
||||||
|
|
||||||
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
|
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
|
||||||
@ -276,6 +280,9 @@ class SelectMenu(Component):
|
|||||||
self.options: List[SelectOption] = [SelectOption.from_dict(option) for option in data.get('options', [])]
|
self.options: List[SelectOption] = [SelectOption.from_dict(option) for option in data.get('options', [])]
|
||||||
self.disabled: bool = data.get('disabled', False)
|
self.disabled: bool = data.get('disabled', False)
|
||||||
self.channel_types: List[ChannelType] = [try_enum(ChannelType, t) for t in data.get('channel_types', [])]
|
self.channel_types: List[ChannelType] = [try_enum(ChannelType, t) for t in data.get('channel_types', [])]
|
||||||
|
self.default_values: List[SelectDefaultValue] = [
|
||||||
|
SelectDefaultValue.from_dict(d) for d in data.get('default_values', [])
|
||||||
|
]
|
||||||
|
|
||||||
def to_dict(self) -> SelectMenuPayload:
|
def to_dict(self) -> SelectMenuPayload:
|
||||||
payload: SelectMenuPayload = {
|
payload: SelectMenuPayload = {
|
||||||
@ -291,6 +298,8 @@ class SelectMenu(Component):
|
|||||||
payload['options'] = [op.to_dict() for op in self.options]
|
payload['options'] = [op.to_dict() for op in self.options]
|
||||||
if self.channel_types:
|
if self.channel_types:
|
||||||
payload['channel_types'] = [t.value for t in self.channel_types]
|
payload['channel_types'] = [t.value for t in self.channel_types]
|
||||||
|
if self.default_values:
|
||||||
|
payload["default_values"] = [v.to_dict() for v in self.default_values]
|
||||||
|
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
@ -512,6 +521,79 @@ class TextInput(Component):
|
|||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
|
class SelectDefaultValue:
|
||||||
|
"""Represents a select menu's default value.
|
||||||
|
|
||||||
|
These can be created by users.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
id: :class:`int`
|
||||||
|
The id of a role, user, or channel.
|
||||||
|
type: :class:`SelectDefaultValueType`
|
||||||
|
The type of value that ``id`` represents.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
id: int,
|
||||||
|
type: SelectDefaultValueType,
|
||||||
|
) -> None:
|
||||||
|
self.id: int = id
|
||||||
|
self._type: SelectDefaultValueType = type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self) -> SelectDefaultValueType:
|
||||||
|
return self._type
|
||||||
|
|
||||||
|
@type.setter
|
||||||
|
def type(self, value: SelectDefaultValueType) -> None:
|
||||||
|
if not isinstance(value, SelectDefaultValueType):
|
||||||
|
raise TypeError(f'expected SelectDefaultValueType, received {value.__class__.__name__} instead')
|
||||||
|
|
||||||
|
self._type = value
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f'<SelectDefaultValue id={self.id!r} type={self.type!r}>'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, data: SelectDefaultValuesPayload) -> SelectDefaultValue:
|
||||||
|
return cls(
|
||||||
|
id=data['id'],
|
||||||
|
type=try_enum(SelectDefaultValueType, data['type']),
|
||||||
|
)
|
||||||
|
|
||||||
|
def to_dict(self) -> SelectDefaultValuesPayload:
|
||||||
|
return {
|
||||||
|
'id': self.id,
|
||||||
|
'type': self._type.value,
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_channel(cls, channel: Snowflake, /) -> Self:
|
||||||
|
return cls(
|
||||||
|
id=channel.id,
|
||||||
|
type=SelectDefaultValueType.channel,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_role(cls, role: Snowflake, /) -> Self:
|
||||||
|
return cls(
|
||||||
|
id=role.id,
|
||||||
|
type=SelectDefaultValueType.role,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_user(cls, user: Snowflake, /) -> Self:
|
||||||
|
return cls(
|
||||||
|
id=user.id,
|
||||||
|
type=SelectDefaultValueType.user,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def _component_factory(data: ActionRowChildComponentPayload) -> Optional[ActionRowChildComponentType]:
|
def _component_factory(data: ActionRowChildComponentPayload) -> Optional[ActionRowChildComponentType]:
|
||||||
...
|
...
|
||||||
|
@ -69,6 +69,7 @@ __all__ = (
|
|||||||
'AutoModRuleActionType',
|
'AutoModRuleActionType',
|
||||||
'ForumLayoutType',
|
'ForumLayoutType',
|
||||||
'ForumOrderType',
|
'ForumOrderType',
|
||||||
|
'SelectDefaultValueType',
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -772,6 +773,12 @@ class ForumOrderType(Enum):
|
|||||||
creation_date = 1
|
creation_date = 1
|
||||||
|
|
||||||
|
|
||||||
|
class SelectDefaultValueType(Enum):
|
||||||
|
user = 'user'
|
||||||
|
role = 'role'
|
||||||
|
channel = 'channel'
|
||||||
|
|
||||||
|
|
||||||
def create_unknown_value(cls: Type[E], val: Any) -> E:
|
def create_unknown_value(cls: Type[E], val: Any) -> E:
|
||||||
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
|
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
|
||||||
name = f'unknown_{val}'
|
name = f'unknown_{val}'
|
||||||
|
@ -33,6 +33,7 @@ from .channel import ChannelType
|
|||||||
ComponentType = Literal[1, 2, 3, 4]
|
ComponentType = Literal[1, 2, 3, 4]
|
||||||
ButtonStyle = Literal[1, 2, 3, 4, 5]
|
ButtonStyle = Literal[1, 2, 3, 4, 5]
|
||||||
TextStyle = Literal[1, 2]
|
TextStyle = Literal[1, 2]
|
||||||
|
DefaultValueType = Literal['user', 'role', 'channel']
|
||||||
|
|
||||||
|
|
||||||
class ActionRow(TypedDict):
|
class ActionRow(TypedDict):
|
||||||
@ -66,6 +67,11 @@ class SelectComponent(TypedDict):
|
|||||||
disabled: NotRequired[bool]
|
disabled: NotRequired[bool]
|
||||||
|
|
||||||
|
|
||||||
|
class SelectDefaultValues(TypedDict):
|
||||||
|
id: int
|
||||||
|
type: DefaultValueType
|
||||||
|
|
||||||
|
|
||||||
class StringSelectComponent(SelectComponent):
|
class StringSelectComponent(SelectComponent):
|
||||||
type: Literal[3]
|
type: Literal[3]
|
||||||
options: NotRequired[List[SelectOption]]
|
options: NotRequired[List[SelectOption]]
|
||||||
@ -73,19 +79,23 @@ class StringSelectComponent(SelectComponent):
|
|||||||
|
|
||||||
class UserSelectComponent(SelectComponent):
|
class UserSelectComponent(SelectComponent):
|
||||||
type: Literal[5]
|
type: Literal[5]
|
||||||
|
default_values: NotRequired[List[SelectDefaultValues]]
|
||||||
|
|
||||||
|
|
||||||
class RoleSelectComponent(SelectComponent):
|
class RoleSelectComponent(SelectComponent):
|
||||||
type: Literal[6]
|
type: Literal[6]
|
||||||
|
default_values: NotRequired[List[SelectDefaultValues]]
|
||||||
|
|
||||||
|
|
||||||
class MentionableSelectComponent(SelectComponent):
|
class MentionableSelectComponent(SelectComponent):
|
||||||
type: Literal[7]
|
type: Literal[7]
|
||||||
|
default_values: NotRequired[List[SelectDefaultValues]]
|
||||||
|
|
||||||
|
|
||||||
class ChannelSelectComponent(SelectComponent):
|
class ChannelSelectComponent(SelectComponent):
|
||||||
type: Literal[8]
|
type: Literal[8]
|
||||||
channel_types: NotRequired[List[ChannelType]]
|
channel_types: NotRequired[List[ChannelType]]
|
||||||
|
default_values: NotRequired[List[SelectDefaultValues]]
|
||||||
|
|
||||||
|
|
||||||
class TextInput(TypedDict):
|
class TextInput(TypedDict):
|
||||||
@ -104,6 +114,7 @@ class SelectMenu(SelectComponent):
|
|||||||
type: Literal[3, 5, 6, 7, 8]
|
type: Literal[3, 5, 6, 7, 8]
|
||||||
options: NotRequired[List[SelectOption]]
|
options: NotRequired[List[SelectOption]]
|
||||||
channel_types: NotRequired[List[ChannelType]]
|
channel_types: NotRequired[List[ChannelType]]
|
||||||
|
default_values: NotRequired[List[SelectDefaultValues]]
|
||||||
|
|
||||||
|
|
||||||
ActionRowChildComponent = Union[ButtonComponent, SelectMenu, TextInput]
|
ActionRowChildComponent = Union[ButtonComponent, SelectMenu, TextInput]
|
||||||
|
@ -22,21 +22,42 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import Any, List, Literal, Optional, TYPE_CHECKING, Tuple, Type, TypeVar, Callable, Union, Dict, overload
|
from typing import (
|
||||||
|
Any,
|
||||||
|
List,
|
||||||
|
Literal,
|
||||||
|
Optional,
|
||||||
|
TYPE_CHECKING,
|
||||||
|
Tuple,
|
||||||
|
Type,
|
||||||
|
TypeVar,
|
||||||
|
Callable,
|
||||||
|
Union,
|
||||||
|
Dict,
|
||||||
|
overload,
|
||||||
|
Sequence,
|
||||||
|
)
|
||||||
from contextvars import ContextVar
|
from contextvars import ContextVar
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from .item import Item, ItemCallbackType
|
from .item import Item, ItemCallbackType
|
||||||
from ..enums import ChannelType, ComponentType
|
from ..enums import ChannelType, ComponentType, SelectDefaultValueType
|
||||||
from ..partial_emoji import PartialEmoji
|
from ..partial_emoji import PartialEmoji
|
||||||
from ..emoji import Emoji
|
from ..emoji import Emoji
|
||||||
from ..utils import MISSING
|
from ..utils import MISSING
|
||||||
from ..components import (
|
from ..components import (
|
||||||
SelectOption,
|
SelectOption,
|
||||||
SelectMenu,
|
SelectMenu,
|
||||||
|
SelectDefaultValue,
|
||||||
)
|
)
|
||||||
from ..app_commands.namespace import Namespace
|
from ..app_commands.namespace import Namespace
|
||||||
|
from ..member import Member
|
||||||
|
from ..object import Object
|
||||||
|
from ..role import Role
|
||||||
|
from ..user import User
|
||||||
|
from ..abc import GuildChannel
|
||||||
|
from ..threads import Thread
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'Select',
|
'Select',
|
||||||
@ -54,9 +75,6 @@ if TYPE_CHECKING:
|
|||||||
from ..types.components import SelectMenu as SelectMenuPayload
|
from ..types.components import SelectMenu as SelectMenuPayload
|
||||||
from ..types.interactions import SelectMessageComponentInteractionData
|
from ..types.interactions import SelectMessageComponentInteractionData
|
||||||
from ..app_commands import AppCommandChannel, AppCommandThread
|
from ..app_commands import AppCommandChannel, AppCommandThread
|
||||||
from ..member import Member
|
|
||||||
from ..role import Role
|
|
||||||
from ..user import User
|
|
||||||
from ..interactions import Interaction
|
from ..interactions import Interaction
|
||||||
|
|
||||||
ValidSelectType: TypeAlias = Literal[
|
ValidSelectType: TypeAlias = Literal[
|
||||||
@ -69,6 +87,17 @@ if TYPE_CHECKING:
|
|||||||
PossibleValue: TypeAlias = Union[
|
PossibleValue: TypeAlias = Union[
|
||||||
str, User, Member, Role, AppCommandChannel, AppCommandThread, Union[Role, Member], Union[Role, User]
|
str, User, Member, Role, AppCommandChannel, AppCommandThread, Union[Role, Member], Union[Role, User]
|
||||||
]
|
]
|
||||||
|
ValidDefaultValues: TypeAlias = Union[
|
||||||
|
SelectDefaultValue,
|
||||||
|
Object,
|
||||||
|
Role,
|
||||||
|
Member,
|
||||||
|
User,
|
||||||
|
GuildChannel,
|
||||||
|
AppCommandChannel,
|
||||||
|
AppCommandThread,
|
||||||
|
Thread,
|
||||||
|
]
|
||||||
|
|
||||||
V = TypeVar('V', bound='View', covariant=True)
|
V = TypeVar('V', bound='View', covariant=True)
|
||||||
BaseSelectT = TypeVar('BaseSelectT', bound='BaseSelect[Any]')
|
BaseSelectT = TypeVar('BaseSelectT', bound='BaseSelect[Any]')
|
||||||
@ -82,6 +111,73 @@ SelectCallbackDecorator: TypeAlias = Callable[[ItemCallbackType[V, BaseSelectT]]
|
|||||||
selected_values: ContextVar[Dict[str, List[PossibleValue]]] = ContextVar('selected_values')
|
selected_values: ContextVar[Dict[str, List[PossibleValue]]] = ContextVar('selected_values')
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_select_defaults(
|
||||||
|
defaults: Sequence[ValidDefaultValues],
|
||||||
|
component_type: Literal[
|
||||||
|
ComponentType.user_select,
|
||||||
|
ComponentType.role_select,
|
||||||
|
ComponentType.channel_select,
|
||||||
|
ComponentType.mentionable_select,
|
||||||
|
],
|
||||||
|
) -> List[SelectDefaultValue]:
|
||||||
|
if not defaults or defaults is MISSING:
|
||||||
|
return []
|
||||||
|
|
||||||
|
from ..app_commands import AppCommandChannel, AppCommandThread
|
||||||
|
|
||||||
|
cls_to_type: Dict[Type[ValidDefaultValues], SelectDefaultValueType] = {
|
||||||
|
User: SelectDefaultValueType.user,
|
||||||
|
Member: SelectDefaultValueType.user,
|
||||||
|
Role: SelectDefaultValueType.role,
|
||||||
|
GuildChannel: SelectDefaultValueType.channel,
|
||||||
|
AppCommandChannel: SelectDefaultValueType.channel,
|
||||||
|
AppCommandThread: SelectDefaultValueType.channel,
|
||||||
|
Thread: SelectDefaultValueType.channel,
|
||||||
|
}
|
||||||
|
type_to_supported_classes: Dict[ValidSelectType, Tuple[Type[ValidDefaultValues], ...]] = {
|
||||||
|
ComponentType.user_select: (User, Member, Object),
|
||||||
|
ComponentType.role_select: (Role, Object),
|
||||||
|
ComponentType.channel_select: (GuildChannel, AppCommandChannel, AppCommandThread, Thread, Object),
|
||||||
|
ComponentType.mentionable_select: (User, Member, Role, Object),
|
||||||
|
}
|
||||||
|
|
||||||
|
values: List[SelectDefaultValue] = []
|
||||||
|
for obj in defaults:
|
||||||
|
if isinstance(obj, SelectDefaultValue):
|
||||||
|
values.append(obj)
|
||||||
|
continue
|
||||||
|
|
||||||
|
object_type = obj.__class__ if not isinstance(obj, Object) else obj.type
|
||||||
|
|
||||||
|
if object_type not in type_to_supported_classes[component_type]:
|
||||||
|
# TODO: split this into a util function
|
||||||
|
supported_classes = [c.__name__ for c in type_to_supported_classes[component_type]]
|
||||||
|
if len(supported_classes) > 2:
|
||||||
|
supported_classes = ', '.join(supported_classes[:-1]) + f', or {supported_classes[-1]}'
|
||||||
|
elif len(supported_classes) == 2:
|
||||||
|
supported_classes = f'{supported_classes[0]} or {supported_classes[1]}'
|
||||||
|
else:
|
||||||
|
supported_classes = supported_classes[0]
|
||||||
|
|
||||||
|
raise TypeError(f'Expected an instance of {supported_classes} not {object_type.__name__}')
|
||||||
|
|
||||||
|
if object_type is Object:
|
||||||
|
if component_type is ComponentType.mentionable_select:
|
||||||
|
raise ValueError(
|
||||||
|
'Object must have a type specified for the chosen select type. Please pass one using the `type`` kwarg.'
|
||||||
|
)
|
||||||
|
elif component_type is ComponentType.user_select:
|
||||||
|
object_type = User
|
||||||
|
elif component_type is ComponentType.role_select:
|
||||||
|
object_type = Role
|
||||||
|
elif component_type is ComponentType.channel_select:
|
||||||
|
object_type = GuildChannel
|
||||||
|
|
||||||
|
values.append(SelectDefaultValue(id=obj.id, type=cls_to_type[object_type]))
|
||||||
|
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
class BaseSelect(Item[V]):
|
class BaseSelect(Item[V]):
|
||||||
"""The base Select model that all other Select models inherit from.
|
"""The base Select model that all other Select models inherit from.
|
||||||
|
|
||||||
@ -128,6 +224,7 @@ class BaseSelect(Item[V]):
|
|||||||
disabled: bool = False,
|
disabled: bool = False,
|
||||||
options: List[SelectOption] = MISSING,
|
options: List[SelectOption] = MISSING,
|
||||||
channel_types: List[ChannelType] = MISSING,
|
channel_types: List[ChannelType] = MISSING,
|
||||||
|
default_values: Sequence[SelectDefaultValue] = MISSING,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._provided_custom_id = custom_id is not MISSING
|
self._provided_custom_id = custom_id is not MISSING
|
||||||
@ -144,6 +241,7 @@ class BaseSelect(Item[V]):
|
|||||||
disabled=disabled,
|
disabled=disabled,
|
||||||
channel_types=[] if channel_types is MISSING else channel_types,
|
channel_types=[] if channel_types is MISSING else channel_types,
|
||||||
options=[] if options is MISSING else options,
|
options=[] if options is MISSING else options,
|
||||||
|
default_values=[] if default_values is MISSING else default_values,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.row = row
|
self.row = row
|
||||||
@ -410,6 +508,10 @@ class UserSelect(BaseSelect[V]):
|
|||||||
Defaults to 1 and must be between 1 and 25.
|
Defaults to 1 and must be between 1 and 25.
|
||||||
disabled: :class:`bool`
|
disabled: :class:`bool`
|
||||||
Whether the select is disabled or not.
|
Whether the select is disabled or not.
|
||||||
|
default_values: Sequence[:class:`~discord.abc.Snowflake`]
|
||||||
|
A list of objects representing the users that should be selected by default.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
row: Optional[:class:`int`]
|
row: Optional[:class:`int`]
|
||||||
The relative row this select menu belongs to. A Discord component can only have 5
|
The relative row this select menu belongs to. A Discord component can only have 5
|
||||||
rows. By default, items are arranged automatically into those 5 rows. If you'd
|
rows. By default, items are arranged automatically into those 5 rows. If you'd
|
||||||
@ -418,6 +520,8 @@ class UserSelect(BaseSelect[V]):
|
|||||||
ordering. The row number must be between 0 and 4 (i.e. zero indexed).
|
ordering. The row number must be between 0 and 4 (i.e. zero indexed).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
__item_repr_attributes__ = BaseSelect.__item_repr_attributes__ + ('default_values',)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@ -427,6 +531,7 @@ class UserSelect(BaseSelect[V]):
|
|||||||
max_values: int = 1,
|
max_values: int = 1,
|
||||||
disabled: bool = False,
|
disabled: bool = False,
|
||||||
row: Optional[int] = None,
|
row: Optional[int] = None,
|
||||||
|
default_values: Sequence[ValidDefaultValues] = MISSING,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
self.type,
|
self.type,
|
||||||
@ -436,6 +541,7 @@ class UserSelect(BaseSelect[V]):
|
|||||||
max_values=max_values,
|
max_values=max_values,
|
||||||
disabled=disabled,
|
disabled=disabled,
|
||||||
row=row,
|
row=row,
|
||||||
|
default_values=_handle_select_defaults(default_values, self.type),
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -456,6 +562,18 @@ class UserSelect(BaseSelect[V]):
|
|||||||
"""
|
"""
|
||||||
return super().values # type: ignore
|
return super().values # type: ignore
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default_values(self) -> List[SelectDefaultValue]:
|
||||||
|
"""List[:class:`discord.SelectDefaultValue`]: A list of default values for the select menu.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
"""
|
||||||
|
return self._underlying.default_values
|
||||||
|
|
||||||
|
@default_values.setter
|
||||||
|
def default_values(self, value: Sequence[ValidDefaultValues]) -> None:
|
||||||
|
self._underlying.default_values = _handle_select_defaults(value, self.type)
|
||||||
|
|
||||||
|
|
||||||
class RoleSelect(BaseSelect[V]):
|
class RoleSelect(BaseSelect[V]):
|
||||||
"""Represents a UI select menu with a list of predefined options with the current roles of the guild.
|
"""Represents a UI select menu with a list of predefined options with the current roles of the guild.
|
||||||
@ -479,6 +597,10 @@ class RoleSelect(BaseSelect[V]):
|
|||||||
Defaults to 1 and must be between 1 and 25.
|
Defaults to 1 and must be between 1 and 25.
|
||||||
disabled: :class:`bool`
|
disabled: :class:`bool`
|
||||||
Whether the select is disabled or not.
|
Whether the select is disabled or not.
|
||||||
|
default_values: Sequence[:class:`~discord.abc.Snowflake`]
|
||||||
|
A list of objects representing the users that should be selected by default.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
row: Optional[:class:`int`]
|
row: Optional[:class:`int`]
|
||||||
The relative row this select menu belongs to. A Discord component can only have 5
|
The relative row this select menu belongs to. A Discord component can only have 5
|
||||||
rows. By default, items are arranged automatically into those 5 rows. If you'd
|
rows. By default, items are arranged automatically into those 5 rows. If you'd
|
||||||
@ -487,6 +609,8 @@ class RoleSelect(BaseSelect[V]):
|
|||||||
ordering. The row number must be between 0 and 4 (i.e. zero indexed).
|
ordering. The row number must be between 0 and 4 (i.e. zero indexed).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
__item_repr_attributes__ = BaseSelect.__item_repr_attributes__ + ('default_values',)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@ -496,6 +620,7 @@ class RoleSelect(BaseSelect[V]):
|
|||||||
max_values: int = 1,
|
max_values: int = 1,
|
||||||
disabled: bool = False,
|
disabled: bool = False,
|
||||||
row: Optional[int] = None,
|
row: Optional[int] = None,
|
||||||
|
default_values: Sequence[ValidDefaultValues] = MISSING,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
self.type,
|
self.type,
|
||||||
@ -505,6 +630,7 @@ class RoleSelect(BaseSelect[V]):
|
|||||||
max_values=max_values,
|
max_values=max_values,
|
||||||
disabled=disabled,
|
disabled=disabled,
|
||||||
row=row,
|
row=row,
|
||||||
|
default_values=_handle_select_defaults(default_values, self.type),
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -517,6 +643,18 @@ class RoleSelect(BaseSelect[V]):
|
|||||||
"""List[:class:`discord.Role`]: A list of roles that have been selected by the user."""
|
"""List[:class:`discord.Role`]: A list of roles that have been selected by the user."""
|
||||||
return super().values # type: ignore
|
return super().values # type: ignore
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default_values(self) -> List[SelectDefaultValue]:
|
||||||
|
"""List[:class:`discord.SelectDefaultValue`]: A list of default values for the select menu.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
"""
|
||||||
|
return self._underlying.default_values
|
||||||
|
|
||||||
|
@default_values.setter
|
||||||
|
def default_values(self, value: Sequence[ValidDefaultValues]) -> None:
|
||||||
|
self._underlying.default_values = _handle_select_defaults(value, self.type)
|
||||||
|
|
||||||
|
|
||||||
class MentionableSelect(BaseSelect[V]):
|
class MentionableSelect(BaseSelect[V]):
|
||||||
"""Represents a UI select menu with a list of predefined options with the current members and roles in the guild.
|
"""Represents a UI select menu with a list of predefined options with the current members and roles in the guild.
|
||||||
@ -543,6 +681,11 @@ class MentionableSelect(BaseSelect[V]):
|
|||||||
Defaults to 1 and must be between 1 and 25.
|
Defaults to 1 and must be between 1 and 25.
|
||||||
disabled: :class:`bool`
|
disabled: :class:`bool`
|
||||||
Whether the select is disabled or not.
|
Whether the select is disabled or not.
|
||||||
|
default_values: Sequence[:class:`~discord.abc.Snowflake`]
|
||||||
|
A list of objects representing the users/roles that should be selected by default.
|
||||||
|
if :class:`.Object` is passed, then the type must be specified in the constructor.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
row: Optional[:class:`int`]
|
row: Optional[:class:`int`]
|
||||||
The relative row this select menu belongs to. A Discord component can only have 5
|
The relative row this select menu belongs to. A Discord component can only have 5
|
||||||
rows. By default, items are arranged automatically into those 5 rows. If you'd
|
rows. By default, items are arranged automatically into those 5 rows. If you'd
|
||||||
@ -551,6 +694,8 @@ class MentionableSelect(BaseSelect[V]):
|
|||||||
ordering. The row number must be between 0 and 4 (i.e. zero indexed).
|
ordering. The row number must be between 0 and 4 (i.e. zero indexed).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
__item_repr_attributes__ = BaseSelect.__item_repr_attributes__ + ('default_values',)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@ -560,6 +705,7 @@ class MentionableSelect(BaseSelect[V]):
|
|||||||
max_values: int = 1,
|
max_values: int = 1,
|
||||||
disabled: bool = False,
|
disabled: bool = False,
|
||||||
row: Optional[int] = None,
|
row: Optional[int] = None,
|
||||||
|
default_values: Sequence[ValidDefaultValues] = MISSING,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
self.type,
|
self.type,
|
||||||
@ -569,6 +715,7 @@ class MentionableSelect(BaseSelect[V]):
|
|||||||
max_values=max_values,
|
max_values=max_values,
|
||||||
disabled=disabled,
|
disabled=disabled,
|
||||||
row=row,
|
row=row,
|
||||||
|
default_values=_handle_select_defaults(default_values, self.type),
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -589,6 +736,18 @@ class MentionableSelect(BaseSelect[V]):
|
|||||||
"""
|
"""
|
||||||
return super().values # type: ignore
|
return super().values # type: ignore
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default_values(self) -> List[SelectDefaultValue]:
|
||||||
|
"""List[:class:`discord.SelectDefaultValue`]: A list of default values for the select menu.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
"""
|
||||||
|
return self._underlying.default_values
|
||||||
|
|
||||||
|
@default_values.setter
|
||||||
|
def default_values(self, value: Sequence[ValidDefaultValues]) -> None:
|
||||||
|
self._underlying.default_values = _handle_select_defaults(value, self.type)
|
||||||
|
|
||||||
|
|
||||||
class ChannelSelect(BaseSelect[V]):
|
class ChannelSelect(BaseSelect[V]):
|
||||||
"""Represents a UI select menu with a list of predefined options with the current channels in the guild.
|
"""Represents a UI select menu with a list of predefined options with the current channels in the guild.
|
||||||
@ -614,6 +773,10 @@ class ChannelSelect(BaseSelect[V]):
|
|||||||
Defaults to 1 and must be between 1 and 25.
|
Defaults to 1 and must be between 1 and 25.
|
||||||
disabled: :class:`bool`
|
disabled: :class:`bool`
|
||||||
Whether the select is disabled or not.
|
Whether the select is disabled or not.
|
||||||
|
default_values: Sequence[:class:`~discord.abc.Snowflake`]
|
||||||
|
A list of objects representing the channels that should be selected by default.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
row: Optional[:class:`int`]
|
row: Optional[:class:`int`]
|
||||||
The relative row this select menu belongs to. A Discord component can only have 5
|
The relative row this select menu belongs to. A Discord component can only have 5
|
||||||
rows. By default, items are arranged automatically into those 5 rows. If you'd
|
rows. By default, items are arranged automatically into those 5 rows. If you'd
|
||||||
@ -622,7 +785,10 @@ class ChannelSelect(BaseSelect[V]):
|
|||||||
ordering. The row number must be between 0 and 4 (i.e. zero indexed).
|
ordering. The row number must be between 0 and 4 (i.e. zero indexed).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__item_repr_attributes__ = BaseSelect.__item_repr_attributes__ + ('channel_types',)
|
__item_repr_attributes__ = BaseSelect.__item_repr_attributes__ + (
|
||||||
|
'channel_types',
|
||||||
|
'default_values',
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -634,6 +800,7 @@ class ChannelSelect(BaseSelect[V]):
|
|||||||
max_values: int = 1,
|
max_values: int = 1,
|
||||||
disabled: bool = False,
|
disabled: bool = False,
|
||||||
row: Optional[int] = None,
|
row: Optional[int] = None,
|
||||||
|
default_values: Sequence[ValidDefaultValues] = MISSING,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
self.type,
|
self.type,
|
||||||
@ -644,6 +811,7 @@ class ChannelSelect(BaseSelect[V]):
|
|||||||
disabled=disabled,
|
disabled=disabled,
|
||||||
row=row,
|
row=row,
|
||||||
channel_types=channel_types,
|
channel_types=channel_types,
|
||||||
|
default_values=_handle_select_defaults(default_values, self.type),
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -670,6 +838,18 @@ class ChannelSelect(BaseSelect[V]):
|
|||||||
"""List[Union[:class:`~discord.app_commands.AppCommandChannel`, :class:`~discord.app_commands.AppCommandThread`]]: A list of channels selected by the user."""
|
"""List[Union[:class:`~discord.app_commands.AppCommandChannel`, :class:`~discord.app_commands.AppCommandThread`]]: A list of channels selected by the user."""
|
||||||
return super().values # type: ignore
|
return super().values # type: ignore
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default_values(self) -> List[SelectDefaultValue]:
|
||||||
|
"""List[:class:`discord.SelectDefaultValue`]: A list of default values for the select menu.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
"""
|
||||||
|
return self._underlying.default_values
|
||||||
|
|
||||||
|
@default_values.setter
|
||||||
|
def default_values(self, value: Sequence[ValidDefaultValues]) -> None:
|
||||||
|
self._underlying.default_values = _handle_select_defaults(value, self.type)
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def select(
|
def select(
|
||||||
@ -698,6 +878,7 @@ def select(
|
|||||||
min_values: int = ...,
|
min_values: int = ...,
|
||||||
max_values: int = ...,
|
max_values: int = ...,
|
||||||
disabled: bool = ...,
|
disabled: bool = ...,
|
||||||
|
default_values: Sequence[ValidDefaultValues] = ...,
|
||||||
row: Optional[int] = ...,
|
row: Optional[int] = ...,
|
||||||
) -> SelectCallbackDecorator[V, UserSelectT]:
|
) -> SelectCallbackDecorator[V, UserSelectT]:
|
||||||
...
|
...
|
||||||
@ -714,6 +895,7 @@ def select(
|
|||||||
min_values: int = ...,
|
min_values: int = ...,
|
||||||
max_values: int = ...,
|
max_values: int = ...,
|
||||||
disabled: bool = ...,
|
disabled: bool = ...,
|
||||||
|
default_values: Sequence[ValidDefaultValues] = ...,
|
||||||
row: Optional[int] = ...,
|
row: Optional[int] = ...,
|
||||||
) -> SelectCallbackDecorator[V, RoleSelectT]:
|
) -> SelectCallbackDecorator[V, RoleSelectT]:
|
||||||
...
|
...
|
||||||
@ -730,6 +912,7 @@ def select(
|
|||||||
min_values: int = ...,
|
min_values: int = ...,
|
||||||
max_values: int = ...,
|
max_values: int = ...,
|
||||||
disabled: bool = ...,
|
disabled: bool = ...,
|
||||||
|
default_values: Sequence[ValidDefaultValues] = ...,
|
||||||
row: Optional[int] = ...,
|
row: Optional[int] = ...,
|
||||||
) -> SelectCallbackDecorator[V, ChannelSelectT]:
|
) -> SelectCallbackDecorator[V, ChannelSelectT]:
|
||||||
...
|
...
|
||||||
@ -746,6 +929,7 @@ def select(
|
|||||||
min_values: int = ...,
|
min_values: int = ...,
|
||||||
max_values: int = ...,
|
max_values: int = ...,
|
||||||
disabled: bool = ...,
|
disabled: bool = ...,
|
||||||
|
default_values: Sequence[ValidDefaultValues] = ...,
|
||||||
row: Optional[int] = ...,
|
row: Optional[int] = ...,
|
||||||
) -> SelectCallbackDecorator[V, MentionableSelectT]:
|
) -> SelectCallbackDecorator[V, MentionableSelectT]:
|
||||||
...
|
...
|
||||||
@ -761,6 +945,7 @@ def select(
|
|||||||
min_values: int = 1,
|
min_values: int = 1,
|
||||||
max_values: int = 1,
|
max_values: int = 1,
|
||||||
disabled: bool = False,
|
disabled: bool = False,
|
||||||
|
default_values: Sequence[ValidDefaultValues] = MISSING,
|
||||||
row: Optional[int] = None,
|
row: Optional[int] = None,
|
||||||
) -> SelectCallbackDecorator[V, BaseSelectT]:
|
) -> SelectCallbackDecorator[V, BaseSelectT]:
|
||||||
"""A decorator that attaches a select menu to a component.
|
"""A decorator that attaches a select menu to a component.
|
||||||
@ -832,6 +1017,12 @@ def select(
|
|||||||
with :class:`ChannelSelect` instances.
|
with :class:`ChannelSelect` instances.
|
||||||
disabled: :class:`bool`
|
disabled: :class:`bool`
|
||||||
Whether the select is disabled or not. Defaults to ``False``.
|
Whether the select is disabled or not. Defaults to ``False``.
|
||||||
|
default_values: Sequence[:class:`~discord.abc.Snowflake`]
|
||||||
|
A list of objects representing the default values for the select menu. This cannot be used with regular :class:`Select` instances.
|
||||||
|
If ``cls`` is :class:`MentionableSelect` and :class:`.Object` is passed, then the type must be specified in the constructor.
|
||||||
|
if `cls` is :class:`MentionableSelect` and :class:`.Object` is passed, then the type must be specified in the constructor.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def decorator(func: ItemCallbackType[V, BaseSelectT]) -> ItemCallbackType[V, BaseSelectT]:
|
def decorator(func: ItemCallbackType[V, BaseSelectT]) -> ItemCallbackType[V, BaseSelectT]:
|
||||||
@ -855,6 +1046,24 @@ def select(
|
|||||||
func.__discord_ui_model_kwargs__['options'] = options
|
func.__discord_ui_model_kwargs__['options'] = options
|
||||||
if issubclass(callback_cls, ChannelSelect):
|
if issubclass(callback_cls, ChannelSelect):
|
||||||
func.__discord_ui_model_kwargs__['channel_types'] = channel_types
|
func.__discord_ui_model_kwargs__['channel_types'] = channel_types
|
||||||
|
if not issubclass(callback_cls, Select):
|
||||||
|
cls_to_type: Dict[
|
||||||
|
Type[BaseSelect],
|
||||||
|
Literal[
|
||||||
|
ComponentType.user_select,
|
||||||
|
ComponentType.channel_select,
|
||||||
|
ComponentType.role_select,
|
||||||
|
ComponentType.mentionable_select,
|
||||||
|
],
|
||||||
|
] = {
|
||||||
|
UserSelect: ComponentType.user_select,
|
||||||
|
RoleSelect: ComponentType.role_select,
|
||||||
|
MentionableSelect: ComponentType.mentionable_select,
|
||||||
|
ChannelSelect: ComponentType.channel_select,
|
||||||
|
}
|
||||||
|
func.__discord_ui_model_kwargs__['default_values'] = (
|
||||||
|
MISSING if default_values is MISSING else _handle_select_defaults(default_values, cls_to_type[callback_cls])
|
||||||
|
)
|
||||||
|
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
18
docs/api.rst
18
docs/api.rst
@ -3392,6 +3392,24 @@ of :class:`enum.Enum`.
|
|||||||
|
|
||||||
Sort forum posts by creation time (from most recent to oldest).
|
Sort forum posts by creation time (from most recent to oldest).
|
||||||
|
|
||||||
|
.. class:: SelectDefaultValueType
|
||||||
|
|
||||||
|
Represents the default value of a select menu.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
.. attribute:: user
|
||||||
|
|
||||||
|
The underlying type of the ID is a user.
|
||||||
|
|
||||||
|
.. attribute:: role
|
||||||
|
|
||||||
|
The underlying type of the ID is a role.
|
||||||
|
|
||||||
|
.. attribute:: channel
|
||||||
|
|
||||||
|
The underlying type of the ID is a channel or thread.
|
||||||
|
|
||||||
|
|
||||||
.. _discord-api-audit-logs:
|
.. _discord-api-audit-logs:
|
||||||
|
|
||||||
|
@ -166,6 +166,14 @@ SelectOption
|
|||||||
.. autoclass:: SelectOption
|
.. autoclass:: SelectOption
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
SelectDefaultValue
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. attributetable:: SelectDefaultValue
|
||||||
|
|
||||||
|
.. autoclass:: SelectDefaultValue
|
||||||
|
:members:
|
||||||
|
|
||||||
Choice
|
Choice
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user