diff --git a/changelog/1307.feature.rst b/changelog/1307.feature.rst new file mode 100644 index 0000000000..fffc2d4eac --- /dev/null +++ b/changelog/1307.feature.rst @@ -0,0 +1 @@ +Add the new :attr:`Activity.details_url`, :attr:`Activity.state_url`, :attr:`Activity.status_display_type` and :class:`StatusDisplayType` RPC attributes and enum. diff --git a/disnake/activity.py b/disnake/activity.py index 97c4381c14..32761f3844 100644 --- a/disnake/activity.py +++ b/disnake/activity.py @@ -7,7 +7,7 @@ from .asset import Asset from .colour import Colour -from .enums import ActivityType, try_enum +from .enums import ActivityType, StatusDisplayType, try_enum from .partial_emoji import PartialEmoji __all__ = ( @@ -181,7 +181,7 @@ def large_image_text(self) -> Optional[str]: .. versionchanged:: 2.10 Moved from :class:`Activity` to base type, making this available to all activity types. """ - return self.assets.get("large_text", None) + return self.assets.get("large_text") @property def small_image_text(self) -> Optional[str]: @@ -190,7 +190,23 @@ def small_image_text(self) -> Optional[str]: .. versionchanged:: 2.10 Moved from :class:`Activity` to base type, making this available to all activity types. """ - return self.assets.get("small_text", None) + return self.assets.get("small_text") + + @property + def large_image_link(self) -> Optional[str]: + """Optional[:class:`str`]: Returns the large image asset URL of this activity, if applicable. + + .. versionadded:: 2.11 + """ + return self.assets.get("large_url") + + @property + def small_image_link(self) -> Optional[str]: + """Optional[:class:`str`]: Returns the small image asset URL of this activity, if applicable. + + .. versionadded:: 2.11 + """ + return self.assets.get("small_url") # tag type for user-settable activities @@ -267,8 +283,10 @@ class Activity(BaseActivity): - ``large_image``: A string representing the ID for the large image asset. - ``large_text``: A string representing the text when hovering over the large image asset. + - ``large_url``: A string representing an URL that is opened when clicking on the large image. - ``small_image``: A string representing the ID for the small image asset. - ``small_text``: A string representing the text when hovering over the small image asset. + - ``small_url``: A string representing a URL that is opened when clicking on the small image. party: :class:`dict` A dictionary representing the activity party. It contains the following optional keys: @@ -284,6 +302,18 @@ class Activity(BaseActivity): emoji: Optional[:class:`PartialEmoji`] The emoji that belongs to this activity. + details_url: Optional[:class:`str`] + An URL that is linked when clicking on the details text of an activity. + + .. versionadded:: 2.11 + state_url: Optional[:class:`str`] + An URL that is linked when clicking on the state text of an activity. + + .. versionadded:: 2.11 + status_display_type: Optional[:class:`StatusDisplayType`] + Controls which field is displayed in the user's status activity text in the member list. + + .. versionadded:: 2.11 """ __slots__ = ( @@ -301,6 +331,9 @@ class Activity(BaseActivity): "platform", "sync_id", "session_id", + "details_url", + "state_url", + "status_display_type", ) def __init__( @@ -310,7 +343,9 @@ def __init__( url: Optional[str] = None, type: Optional[Union[ActivityType, int]] = None, state: Optional[str] = None, + state_url: Optional[str] = None, details: Optional[str] = None, + details_url: Optional[str] = None, party: Optional[ActivityParty] = None, application_id: Optional[Union[str, int]] = None, flags: Optional[int] = None, @@ -320,11 +355,14 @@ def __init__( platform: Optional[str] = None, sync_id: Optional[str] = None, session_id: Optional[str] = None, + status_display_type: Optional[Union[StatusDisplayType, int]] = None, **kwargs: Any, ) -> None: super().__init__(**kwargs) self.state: Optional[str] = state + self.state_url: Optional[str] = state_url self.details: Optional[str] = details + self.details_url: Optional[str] = details_url self.party: ActivityParty = party or {} self.application_id: Optional[int] = ( int(application_id) if application_id is not None else None @@ -347,6 +385,12 @@ def __init__( else try_enum(ActivityType, activity_type) ) + self.status_display_type: Optional[StatusDisplayType] = ( + try_enum(StatusDisplayType, status_display_type) + if isinstance(status_display_type, int) + else status_display_type + ) + self.emoji: Optional[PartialEmoji] = ( PartialEmoji.from_dict(emoji) if emoji is not None else None ) @@ -379,6 +423,9 @@ def to_dict(self) -> Dict[str, Any]: # fix type field ret["type"] = int(self.type) + if self.status_display_type: + ret["status_display_type"] = int(self.status_display_type) + if self.emoji: ret["emoji"] = self.emoji.to_dict() # defined in base class slots diff --git a/disnake/enums.py b/disnake/enums.py index d02b551d56..9d3aee7b04 100644 --- a/disnake/enums.py +++ b/disnake/enums.py @@ -28,6 +28,7 @@ "VerificationLevel", "ContentFilter", "Status", + "StatusDisplayType", "DefaultAvatar", "AuditLogAction", "AuditLogActionCategory", @@ -603,6 +604,23 @@ def __str__(self) -> str: return self.value +class StatusDisplayType(Enum): + """Specifies an :class:`Activity` display status. + + .. versionadded:: 2.11 + """ + + name = 0 # type: ignore[reportAssignmentType] + """The name of the activity is displayed, e.g: ``Listening to Spotify``.""" + state = 1 + """The state of the activity is displayed, e.g: ``Listening to Rick Astley``.""" + details = 2 + """The details of the activity are displayed, e.g: ``Listening to Never Gonna Give You Up``.""" + + def __int__(self) -> int: + return self.value + + class DefaultAvatar(Enum): """Represents the default avatar of a Discord :class:`User`.""" diff --git a/disnake/types/activity.py b/disnake/types/activity.py index 39a292f46a..749f015bdc 100644 --- a/disnake/types/activity.py +++ b/disnake/types/activity.py @@ -10,6 +10,7 @@ from .user import User StatusType = Literal["idle", "dnd", "online", "offline"] +StatusDisplayType = Literal[0, 1, 2] class PresenceData(TypedDict): @@ -44,8 +45,10 @@ class ActivityAssets(TypedDict, total=False): # https://discord.com/developers/docs/topics/gateway-events#activity-object-activity-asset-image large_image: str large_text: str + large_url: str small_image: str small_text: str + small_url: str class ActivitySecrets(TypedDict, total=False): @@ -75,7 +78,9 @@ class Activity(SendableActivity, total=False): timestamps: ActivityTimestamps application_id: Snowflake details: Optional[str] + details_url: Optional[str] state: Optional[str] + state_url: Optional[str] emoji: Optional[ActivityEmoji] party: ActivityParty assets: ActivityAssets @@ -90,3 +95,4 @@ class Activity(SendableActivity, total=False): platform: Optional[str] sync_id: Optional[str] session_id: Optional[str] + status_display_type: Optional[StatusDisplayType] diff --git a/docs/api/activities.rst b/docs/api/activities.rst index 6dd6b34bf2..300e69dedc 100644 --- a/docs/api/activities.rst +++ b/docs/api/activities.rst @@ -83,6 +83,12 @@ Status .. autoclass:: Status() :members: +StatusDisplayType +~~~~~~~~~~~~~~~~~ + +.. autoclass:: StatusDisplayType() + :members: + Events ------