Browse Source

Merge 5633d80459 into 2fbed93624

pull/10285/merge
Soheab 4 days ago
committed by GitHub
parent
commit
154ff2b40a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 26
      discord/enums.py
  2. 76
      discord/member.py
  3. 4
      discord/types/member.py
  4. 11
      discord/types/user.py
  5. 40
      discord/user.py
  6. 92
      docs/api.rst

26
discord/enums.py

@ -87,6 +87,8 @@ __all__ = (
'MediaItemLoadingState',
'CollectibleType',
'NameplatePalette',
'DisplayNameFont',
'DisplayNameEffect',
)
@ -1006,6 +1008,30 @@ class NameplatePalette(Enum):
white = 'white'
class DisplayNameFont(Enum):
default = 11
bangers = 1
bio_rhyme = 2
cherry_bomb = 3
chicle = 4
compagnon = 5
museo_moderno = 6
neo_castel = 7
pixelify = 8
ribes = 9
sinistre = 10
zilla_slab = 12
class DisplayNameEffect(Enum):
solid = 1
gradient = 2
neon = 3
toon = 4
pop = 5
glow = 6
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}'

76
discord/member.py

@ -36,12 +36,13 @@ from .asset import Asset
from .utils import MISSING
from .user import BaseUser, ClientUser, User, _UserTag
from .permissions import Permissions
from .enums import Status
from .enums import DisplayNameEffect, DisplayNameFont, Status
from .errors import ClientException
from .colour import Colour
from .object import Object
from .flags import MemberFlags
from .presences import ClientStatus
from .user import DisplayNameStyle
__all__ = (
'VoiceState',
@ -64,7 +65,7 @@ if TYPE_CHECKING:
UserWithMember as UserWithMemberPayload,
)
from .types.gateway import GuildMemberUpdateEvent
from .types.user import User as UserPayload, AvatarDecorationData
from .types.user import User as UserPayload, AvatarDecorationData, DisplayNameStyle as DisplayNameStylePayload
from .abc import Snowflake
from .state import ConnectionState
from .message import Message
@ -289,6 +290,7 @@ class Member(discord.abc.Messageable, _UserTag):
'_banner',
'_flags',
'_avatar_decoration_data',
'_display_name_style',
)
if TYPE_CHECKING:
@ -329,6 +331,7 @@ class Member(discord.abc.Messageable, _UserTag):
self._permissions: Optional[int]
self._flags: int = data['flags']
self._avatar_decoration_data: Optional[AvatarDecorationData] = data.get('avatar_decoration_data')
self._display_name_style: Optional[DisplayNameStylePayload] = data.get('display_name_style')
try:
self._permissions = int(data['permissions']) # pyright: ignore[reportTypedDictNotRequiredAccess]
except KeyError:
@ -408,6 +411,7 @@ class Member(discord.abc.Messageable, _UserTag):
self._avatar = member._avatar
self._banner = member._banner
self._avatar_decoration_data = member._avatar_decoration_data
self._display_name_style = member._display_name_style
# Reference will not be copied unless necessary by PRESENCE_UPDATE
# See below
@ -438,6 +442,7 @@ class Member(discord.abc.Messageable, _UserTag):
self._banner = data.get('banner')
self._flags = data.get('flags', 0)
self._avatar_decoration_data = data.get('avatar_decoration_data')
self._display_name_style = data.get('display_name_style')
def _presence_update(self, raw: RawPresenceUpdateEvent, user: UserPayload) -> Optional[Tuple[User, User]]:
self.activities = raw.activities
@ -456,10 +461,12 @@ class Member(discord.abc.Messageable, _UserTag):
u._public_flags,
u._avatar_decoration_data['sku_id'] if u._avatar_decoration_data is not None else None,
u._primary_guild,
u._display_name_style,
)
decoration_payload = user.get('avatar_decoration_data')
primary_guild_payload = user.get('primary_guild', None)
display_name_style_payload = user.get('display_name_style', None)
# These keys seem to always be available
modified = (
user['username'],
@ -469,6 +476,7 @@ class Member(discord.abc.Messageable, _UserTag):
user.get('public_flags', 0),
decoration_payload['sku_id'] if decoration_payload is not None else None,
primary_guild_payload,
display_name_style_payload,
)
if original != modified:
to_return = User._copy(self._user)
@ -480,6 +488,7 @@ class Member(discord.abc.Messageable, _UserTag):
u._public_flags,
u._avatar_decoration_data,
u._primary_guild,
u._display_name_style,
) = (
user['username'],
user['discriminator'],
@ -488,6 +497,7 @@ class Member(discord.abc.Messageable, _UserTag):
user.get('public_flags', 0),
decoration_payload,
primary_guild_payload,
display_name_style_payload,
)
# Signal to dispatch on_user_update
return to_return, u
@ -659,6 +669,35 @@ class Member(discord.abc.Messageable, _UserTag):
return None
return Asset._from_guild_banner(self._state, self.guild.id, self.id, self._banner)
@property
def display_name_style(self) -> Optional[DisplayNameStyle]:
"""Optional[:class:`DisplayNameStyle`]: Returns the member's guild display name style if they have one,
otherwise their global display name style if they have one, otherwise ``None``.
.. versionadded:: 2.8
"""
return self.guild_display_name_style or self.global_display_name_style
@property
def guild_display_name_style(self) -> Optional[DisplayNameStyle]:
"""Optional[:class:`DisplayNameStyle`]: Returns the member's guild specific display name style.
if the member has no guild display name style set then ``None`` is returned.
.. versionadded:: 2.8
"""
if self._display_name_style is None:
return None
return DisplayNameStyle(data=self._display_name_style)
@property
def global_display_name_style(self) -> Optional[DisplayNameStyle]:
"""Optional[:class:`DisplayNameStyle`]: Returns the user's global display name style.
if the user has no global display name style set then ``None`` is returned.
.. versionadded:: 2.8
"""
return self._user.display_name_style
@property
def activity(self) -> Optional[ActivityTypes]:
"""Optional[Union[:class:`BaseActivity`, :class:`Spotify`]]: Returns the primary
@ -817,6 +856,9 @@ class Member(discord.abc.Messageable, _UserTag):
avatar: Optional[bytes] = MISSING,
banner: Optional[bytes] = MISSING,
bio: Optional[str] = MISSING,
display_name_font: Optional[DisplayNameFont] = MISSING,
display_name_effect: Optional[DisplayNameEffect] = MISSING,
display_name_colors: Optional[List[Union[Colour, int]]] = MISSING,
reason: Optional[str] = None,
) -> Optional[Member]:
"""|coro|
@ -902,7 +944,22 @@ class Member(discord.abc.Messageable, _UserTag):
This can only be set when editing the bot's own member.
.. versionadded:: 2.7
display_name_font: Optional[:class:`DisplayNameFont`]
The new display name font for the member. Use ``None`` to remove the display name font.
This can only be set when editing the bot's own member.
.. versionadded:: 2.8
display_name_effect: Optional[:class:`DisplayNameEffect`]
The new display name effect for the member. Use ``None`` to remove the display name effect.
This can only be set when editing the bot's own member.
.. versionadded:: 2.8
display_name_colors: Optional[List[Union[:class:`Colour`, :class:`int`]]]
A list of up to 2 colors that will be used for the member's display name
gradient. This can only be set when editing the bot's own member.
Use ``None`` to remove the display name colors.
.. versionadded:: 2.8
reason: Optional[:class:`str`]
The reason for editing this member. Shows up on the audit log.
@ -952,8 +1009,21 @@ class Member(discord.abc.Messageable, _UserTag):
if bio is not MISSING:
self_payload['bio'] = bio or ''
if display_name_font is not MISSING:
self_payload['display_name_font_id'] = display_name_font.value if display_name_font else None
if display_name_effect is not MISSING:
self_payload['display_name_effect_id'] = display_name_effect.value if display_name_effect else None
if display_name_colors is not MISSING:
self_payload['display_name_colors'] = [
c.value if isinstance(c, Colour) else c for c in display_name_colors or []
]
if not me and self_payload:
raise ValueError("Editing the bio, avatar or banner is only for the bot's own member.")
only_fields = {'avatar', 'banner', 'bio', 'display_name_font', 'display_name_effect', 'display_name_colors'}
current_fields = utils._human_join(list(only_fields.intersection(set(self_payload.keys()))), final='and')
raise ValueError(f"Editing {current_fields} can only happen when editing the bot's own member.")
if deafen is not MISSING:
payload['deaf'] = deafen

4
discord/types/member.py

@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE.
from typing import Optional, TypedDict
from .snowflake import SnowflakeList
from .user import User, AvatarDecorationData
from .user import User, AvatarDecorationData, DisplayNameStyle
from typing_extensions import NotRequired
@ -50,6 +50,7 @@ class Member(PartialMember, total=False):
communication_disabled_until: str
banner: NotRequired[Optional[str]]
avatar_decoration_data: NotRequired[AvatarDecorationData]
display_name_style: NotRequired[DisplayNameStyle]
class _OptionalMemberWithUser(PartialMember, total=False):
@ -60,6 +61,7 @@ class _OptionalMemberWithUser(PartialMember, total=False):
permissions: str
communication_disabled_until: str
avatar_decoration_data: NotRequired[AvatarDecorationData]
display_name_style: NotRequired[DisplayNameStyle]
class MemberWithUser(_OptionalMemberWithUser):

11
discord/types/user.py

@ -23,12 +23,14 @@ DEALINGS IN THE SOFTWARE.
"""
from .snowflake import Snowflake
from typing import Literal, Optional, TypedDict
from typing import Literal, Optional, TypedDict, List
from typing_extensions import NotRequired
PremiumType = Literal[0, 1, 2, 3]
NameplatePallete = Literal['crimson', 'berry', 'sky', 'teal', 'forest', 'bubble_gum', 'violet', 'cobalt', 'clover']
DisplayNameFont = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
DisplayNameEffect = Literal[1, 2, 3, 4, 5]
class _UserSKU(TypedDict):
@ -70,6 +72,12 @@ class PartialUser(TypedDict):
collectibles: NotRequired[UserCollectibles]
class DisplayNameStyle(TypedDict):
font_id: DisplayNameFont
effect_id: DisplayNameEffect
colors: List[int]
class User(PartialUser, total=False):
bot: bool
system: bool
@ -80,3 +88,4 @@ class User(PartialUser, total=False):
flags: int
premium_type: PremiumType
public_flags: int
display_name_styles: DisplayNameStyle

40
discord/user.py

@ -29,7 +29,7 @@ from typing import Any, Dict, List, Optional, TYPE_CHECKING, Union
import discord.abc
from .asset import Asset
from .colour import Colour
from .enums import DefaultAvatar
from .enums import DefaultAvatar, DisplayNameEffect, DisplayNameFont, try_enum
from .flags import PublicUserFlags
from .utils import snowflake_time, _bytes_to_base64_data, MISSING, _get_as_snowflake
from .primary_guild import PrimaryGuild
@ -51,15 +51,39 @@ if TYPE_CHECKING:
AvatarDecorationData,
PrimaryGuild as PrimaryGuildPayload,
UserCollectibles as UserCollectiblesPayload,
DisplayNameStyle as DisplayNameStylePayload,
)
__all__ = (
'User',
'ClientUser',
'DisplayNameStyle',
)
class DisplayNameStyle:
"""Represents a user's display name style.
Attributes
-----------
font: :class:`DisplayNameFont`
The font.
effect: :class:`DisplayNameEffect`
The applied effect.
colors: List[:class:`Colour`]
The colors used in the effect. Max of 2.
"""
def __init__(self, *, data: DisplayNameStylePayload) -> None:
self.font: DisplayNameFont = try_enum(DisplayNameFont, data['font_id'])
self.effect: DisplayNameEffect = try_enum(DisplayNameEffect, data['effect_id'])
self.colors: List[discord.Colour] = [discord.Colour(color) for color in data.get('colors', [])]
def __repr__(self) -> str:
return f'<DisplayNameStyle font={self.font} effect={self.effect} colors={self.colors}>'
class _UserTag:
__slots__ = ()
id: int
@ -81,6 +105,7 @@ class BaseUser(_UserTag):
'_avatar_decoration_data',
'_primary_guild',
'_collectibles',
'_display_name_style',
)
if TYPE_CHECKING:
@ -98,6 +123,7 @@ class BaseUser(_UserTag):
_avatar_decoration_data: Optional[AvatarDecorationData]
_primary_guild: Optional[PrimaryGuildPayload]
_collectibles: Optional[UserCollectiblesPayload]
_display_name_style: Optional[DisplayNameStylePayload]
def __init__(self, *, state: ConnectionState, data: Union[UserPayload, PartialUserPayload]) -> None:
self._state = state
@ -137,6 +163,7 @@ class BaseUser(_UserTag):
self._avatar_decoration_data = data.get('avatar_decoration_data')
self._primary_guild = data.get('primary_guild', None)
self._collectibles = data.get('collectibles', None)
self._display_name_style = data.get('display_name_styles', None) or None
@classmethod
def _copy(cls, user: Self) -> Self:
@ -155,6 +182,7 @@ class BaseUser(_UserTag):
self._avatar_decoration_data = user._avatar_decoration_data
self._primary_guild = user._primary_guild
self._collectibles = user._collectibles
self._display_name_style = user._display_name_style
return self
@ -340,6 +368,16 @@ class BaseUser(_UserTag):
return []
return [Collectible(state=self._state, type=key, data=value) for key, value in self._collectibles.items() if value] # type: ignore
@property
def display_name_style(self) -> Optional[DisplayNameStyle]:
"""Optional[:class:`DisplayNameStyle`]: Returns the user's display name style.
.. versionadded:: 2.8
"""
if self._display_name_style is None:
return None
return DisplayNameStyle(data=self._display_name_style)
def mentioned_in(self, message: Message) -> bool:
"""Checks if the user is mentioned in the specified message.

92
docs/api.rst

@ -4154,6 +4154,90 @@ of :class:`enum.Enum`.
The collectible nameplate palette is white.
.. class:: DisplayNameFont
Represents the available fonts for a user display name style.
.. versionadded:: 2.8
.. attribute:: default
The default font is used.
.. attribute:: bangers
The 'Bangers' font is used.
.. attribute:: bio_rhyme
The 'BioRhyme' font is used.
.. attribute:: cherry_bomb
The 'Cherry Bomb' font is used.
.. attribute:: chicle
The 'Chicle' font is used.
.. attribute:: compagnon
The 'Compagnon' font is used.
.. attribute:: museo_moderno
The 'Museo Moderno' font is used.
.. attribute:: neo_castel
The 'Neo Castel' font is used.
.. attribute:: pixelify
The 'Pixelify' font is used.
.. attribute:: ribes
The 'Ribes' font is used.
.. attribute:: sinistre
The 'Sinistre' font is used.
.. attribute:: zilla_slab
The 'Zilla Slab' font is used.
.. class:: DisplayNameEffect
Represents the available effects for a user display name style.
.. versionadded:: 2.8
.. attribute:: solid
The first color provided is used.
.. attribute:: gradient
There is a two colour gradient using both colors provided.
.. attribute:: neon
There is a neon glow around the name.
.. attribute:: toon
There is a subtle vertical gradient and stroke around the name.
.. attribute:: pop
A coloured dropshadow is shown.
.. attribute:: glow
An alternative for the gradient style is used.
.. _discord-api-audit-logs:
Audit Log Data
@ -5859,6 +5943,14 @@ Collectible
.. autoclass:: Collectible()
:members:
DisplayNameStyle
~~~~~~~~~~~~~~~~~
.. attributetable:: DisplayNameStyle
.. autoclass:: DisplayNameStyle()
:members:
CallMessage
~~~~~~~~~~~~~~~~~~~

Loading…
Cancel
Save