diff --git a/discord/channel.py b/discord/channel.py index dc06cbe78..b8ce9cb0a 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -47,7 +47,7 @@ import datetime import discord.abc from .scheduled_event import ScheduledEvent from .permissions import PermissionOverwrite, Permissions -from .enums import ChannelType, EntityType, ForumLayoutType, PrivacyLevel, try_enum, VideoQualityMode +from .enums import ChannelType, EntityType, ForumLayoutType, ForumOrderType, PrivacyLevel, try_enum, VideoQualityMode from .calls import PrivateCall, GroupCall from .mixins import Hashable from . import utils @@ -2043,8 +2043,6 @@ class ForumTag(Hashable): class ForumChannel(discord.abc.GuildChannel, Hashable): """Represents a Discord guild forum channel. - .. versionadded:: 2.0 - .. container:: operations .. describe:: x == y @@ -2063,6 +2061,8 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): Returns the forum's name. + .. versionadded:: 2.0 + Attributes ----------- name: :class:`str` @@ -2094,18 +2094,14 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): The default auto archive duration in minutes for threads created in this forum. default_thread_slowmode_delay: :class:`int` The default slowmode delay in seconds for threads created in this forum. - - .. versionadded:: 2.0 default_reaction_emoji: Optional[:class:`PartialEmoji`] The default reaction emoji for threads created in this forum to show in the add reaction button. - - .. versionadded:: 2.0 default_layout: :class:`ForumLayoutType` The default layout for posts in this forum channel. Defaults to :attr:`ForumLayoutType.not_set`. - - .. versionadded:: 2.0 + default_sort_order: Optional[:class:`ForumOrderType`] + The default sort order for posts in this forum channel. """ __slots__ = ( @@ -2125,6 +2121,7 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): 'default_thread_slowmode_delay', 'default_reaction_emoji', 'default_layout', + 'default_sort_order', '_available_tags', '_flags', ) @@ -2170,6 +2167,11 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): name=default_reaction_emoji.get('emoji_name') or '', ) + self.default_sort_order: Optional[ForumOrderType] = None + default_sort_order = data.get('default_sort_order') + if default_sort_order is not None: + self.default_sort_order = try_enum(ForumOrderType, default_sort_order) + self._flags: int = data.get('flags', 0) self._fill_overwrites(data) @@ -2292,6 +2294,7 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): default_thread_slowmode_delay: int = ..., default_reaction_emoji: Optional[EmojiInputType] = ..., default_layout: ForumLayoutType = ..., + default_sort_order: ForumOrderType = ..., require_tag: bool = ..., ) -> ForumChannel: ... @@ -2336,25 +2339,17 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): Must be one of ``60``, ``1440``, ``4320``, or ``10080``. available_tags: Sequence[:class:`ForumTag`] The new available tags for this forum. - - .. versionadded:: 2.0 default_thread_slowmode_delay: :class:`int` The new default slowmode delay for threads in this channel. - - .. versionadded:: 2.0 default_reaction_emoji: Optional[Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`]] The new default reaction emoji for threads in this channel. - - .. versionadded:: 2.0 default_layout: :class:`ForumLayoutType` The new default layout for posts in this forum. - - .. versionadded:: 2.0 + default_sort_order: Optional[:class:`ForumOrderType`] + The new default sort order for posts in this forum. require_tag: :class:`bool` Whether to require a tag for threads in this channel or not. - .. versionadded:: 2.0 - Raises ------ ValueError @@ -2412,6 +2407,21 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): options['default_forum_layout'] = layout.value + try: + sort_order = options.pop('default_sort_order') + except KeyError: + pass + else: + if sort_order is None: + options['default_sort_order'] = None + else: + if not isinstance(sort_order, ForumOrderType): + raise TypeError( + f'default_sort_order parameter must be a ForumOrderType not {sort_order.__class__.__name__}' + ) + + options['default_sort_order'] = sort_order.value + payload = await self._edit(options, reason=reason) if payload is not None: # the payload will always be the proper channel payload diff --git a/discord/enums.py b/discord/enums.py index e3102cf3e..624de83d8 100644 --- a/discord/enums.py +++ b/discord/enums.py @@ -112,6 +112,7 @@ __all__ = ( 'AutoModRuleEventType', 'AutoModRuleActionType', 'ForumLayoutType', + 'ForumOrderType', ) if TYPE_CHECKING: @@ -1489,6 +1490,11 @@ class ForumLayoutType(Enum): gallery_view = 2 +class ForumOrderType(Enum): + latest_activity = 0 + creation_date = 1 + + def create_unknown_value(cls: Type[E], val: Any) -> E: value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below name = f'unknown_{val}' diff --git a/discord/ext/commands/errors.py b/discord/ext/commands/errors.py index 48ae70bbb..55561b762 100644 --- a/discord/ext/commands/errors.py +++ b/discord/ext/commands/errors.py @@ -921,7 +921,7 @@ class BadLiteralArgument(UserInputError): argument: :class:`str` The argument's value that failed to be converted. Defaults to an empty string. - .. versionadded:: 2.3 + .. versionadded:: 2.0 """ def __init__(self, param: Parameter, literals: Tuple[Any, ...], errors: List[CommandError], argument: str = "") -> None: diff --git a/discord/guild.py b/discord/guild.py index cd0cdfb6b..8e558702c 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -72,6 +72,7 @@ from .enums import ( MFALevel, Locale, AutoModRuleEventType, + ForumOrderType, ) from .mixins import Hashable from .user import User @@ -1642,6 +1643,7 @@ class Guild(Hashable): reason: Optional[str] = None, default_auto_archive_duration: int = MISSING, default_thread_slowmode_delay: int = MISSING, + default_sort_order: Optional[ForumOrderType] = None, available_tags: Sequence[ForumTag] = MISSING, ) -> ForumChannel: """|coro| @@ -1684,6 +1686,8 @@ class Guild(Hashable): Must be one of ``60``, ``1440``, ``4320``, or ``10080``. default_thread_slowmode_delay: :class:`int` The default slowmode delay in seconds for threads created in this forum. + default_sort_order: Optional[:class:`ForumOrderType`] + The default sort order for posts in this forum channel. available_tags: Sequence[:class:`ForumTag`] The available tags for this forum channel. @@ -1721,6 +1725,16 @@ class Guild(Hashable): if default_thread_slowmode_delay is not MISSING: options['default_thread_rate_limit_per_user'] = default_thread_slowmode_delay + if default_sort_order is None: + options['default_sort_order'] = None + else: + if not isinstance(default_sort_order, ForumOrderType): + raise TypeError( + f'default_sort_order parameter must be a ForumOrderType not {default_sort_order.__class__.__name__}' + ) + + options['default_sort_order'] = default_sort_order.value + if available_tags is not MISSING: options['available_tags'] = [t.to_dict() for t in available_tags] diff --git a/discord/http.py b/discord/http.py index 6eac1dd42..8b97504bd 100644 --- a/discord/http.py +++ b/discord/http.py @@ -1379,6 +1379,7 @@ class HTTPClient: 'available_tags', 'applied_tags', 'default_forum_layout', + 'default_sort_order', ) payload = {k: v for k, v in options.items() if k in valid_keys} @@ -1419,6 +1420,7 @@ class HTTPClient: 'video_quality_mode', 'default_auto_archive_duration', 'default_thread_rate_limit_per_user', + 'default_sort_order', 'available_tags', ) payload.update({k: v for k, v in options.items() if k in valid_keys and v is not None}) diff --git a/discord/types/channel.py b/discord/types/channel.py index b385aab72..9369919b9 100644 --- a/discord/types/channel.py +++ b/discord/types/channel.py @@ -140,6 +140,7 @@ class ForumTag(TypedDict): emoji_name: Optional[str] +ForumOrderType = Literal[0, 1] ForumLayoutType = Literal[0, 1, 2] @@ -147,6 +148,7 @@ class ForumChannel(_BaseTextChannel): type: Literal[15] available_tags: List[ForumTag] default_reaction_emoji: Optional[DefaultReaction] + default_sort_order: Optional[ForumOrderType] default_forum_layout: NotRequired[ForumLayoutType] flags: NotRequired[int] diff --git a/docs/api.rst b/docs/api.rst index 1152373d9..ba63687f8 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -5453,6 +5453,21 @@ of :class:`enum.Enum`. Displays posts as a collection of tiles. +.. class:: ForumOrderType + + Represents how a forum's posts are sorted in the client. + + .. versionadded:: 2.0 + + .. attribute:: latest_activity + + Sort forum posts by activity. + + .. attribute:: creation_date + + Sort forum posts by creation time (from most recent to oldest). + + .. _discord-api-audit-logs: Audit Log Data