diff --git a/changelog/1175.feature.rst b/changelog/1175.feature.rst index 78dd79b311..5c839ba33f 100644 --- a/changelog/1175.feature.rst +++ b/changelog/1175.feature.rst @@ -1,6 +1,6 @@ Add the new poll discord API feature. This includes the following new classes and events: -- New types: :class:`Poll`, :class:`PollAnswer`, :class:`PollMedia`, :class:`RawMessagePollVoteActionEvent` and :class:`PollLayoutType`. +- New types: :class:`Poll`, :class:`PollAnswer`, :class:`PollMedia`, :class:`RawPollVoteActionEvent` and :class:`PollLayoutType`. - Edited :meth:`abc.Messageable.send`, :meth:`Webhook.send`, :meth:`ext.commands.Context.send` and :meth:`disnake.InteractionResponse.send_message` to be able to send polls. - Edited :class:`Message` to store a new :attr:`Message.poll` attribute for polls. -- Edited :class:`Event` to contain the new :func:`on_message_poll_vote_add`, :func:`on_message_poll_vote_remove`, :func:`on_raw_message_poll_vote_add` and :func:`on_raw_message_poll_vote_remove`. +- Edited :class:`Event` to contain the new :func:`on_poll_vote_add`, :func:`on_poll_vote_remove`, :func:`on_raw_poll_vote_add` and :func:`on_raw_poll_vote_remove`. diff --git a/changelog/1233.feature.rst b/changelog/1233.feature.rst new file mode 100644 index 0000000000..5a2cea0fa0 --- /dev/null +++ b/changelog/1233.feature.rst @@ -0,0 +1,2 @@ +For interactions in private channels, :attr:`Interaction.channel` is now always a proper :class:`DMChannel` or :class:`GroupChannel` object, instead of :class:`PartialMessageable`. +- This also applies to other channel objects in interactions, e.g. channel parameters in slash commands, or :attr:`ui.ChannelSelect.values`. diff --git a/disnake/abc.py b/disnake/abc.py index b5b0f5509e..c6c4c651cf 100644 --- a/disnake/abc.py +++ b/disnake/abc.py @@ -64,12 +64,12 @@ from typing_extensions import Self from .asset import Asset - from .channel import CategoryChannel, DMChannel, PartialMessageable + from .channel import CategoryChannel, DMChannel, GroupChannel, PartialMessageable from .client import Client from .embeds import Embed from .emoji import Emoji from .enums import InviteTarget - from .guild import Guild, GuildMessageable + from .guild import Guild, GuildChannel as AnyGuildChannel, GuildMessageable from .guild_scheduled_event import GuildScheduledEvent from .iterators import HistoryIterator from .member import Member @@ -90,7 +90,10 @@ from .user import ClientUser from .voice_region import VoiceRegion - MessageableChannel = Union[GuildMessageable, DMChannel, PartialMessageable] + MessageableChannel = Union[GuildMessageable, DMChannel, GroupChannel, PartialMessageable] + # include non-messageable channels, e.g. category/forum + AnyChannel = Union[MessageableChannel, AnyGuildChannel] + SnowflakeTime = Union["Snowflake", datetime] MISSING = utils.MISSING diff --git a/disnake/channel.py b/disnake/channel.py index 1f84e702b3..980a5ea1ce 100644 --- a/disnake/channel.py +++ b/disnake/channel.py @@ -4663,7 +4663,10 @@ class DMChannel(disnake.abc.Messageable, Hashable): def __init__(self, *, me: ClientUser, state: ConnectionState, data: DMChannelPayload) -> None: self._state: ConnectionState = state - self.recipient: Optional[User] = state.store_user(data["recipients"][0]) # type: ignore + self.recipient: Optional[User] = None + if recipients := data.get("recipients"): + self.recipient = state.store_user(recipients[0]) # type: ignore + self.me: ClientUser = me self.id: int = int(data["id"]) self.last_pin_timestamp: Optional[datetime.datetime] = utils.parse_time( @@ -4803,8 +4806,10 @@ class GroupChannel(disnake.abc.Messageable, Hashable): ---------- recipients: List[:class:`User`] The users you are participating with in the group channel. + If this channel is received through the gateway, the recipient information + may not be always available. me: :class:`ClientUser` - The user presenting yourself. + The user representing yourself. id: :class:`int` The group channel ID. owner: Optional[:class:`User`] diff --git a/disnake/ext/commands/cog.py b/disnake/ext/commands/cog.py index 01fd59937c..bc1cff6e9a 100644 --- a/disnake/ext/commands/cog.py +++ b/disnake/ext/commands/cog.py @@ -34,6 +34,7 @@ from disnake.interactions import ApplicationCommandInteraction + from ._types import MaybeCoro from .bot import AutoShardedBot, AutoShardedInteractionBot, Bot, InteractionBot from .context import Context from .core import Command @@ -491,7 +492,7 @@ def cog_unload(self) -> None: pass @_cog_special_method - def bot_check_once(self, ctx: Context) -> bool: + def bot_check_once(self, ctx: Context) -> MaybeCoro[bool]: """A special method that registers as a :meth:`.Bot.check_once` check. @@ -503,7 +504,7 @@ def bot_check_once(self, ctx: Context) -> bool: return True @_cog_special_method - def bot_check(self, ctx: Context) -> bool: + def bot_check(self, ctx: Context) -> MaybeCoro[bool]: """A special method that registers as a :meth:`.Bot.check` check. @@ -515,7 +516,7 @@ def bot_check(self, ctx: Context) -> bool: return True @_cog_special_method - def bot_slash_command_check_once(self, inter: ApplicationCommandInteraction) -> bool: + def bot_slash_command_check_once(self, inter: ApplicationCommandInteraction) -> MaybeCoro[bool]: """A special method that registers as a :meth:`.Bot.slash_command_check_once` check. @@ -525,7 +526,7 @@ def bot_slash_command_check_once(self, inter: ApplicationCommandInteraction) -> return True @_cog_special_method - def bot_slash_command_check(self, inter: ApplicationCommandInteraction) -> bool: + def bot_slash_command_check(self, inter: ApplicationCommandInteraction) -> MaybeCoro[bool]: """A special method that registers as a :meth:`.Bot.slash_command_check` check. @@ -535,27 +536,29 @@ def bot_slash_command_check(self, inter: ApplicationCommandInteraction) -> bool: return True @_cog_special_method - def bot_user_command_check_once(self, inter: ApplicationCommandInteraction) -> bool: + def bot_user_command_check_once(self, inter: ApplicationCommandInteraction) -> MaybeCoro[bool]: """Similar to :meth:`.Bot.slash_command_check_once` but for user commands.""" return True @_cog_special_method - def bot_user_command_check(self, inter: ApplicationCommandInteraction) -> bool: + def bot_user_command_check(self, inter: ApplicationCommandInteraction) -> MaybeCoro[bool]: """Similar to :meth:`.Bot.slash_command_check` but for user commands.""" return True @_cog_special_method - def bot_message_command_check_once(self, inter: ApplicationCommandInteraction) -> bool: + def bot_message_command_check_once( + self, inter: ApplicationCommandInteraction + ) -> MaybeCoro[bool]: """Similar to :meth:`.Bot.slash_command_check_once` but for message commands.""" return True @_cog_special_method - def bot_message_command_check(self, inter: ApplicationCommandInteraction) -> bool: + def bot_message_command_check(self, inter: ApplicationCommandInteraction) -> MaybeCoro[bool]: """Similar to :meth:`.Bot.slash_command_check` but for message commands.""" return True @_cog_special_method - def cog_check(self, ctx: Context) -> bool: + def cog_check(self, ctx: Context) -> MaybeCoro[bool]: """A special method that registers as a :func:`~.check` for every text command and subcommand in this cog. @@ -567,7 +570,7 @@ def cog_check(self, ctx: Context) -> bool: return True @_cog_special_method - def cog_slash_command_check(self, inter: ApplicationCommandInteraction) -> bool: + def cog_slash_command_check(self, inter: ApplicationCommandInteraction) -> MaybeCoro[bool]: """A special method that registers as a :func:`~.check` for every slash command and subcommand in this cog. @@ -577,12 +580,12 @@ def cog_slash_command_check(self, inter: ApplicationCommandInteraction) -> bool: return True @_cog_special_method - def cog_user_command_check(self, inter: ApplicationCommandInteraction) -> bool: + def cog_user_command_check(self, inter: ApplicationCommandInteraction) -> MaybeCoro[bool]: """Similar to :meth:`.Cog.cog_slash_command_check` but for user commands.""" return True @_cog_special_method - def cog_message_command_check(self, inter: ApplicationCommandInteraction) -> bool: + def cog_message_command_check(self, inter: ApplicationCommandInteraction) -> MaybeCoro[bool]: """Similar to :meth:`.Cog.cog_slash_command_check` but for message commands.""" return True diff --git a/disnake/ext/commands/context.py b/disnake/ext/commands/context.py index 0876e7d3a4..9c23583d28 100644 --- a/disnake/ext/commands/context.py +++ b/disnake/ext/commands/context.py @@ -14,7 +14,7 @@ if TYPE_CHECKING: from typing_extensions import ParamSpec - from disnake.channel import DMChannel + from disnake.channel import DMChannel, GroupChannel from disnake.guild import Guild, GuildMessageable from disnake.member import Member from disnake.state import ConnectionState @@ -262,7 +262,7 @@ def guild(self) -> Optional[Guild]: return self.message.guild @disnake.utils.cached_property - def channel(self) -> Union[GuildMessageable, DMChannel]: + def channel(self) -> Union[GuildMessageable, DMChannel, GroupChannel]: """Union[:class:`.abc.Messageable`]: Returns the channel associated with this context's command. Shorthand for :attr:`.Message.channel`. """ diff --git a/disnake/interactions/application_command.py b/disnake/interactions/application_command.py index 46eee43985..bd85325a36 100644 --- a/disnake/interactions/application_command.py +++ b/disnake/interactions/application_command.py @@ -58,16 +58,18 @@ class ApplicationCommandInteraction(Interaction[ClientT]): The application ID that the interaction was for. guild_id: Optional[:class:`int`] The guild ID the interaction was sent from. - channel: Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`PartialMessageable`] + channel: Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`abc.PrivateChannel`, :class:`PartialMessageable`] The channel the interaction was sent from. Note that due to a Discord limitation, DM channels - are not resolved as there is no data to complete them. - These are :class:`PartialMessageable` instead. + may not contain recipient information. + Unknown channel types will be :class:`PartialMessageable`. .. versionchanged:: 2.10 If the interaction was sent from a thread and the bot cannot normally access the thread, this is now a proper :class:`Thread` object. + Private channels are now proper :class:`DMChannel`/:class:`GroupChannel` + objects instead of :class:`PartialMessageable`. .. note:: If you want to compute the interaction author's or bot's permissions in the channel, diff --git a/disnake/interactions/base.py b/disnake/interactions/base.py index 7e43874bcd..585406ed41 100644 --- a/disnake/interactions/base.py +++ b/disnake/interactions/base.py @@ -65,13 +65,12 @@ from aiohttp import ClientSession - from ..abc import MessageableChannel + from ..abc import AnyChannel, MessageableChannel from ..app_commands import Choices from ..client import Client from ..embeds import Embed from ..ext.commands import AutoShardedBot, Bot from ..file import File - from ..guild import GuildChannel, GuildMessageable from ..mentions import AllowedMentions from ..poll import Poll from ..state import ConnectionState @@ -88,9 +87,6 @@ from .message import MessageInteraction from .modal import ModalInteraction - InteractionMessageable = Union[GuildMessageable, PartialMessageable] - InteractionChannel = Union[InteractionMessageable, GuildChannel] - AnyBot = Union[Bot, AutoShardedBot] @@ -130,16 +126,18 @@ class Interaction(Generic[ClientT]): .. versionchanged:: 2.5 Changed to :class:`Locale` instead of :class:`str`. - channel: Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`PartialMessageable`] + channel: Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`abc.PrivateChannel`, :class:`PartialMessageable`] The channel the interaction was sent from. Note that due to a Discord limitation, DM channels - are not resolved as there is no data to complete them. - These are :class:`PartialMessageable` instead. + may not contain recipient information. + Unknown channel types will be :class:`PartialMessageable`. .. versionchanged:: 2.10 If the interaction was sent from a thread and the bot cannot normally access the thread, this is now a proper :class:`Thread` object. + Private channels are now proper :class:`DMChannel`/:class:`GroupChannel` + objects instead of :class:`PartialMessageable`. .. note:: If you want to compute the interaction author's or bot's permissions in the channel, @@ -236,7 +234,7 @@ def __init__(self, *, data: InteractionPayload, state: ConnectionState) -> None: self.author = self._state.store_user(user) # TODO: consider making this optional in 3.0 - self.channel: InteractionMessageable = state._get_partial_interaction_channel( + self.channel: MessageableChannel = state._get_partial_interaction_channel( data["channel"], guild_fallback, return_messageable=True ) @@ -1866,7 +1864,7 @@ class InteractionDataResolved(Dict[str, Any]): A mapping of IDs to users. roles: Dict[:class:`int`, :class:`Role`] A mapping of IDs to roles. - channels: Dict[:class:`int`, Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`PartialMessageable`]] + channels: Dict[:class:`int`, Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`abc.PrivateChannel`, :class:`PartialMessageable`]] A mapping of IDs to partial channels (only ``id``, ``name`` and ``permissions`` are included, threads also have ``thread_metadata`` and ``parent_id``). messages: Dict[:class:`int`, :class:`Message`] @@ -1891,7 +1889,7 @@ def __init__( self.members: Dict[int, Member] = {} self.users: Dict[int, User] = {} self.roles: Dict[int, Role] = {} - self.channels: Dict[int, InteractionChannel] = {} + self.channels: Dict[int, AnyChannel] = {} self.messages: Dict[int, Message] = {} self.attachments: Dict[int, Attachment] = {} @@ -1946,25 +1944,20 @@ def __init__( channel_id = int(message["channel_id"]) channel: Optional[MessageableChannel] = None - if ( - channel_id == parent.channel.id - # we still want to fall back to state.get_channel when the - # parent channel is a dm/group channel, for now. - # FIXME: remove this once `parent.channel` supports `DMChannel` - and not isinstance(parent.channel, PartialMessageable) - ): + if channel_id == parent.channel.id: # fast path, this should generally be the case channel = parent.channel else: + # in case this ever happens, fall back to guild channel cache channel = cast( "Optional[MessageableChannel]", - (guild and guild.get_channel(channel_id) or state.get_channel(channel_id)), + (guild and guild.get_channel(channel_id)), ) - if channel is None: - # n.b. the message's channel is not sent as part of `resolved.channels`, - # so we need to fall back to partials here. - channel = PartialMessageable(state=state, id=channel_id, type=None) + if channel is None: + # n.b. the message's channel is not sent as part of `resolved.channels`, + # so we need to fall back to partials here. + channel = PartialMessageable(state=state, id=channel_id, type=None) self.messages[int(str_id)] = Message(state=state, channel=channel, data=message) @@ -1980,18 +1973,18 @@ def __repr__(self) -> str: @overload def get_with_type( self, key: Snowflake, data_type: Union[OptionType, ComponentType] - ) -> Union[Member, User, Role, InteractionChannel, Message, Attachment, None]: + ) -> Union[Member, User, Role, AnyChannel, Message, Attachment, None]: ... @overload def get_with_type( self, key: Snowflake, data_type: Union[OptionType, ComponentType], default: T - ) -> Union[Member, User, Role, InteractionChannel, Message, Attachment, T]: + ) -> Union[Member, User, Role, AnyChannel, Message, Attachment, T]: ... def get_with_type( self, key: Snowflake, data_type: Union[OptionType, ComponentType], default: T = None - ) -> Union[Member, User, Role, InteractionChannel, Message, Attachment, T, None]: + ) -> Union[Member, User, Role, AnyChannel, Message, Attachment, T, None]: if data_type is OptionType.mentionable or data_type is ComponentType.mentionable_select: key = int(key) if (result := self.members.get(key)) is not None: @@ -2019,7 +2012,7 @@ def get_with_type( def get_by_id( self, key: Optional[int] - ) -> Optional[Union[Member, User, Role, InteractionChannel, Message, Attachment]]: + ) -> Optional[Union[Member, User, Role, AnyChannel, Message, Attachment]]: if key is None: return None diff --git a/disnake/interactions/message.py b/disnake/interactions/message.py index 8ce8c3d3ab..3341e29b11 100644 --- a/disnake/interactions/message.py +++ b/disnake/interactions/message.py @@ -16,6 +16,7 @@ ) if TYPE_CHECKING: + from ..abc import AnyChannel from ..member import Member from ..role import Role from ..state import ConnectionState @@ -25,7 +26,6 @@ MessageInteraction as MessageInteractionPayload, ) from ..user import User - from .base import InteractionChannel class MessageInteraction(Interaction[ClientT]): @@ -47,16 +47,18 @@ class MessageInteraction(Interaction[ClientT]): The token to continue the interaction. These are valid for 15 minutes. guild_id: Optional[:class:`int`] The guild ID the interaction was sent from. - channel: Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`PartialMessageable`] + channel: Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`abc.PrivateChannel`, :class:`PartialMessageable`] The channel the interaction was sent from. Note that due to a Discord limitation, DM channels - are not resolved as there is no data to complete them. - These are :class:`PartialMessageable` instead. + may not contain recipient information. + Unknown channel types will be :class:`PartialMessageable`. .. versionchanged:: 2.10 If the interaction was sent from a thread and the bot cannot normally access the thread, this is now a proper :class:`Thread` object. + Private channels are now proper :class:`DMChannel`/:class:`GroupChannel` + objects instead of :class:`PartialMessageable`. .. note:: If you want to compute the interaction author's or bot's permissions in the channel, @@ -116,7 +118,7 @@ def values(self) -> Optional[List[str]]: @cached_slot_property("_cs_resolved_values") def resolved_values( self, - ) -> Optional[Sequence[Union[str, Member, User, Role, InteractionChannel]]]: + ) -> Optional[Sequence[Union[str, Member, User, Role, AnyChannel]]]: """Optional[Sequence[:class:`str`, :class:`Member`, :class:`User`, :class:`Role`, Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`PartialMessageable`]]]: The (resolved) values the user selected. For select menus of type :attr:`~ComponentType.string_select`, @@ -134,7 +136,7 @@ def resolved_values( return self.data.values resolved = self.data.resolved - values: List[Union[Member, User, Role, InteractionChannel]] = [] + values: List[Union[Member, User, Role, AnyChannel]] = [] for key in self.data.values: # force upcast to avoid typing issues; we expect the api to only provide valid values value: Any = resolved.get_with_type(key, component_type, key) diff --git a/disnake/interactions/modal.py b/disnake/interactions/modal.py index be9520b1cf..98c2358bcc 100644 --- a/disnake/interactions/modal.py +++ b/disnake/interactions/modal.py @@ -39,16 +39,18 @@ class ModalInteraction(Interaction[ClientT]): These are valid for 15 minutes. guild_id: Optional[:class:`int`] The guild ID the interaction was sent from. - channel: Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`PartialMessageable`] + channel: Union[:class:`abc.GuildChannel`, :class:`Thread`, :class:`abc.PrivateChannel`, :class:`PartialMessageable`] The channel the interaction was sent from. Note that due to a Discord limitation, DM channels - are not resolved as there is no data to complete them. - These are :class:`PartialMessageable` instead. + may not contain recipient information. + Unknown channel types will be :class:`PartialMessageable`. .. versionchanged:: 2.10 If the interaction was sent from a thread and the bot cannot normally access the thread, this is now a proper :class:`Thread` object. + Private channels are now proper :class:`DMChannel`/:class:`GroupChannel` + objects instead of :class:`PartialMessageable`. .. note:: If you want to compute the interaction author's or bot's permissions in the channel, diff --git a/disnake/message.py b/disnake/message.py index 9d6c16d56d..f67da56a28 100644 --- a/disnake/message.py +++ b/disnake/message.py @@ -46,7 +46,7 @@ from typing_extensions import Self from .abc import GuildChannel, MessageableChannel, Snowflake - from .channel import DMChannel + from .channel import DMChannel, GroupChannel from .guild import GuildMessageable from .mentions import AllowedMentions from .role import Role @@ -1007,7 +1007,7 @@ def __init__( self.activity: Optional[MessageActivityPayload] = data.get("activity") # for user experience, on_message has no business getting partials # TODO: Subscripted message to include the channel - self.channel: Union[GuildMessageable, DMChannel] = channel # type: ignore + self.channel: Union[GuildMessageable, DMChannel, GroupChannel] = channel # type: ignore self.position: Optional[int] = data.get("position", None) self._edited_timestamp: Optional[datetime.datetime] = utils.parse_time( data["edited_timestamp"] @@ -2258,7 +2258,7 @@ class PartialMessage(Hashable): Attributes ---------- - channel: Union[:class:`TextChannel`, :class:`Thread`, :class:`DMChannel`, :class:`VoiceChannel`, :class:`StageChannel`, :class:`PartialMessageable`] + channel: Union[:class:`TextChannel`, :class:`VoiceChannel`, :class:`StageChannel`, :class:`Thread`, :class:`DMChannel`, :class:`GroupChannel`, :class:`PartialMessageable`] The channel associated with this partial message. id: :class:`int` The message ID. diff --git a/disnake/state.py b/disnake/state.py index 222b2ad3ee..a467ed6b0c 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -43,7 +43,7 @@ TextChannel, VoiceChannel, _guild_channel_factory, - _threaded_guild_channel_factory, + _threaded_channel_factory, ) from .emoji import Emoji from .entitlement import Entitlement @@ -91,13 +91,12 @@ from .webhook import Webhook if TYPE_CHECKING: - from .abc import MessageableChannel, PrivateChannel + from .abc import AnyChannel, MessageableChannel, PrivateChannel from .app_commands import APIApplicationCommand, ApplicationCommand from .client import Client from .gateway import DiscordWebSocket from .guild import GuildChannel, VocalGuildChannel from .http import HTTPClient - from .interactions.base import InteractionChannel, InteractionMessageable from .types import gateway from .types.activity import Activity as ActivityPayload from .types.channel import DMChannel as DMChannelPayload @@ -2039,7 +2038,7 @@ def _get_partial_interaction_channel( guild: Optional[Union[Guild, Object]], *, return_messageable: Literal[False] = False, - ) -> InteractionChannel: + ) -> AnyChannel: ... @overload @@ -2049,10 +2048,10 @@ def _get_partial_interaction_channel( guild: Optional[Union[Guild, Object]], *, return_messageable: Literal[True], - ) -> InteractionMessageable: + ) -> MessageableChannel: ... - # note: this resolves private channels (and unknown types) to `PartialMessageable` + # note: this resolves unknown types to `PartialMessageable` def _get_partial_interaction_channel( self, data: InteractionChannelPayload, @@ -2060,18 +2059,26 @@ def _get_partial_interaction_channel( *, # this param is purely for type-checking, it has no effect on runtime behavior. return_messageable: bool = False, - ) -> InteractionChannel: + ) -> AnyChannel: channel_id = int(data["id"]) channel_type = data["type"] - factory, _ = _threaded_guild_channel_factory(channel_type) - if not factory or not guild: + factory, ch_type = _threaded_channel_factory(channel_type) + if not factory: return PartialMessageable( state=self, id=channel_id, - type=try_enum(ChannelType, channel_type), + type=ch_type, ) + if ch_type in (ChannelType.group, ChannelType.private): + return ( + self._get_private_channel(channel_id) + # the factory will be a DMChannel or GroupChannel here + or factory(me=self.user, data=data, state=self) # type: ignore + ) + + # the factory can't be a DMChannel or GroupChannel here data.setdefault("position", 0) # type: ignore return ( isinstance(guild, Guild) diff --git a/disnake/ui/select/channel.py b/disnake/ui/select/channel.py index 57dd9cfbe9..9214b71223 100644 --- a/disnake/ui/select/channel.py +++ b/disnake/ui/select/channel.py @@ -12,7 +12,7 @@ if TYPE_CHECKING: from typing_extensions import Self - from ...interactions.base import InteractionChannel + from ...abc import AnyChannel from ..item import DecoratedItem, ItemCallbackType, Object @@ -22,7 +22,7 @@ ) -class ChannelSelect(BaseSelect[ChannelSelectMenu, "InteractionChannel", V_co]): +class ChannelSelect(BaseSelect[ChannelSelectMenu, "AnyChannel", V_co]): """Represents a UI channel select menu. This is usually represented as a drop down menu. @@ -58,7 +58,7 @@ class ChannelSelect(BaseSelect[ChannelSelectMenu, "InteractionChannel", V_co]): Attributes ---------- - values: List[Union[:class:`.abc.GuildChannel`, :class:`.Thread`, :class:`.PartialMessageable`]] + values: List[Union[:class:`.abc.GuildChannel`, :class:`.Thread`, :class:`.abc.PrivateChannel`, :class:`.PartialMessageable`]] A list of channels that have been selected by the user. """ diff --git a/docs/_static/style.css b/docs/_static/style.css index b89e43a930..fb9bece8b5 100644 --- a/docs/_static/style.css +++ b/docs/_static/style.css @@ -103,7 +103,7 @@ Historically however, thanks to: --rtd-ad-background: var(--grey-2); --rtd-ad-main-text: var(--grey-6); --rtd-ad-small-text: var(--grey-4); - --rtd-version-background: #272525; + --rtd-version-background: #272725; --rtd-version-main-text: #fcfcfc; --attribute-table-title: var(--grey-6); --attribute-table-list-border: var(--grey-3); @@ -826,7 +826,7 @@ section h3 { } #to-top.is-rtd { - bottom: 90px; + bottom: 100px; } #to-top > span { diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html index ef97d73439..305ec42b45 100644 --- a/docs/_templates/layout.html +++ b/docs/_templates/layout.html @@ -156,16 +156,6 @@ {%- endblock %} - {%- if READTHEDOCS %} - - {%- endif %}