Skip to content

Commit cb73009

Browse files
makerzedolfiesDA-344Rapptz
authored
Add role parameters to support new gradient and holographic roles
Co-authored-by: dolfies <[email protected]> Co-authored-by: DA344 <[email protected]> Co-authored-by: Danny <[email protected]>
1 parent 2502a78 commit cb73009

File tree

5 files changed

+132
-8
lines changed

5 files changed

+132
-8
lines changed

discord/guild.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3648,6 +3648,8 @@ async def create_role(
36483648
hoist: bool = ...,
36493649
display_icon: Union[bytes, str] = MISSING,
36503650
mentionable: bool = ...,
3651+
secondary_colour: Optional[Union[Colour, int]] = ...,
3652+
tertiary_colour: Optional[Union[Colour, int]] = ...,
36513653
) -> Role:
36523654
...
36533655

@@ -3662,6 +3664,8 @@ async def create_role(
36623664
hoist: bool = ...,
36633665
display_icon: Union[bytes, str] = MISSING,
36643666
mentionable: bool = ...,
3667+
secondary_color: Optional[Union[Colour, int]] = ...,
3668+
tertiary_color: Optional[Union[Colour, int]] = ...,
36653669
) -> Role:
36663670
...
36673671

@@ -3676,6 +3680,10 @@ async def create_role(
36763680
display_icon: Union[bytes, str] = MISSING,
36773681
mentionable: bool = MISSING,
36783682
reason: Optional[str] = None,
3683+
secondary_color: Optional[Union[Colour, int]] = MISSING,
3684+
tertiary_color: Optional[Union[Colour, int]] = MISSING,
3685+
secondary_colour: Optional[Union[Colour, int]] = MISSING,
3686+
tertiary_colour: Optional[Union[Colour, int]] = MISSING,
36793687
) -> Role:
36803688
"""|coro|
36813689
@@ -3695,6 +3703,10 @@ async def create_role(
36953703
This function will now raise :exc:`TypeError` instead of
36963704
``InvalidArgument``.
36973705
3706+
.. versionchanged:: 2.6
3707+
The ``colour`` and ``color`` parameters now set the role's primary color.
3708+
3709+
36983710
Parameters
36993711
-----------
37003712
name: :class:`str`
@@ -3704,6 +3716,15 @@ async def create_role(
37043716
colour: Union[:class:`Colour`, :class:`int`]
37053717
The colour for the role. Defaults to :meth:`Colour.default`.
37063718
This is aliased to ``color`` as well.
3719+
secondary_colour: Optional[Union[:class:`Colour`, :class:`int`]]
3720+
The secondary colour for the role.
3721+
3722+
.. versionadded:: 2.6
3723+
tertiary_colour: Optional[Union[:class:`Colour`, :class:`int`]]
3724+
The tertiary colour for the role. Can only be used for the holographic role preset,
3725+
which is ``(11127295, 16759788, 16761760)``
3726+
3727+
.. versionadded:: 2.6
37073728
hoist: :class:`bool`
37083729
Indicates if the role should be shown separately in the member list.
37093730
Defaults to ``False``.
@@ -3738,11 +3759,34 @@ async def create_role(
37383759
else:
37393760
fields['permissions'] = '0'
37403761

3762+
colours: Dict[str, Any] = {}
3763+
37413764
actual_colour = colour or color or Colour.default()
37423765
if isinstance(actual_colour, int):
3743-
fields['color'] = actual_colour
3766+
colours['primary_color'] = actual_colour
37443767
else:
3745-
fields['color'] = actual_colour.value
3768+
colours['primary_color'] = actual_colour.value
3769+
3770+
actual_secondary_colour = secondary_colour or secondary_color
3771+
actual_tertiary_colour = tertiary_colour or tertiary_color
3772+
3773+
if actual_secondary_colour is not MISSING:
3774+
if actual_secondary_colour is None:
3775+
colours['secondary_color'] = None
3776+
elif isinstance(actual_secondary_colour, int):
3777+
colours['secondary_color'] = actual_secondary_colour
3778+
else:
3779+
colours['secondary_color'] = actual_secondary_colour.value
3780+
3781+
if actual_tertiary_colour is not MISSING:
3782+
if actual_tertiary_colour is None:
3783+
colours['tertiary_color'] = None
3784+
elif isinstance(actual_tertiary_colour, int):
3785+
colours['tertiary_color'] = actual_tertiary_colour
3786+
else:
3787+
colours['tertiary_color'] = actual_tertiary_colour.value
3788+
3789+
fields['colors'] = colours
37463790

37473791
if hoist is not MISSING:
37483792
fields['hoist'] = hoist

discord/http.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1897,7 +1897,7 @@ def edit_role(
18971897
self, guild_id: Snowflake, role_id: Snowflake, *, reason: Optional[str] = None, **fields: Any
18981898
) -> Response[role.Role]:
18991899
r = Route('PATCH', '/guilds/{guild_id}/roles/{role_id}', guild_id=guild_id, role_id=role_id)
1900-
valid_keys = ('name', 'permissions', 'color', 'hoist', 'icon', 'unicode_emoji', 'mentionable')
1900+
valid_keys = ('name', 'permissions', 'color', 'hoist', 'icon', 'unicode_emoji', 'mentionable', 'colors')
19011901
payload = {k: v for k, v in fields.items() if k in valid_keys}
19021902
return self.request(r, json=payload, reason=reason)
19031903

discord/role.py

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ class Role(Hashable):
222222
'tags',
223223
'_flags',
224224
'_state',
225+
'_secondary_colour',
226+
'_tertiary_colour',
225227
)
226228

227229
def __init__(self, *, guild: Guild, state: ConnectionState, data: RolePayload):
@@ -273,17 +275,20 @@ def __ge__(self, other: object) -> bool:
273275
return not r
274276

275277
def _update(self, data: RolePayload):
278+
colors = data.get('colors', {})
276279
self.name: str = data['name']
277280
self._permissions: int = int(data.get('permissions', 0))
278281
self.position: int = data.get('position', 0)
279-
self._colour: int = data.get('color', 0)
282+
self._colour: int = colors.get('primary_color', 0)
280283
self.hoist: bool = data.get('hoist', False)
281284
self._icon: Optional[str] = data.get('icon')
282285
self.unicode_emoji: Optional[str] = data.get('unicode_emoji')
283286
self.managed: bool = data.get('managed', False)
284287
self.mentionable: bool = data.get('mentionable', False)
285288
self.tags: Optional[RoleTags]
286289
self._flags: int = data.get('flags', 0)
290+
self._secondary_colour = colors.get('secondary_color', None)
291+
self._tertiary_colour = colors.get('tertiary_color', None)
287292

288293
try:
289294
self.tags = RoleTags(data['tags']) # pyright: ignore[reportTypedDictNotRequiredAccess]
@@ -323,19 +328,47 @@ def is_assignable(self) -> bool:
323328
me = self.guild.me
324329
return not self.is_default() and not self.managed and (me.top_role > self or me.id == self.guild.owner_id)
325330

331+
@property
332+
def secondary_colour(self) -> Optional[Colour]:
333+
"""Optional[:class:`Colour`]: The role's secondary colour.
334+
.. versionadded:: 2.6
335+
"""
336+
return Colour(self._secondary_colour) if self._secondary_colour is not None else None
337+
338+
@property
339+
def secondary_color(self) -> Optional[Colour]:
340+
"""Optional[:class:`Colour`]: Alias for :attr:`secondary_colour`.
341+
.. versionadded:: 2.6
342+
"""
343+
return self.secondary_colour
344+
345+
@property
346+
def tertiary_colour(self) -> Optional[Colour]:
347+
"""Optional[:class:`Colour`]: The role's tertiary colour.
348+
.. versionadded:: 2.6
349+
"""
350+
return Colour(self._tertiary_colour) if self._tertiary_colour is not None else None
351+
352+
@property
353+
def tertiary_color(self) -> Optional[Colour]:
354+
"""Optional[:class:`Colour`]: Alias for :attr:`tertiary_colour`.
355+
.. versionadded:: 2.6
356+
"""
357+
return self.tertiary_colour
358+
326359
@property
327360
def permissions(self) -> Permissions:
328361
""":class:`Permissions`: Returns the role's permissions."""
329362
return Permissions(self._permissions)
330363

331364
@property
332365
def colour(self) -> Colour:
333-
""":class:`Colour`: Returns the role colour. An alias exists under ``color``."""
366+
""":class:`Colour`: Returns the role's primary colour. An alias exists under ``color``."""
334367
return Colour(self._colour)
335368

336369
@property
337370
def color(self) -> Colour:
338-
""":class:`Colour`: Returns the role color. An alias exists under ``colour``."""
371+
""":class:`Colour`: Returns the role's primary colour. An alias exists under ``colour``."""
339372
return self.colour
340373

341374
@property
@@ -425,6 +458,10 @@ async def edit(
425458
mentionable: bool = MISSING,
426459
position: int = MISSING,
427460
reason: Optional[str] = MISSING,
461+
secondary_color: Optional[Union[Colour, int]] = MISSING,
462+
tertiary_color: Optional[Union[Colour, int]] = MISSING,
463+
secondary_colour: Optional[Union[Colour, int]] = MISSING,
464+
tertiary_colour: Optional[Union[Colour, int]] = MISSING,
428465
) -> Optional[Role]:
429466
"""|coro|
430467
@@ -447,6 +484,9 @@ async def edit(
447484
This function will now raise :exc:`ValueError` instead of
448485
``InvalidArgument``.
449486
487+
.. versionchanged:: 2.6
488+
The ``colour`` and ``color`` parameters now set the role's primary color.
489+
450490
Parameters
451491
-----------
452492
name: :class:`str`
@@ -455,6 +495,15 @@ async def edit(
455495
The new permissions to change to.
456496
colour: Union[:class:`Colour`, :class:`int`]
457497
The new colour to change to. (aliased to color as well)
498+
secondary_colour: Optional[Union[:class:`Colour`, :class:`int`]]
499+
The new secondary colour for the role.
500+
501+
.. versionadded:: 2.6
502+
tertiary_colour: Optional[Union[:class:`Colour`, :class:`int`]]
503+
The new tertiary colour for the role. Can only be used for the holographic role preset,
504+
which is ``(11127295, 16759788, 16761760)``
505+
506+
.. versionadded:: 2.6
458507
hoist: :class:`bool`
459508
Indicates if the role should be shown separately in the member list.
460509
display_icon: Optional[Union[:class:`bytes`, :class:`str`]]
@@ -490,14 +539,17 @@ async def edit(
490539
await self._move(position, reason=reason)
491540

492541
payload: Dict[str, Any] = {}
542+
543+
colours: Dict[str, Any] = {}
544+
493545
if color is not MISSING:
494546
colour = color
495547

496548
if colour is not MISSING:
497549
if isinstance(colour, int):
498-
payload['color'] = colour
550+
colours['primary_color'] = colour
499551
else:
500-
payload['color'] = colour.value
552+
colours['primary_color'] = colour.value
501553

502554
if name is not MISSING:
503555
payload['name'] = name
@@ -519,6 +571,26 @@ async def edit(
519571
if mentionable is not MISSING:
520572
payload['mentionable'] = mentionable
521573

574+
actual_secondary_colour = secondary_colour or secondary_color
575+
actual_tertiary_colour = tertiary_colour or tertiary_color
576+
577+
if actual_secondary_colour is not MISSING:
578+
if actual_secondary_colour is None:
579+
colours['secondary_color'] = None
580+
elif isinstance(actual_secondary_colour, int):
581+
colours['secondary_color'] = actual_secondary_colour
582+
else:
583+
colours['secondary_color'] = actual_secondary_colour.value
584+
if actual_tertiary_colour is not MISSING:
585+
if actual_tertiary_colour is None:
586+
colours['tertiary_color'] = None
587+
elif isinstance(actual_tertiary_colour, int):
588+
colours['tertiary_color'] = actual_tertiary_colour
589+
else:
590+
colours['tertiary_color'] = actual_tertiary_colour.value
591+
592+
if colours:
593+
payload['colors'] = colours
522594
data = await self._state.http.edit_role(self.guild.id, self.id, reason=reason, **payload)
523595
return Role(guild=self.guild, data=data, state=self._state)
524596

discord/types/guild.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class IncidentData(TypedDict):
9090
'VERIFIED',
9191
'VIP_REGIONS',
9292
'WELCOME_SCREEN_ENABLED',
93+
'ENHANCED_ROLE_COLORS',
9394
'RAID_ALERTS_DISABLED',
9495
'SOUNDBOARD',
9596
'MORE_SOUNDBOARD',

discord/types/role.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,17 @@
3030
from .snowflake import Snowflake
3131

3232

33+
class RoleColours(TypedDict):
34+
primary_color: int
35+
secondary_color: Optional[int]
36+
tertiary_color: Optional[int]
37+
38+
3339
class Role(TypedDict):
3440
id: Snowflake
3541
name: str
3642
color: int
43+
colors: RoleColours
3744
hoist: bool
3845
position: int
3946
permissions: str

0 commit comments

Comments
 (0)