Skip to content

Commit 4aba1f4

Browse files
Snipy7374shiftinv
andauthored
feat: implement new role color styles (#1312)
Signed-off-by: Snipy7374 <[email protected]> Co-authored-by: vi <[email protected]>
1 parent fa605cf commit 4aba1f4

File tree

6 files changed

+213
-19
lines changed

6 files changed

+213
-19
lines changed

changelog/1311.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add :meth:`Role.primary_colour`, :meth:`Role.secondary_colour`, :meth:`Role.tertiary_colour`, :meth:`Colour.holographic_style`, and aliases, as well as ``primary_colour``, ``secondary_colour``, ``tertiary_colour`` arguments, and aliases, to :meth:`Role.edit` and :meth:`Guild.create_role`.

disnake/colour.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,5 +319,18 @@ def dark_embed(cls) -> Self:
319319
"""
320320
return cls(0x2B2D31)
321321

322+
@classmethod
323+
def holographic_style(cls) -> Tuple[Self, Self, Self]:
324+
"""A factory method that returns a tuple of :class:`Colour` with values of
325+
``0xA9C9FF``, ``0xFFBBEC``, ``0xFFC3A0``. This matches the holographic colour style
326+
for roles.
327+
328+
The first value represents the ``colour`` (``primary_color``), the second and the third
329+
represents the ``secondary_colour`` and ``tertiary_colour`` respectively.
330+
331+
.. versionadded:: 2.11
332+
"""
333+
return cls(0xA9C9FF), cls(0xFFBBEC), cls(0xFFC3A0)
334+
322335

323336
Color = Colour

disnake/guild.py

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3751,6 +3751,12 @@ async def create_role(
37513751
permissions: Permissions = MISSING,
37523752
color: Union[Colour, int] = MISSING,
37533753
colour: Union[Colour, int] = MISSING,
3754+
primary_colour: Union[Colour, int] = MISSING,
3755+
primary_color: Union[Colour, int] = MISSING,
3756+
secondary_colour: Optional[Union[Colour, int]] = None,
3757+
secondary_color: Optional[Union[Colour, int]] = None,
3758+
tertiary_colour: Optional[Union[Colour, int]] = None,
3759+
tertiary_color: Optional[Union[Colour, int]] = None,
37543760
hoist: bool = MISSING,
37553761
icon: AssetBytes = MISSING,
37563762
emoji: str = MISSING,
@@ -3781,6 +3787,28 @@ async def create_role(
37813787
colour: Union[:class:`Colour`, :class:`int`]
37823788
The colour for the role. Defaults to :meth:`Colour.default`.
37833789
This is aliased to ``color`` as well.
3790+
3791+
.. note::
3792+
This is equivalent to ``primary_colour``.
3793+
primary_colour: Union[:class:`Colour`, :class:`int`]
3794+
The primary_colour for the role. Defaults to :meth:`Colour.default`.
3795+
This is aliased to ``primary_color`` as well.
3796+
3797+
.. versionadded:: 2.11
3798+
secondary_colour: Optional[Union[:class:`Colour`, :class:`int`]]
3799+
The secondary_colour for the role. Defaults to ``None``.
3800+
This is aliased to ``secondary_color`` as well.
3801+
3802+
.. versionadded:: 2.11
3803+
tertiary_colour: Optional[Union[:class:`Colour`, :class:`int`]]
3804+
The tertiary_colour for the role. Defaults to ``None``.
3805+
This is aliased to ``tertiary_color`` as well.
3806+
3807+
.. note::
3808+
When passing this the only permitted values are the ones returned by
3809+
:meth:`Colour.holographic_style`, any other color value will get rejected.
3810+
3811+
.. versionadded:: 2.11
37843812
hoist: :class:`bool`
37853813
Whether the role should be shown separately in the member list.
37863814
Defaults to ``False``.
@@ -3821,11 +3849,25 @@ async def create_role(
38213849
else:
38223850
fields["permissions"] = "0"
38233851

3824-
actual_colour = colour or color or Colour.default()
3825-
if isinstance(actual_colour, int):
3826-
fields["color"] = actual_colour
3827-
else:
3828-
fields["color"] = actual_colour.value
3852+
actual_primary_color = colour or color or primary_colour or primary_color
3853+
actual_secondary_color = secondary_colour or secondary_color
3854+
actual_tertiary_color = tertiary_colour or tertiary_color
3855+
if actual_primary_color is MISSING:
3856+
actual_primary_color = 0
3857+
elif isinstance(actual_primary_color, Colour):
3858+
actual_primary_color = actual_primary_color.value
3859+
3860+
if isinstance(actual_secondary_color, Colour):
3861+
actual_secondary_color = actual_secondary_color.value
3862+
3863+
if isinstance(actual_tertiary_color, Colour):
3864+
actual_tertiary_color = actual_tertiary_color.value
3865+
3866+
fields["colors"] = {
3867+
"primary_color": actual_primary_color,
3868+
"secondary_color": actual_secondary_color,
3869+
"tertiary_color": actual_tertiary_color,
3870+
}
38293871

38303872
if hoist is not MISSING:
38313873
fields["hoist"] = hoist
@@ -5454,9 +5496,9 @@ def add_role(
54545496

54555497
actual_colour = colour or color or Colour.default()
54565498
if isinstance(actual_colour, int):
5457-
data["color"] = actual_colour
5499+
data["color"] = actual_colour # type: ignore
54585500
else:
5459-
data["color"] = actual_colour.value
5501+
data["color"] = actual_colour.value # type: ignore
54605502

54615503
if hoist is not MISSING:
54625504
data["hoist"] = hoist

disnake/http.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,6 +1977,7 @@ def edit_role(
19771977
"name",
19781978
"permissions",
19791979
"color",
1980+
"colors",
19801981
"hoist",
19811982
"mentionable",
19821983
"icon",

disnake/role.py

Lines changed: 141 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ class Role(Hashable):
208208
"id",
209209
"name",
210210
"_permissions",
211-
"_colour",
212211
"position",
213212
"managed",
214213
"mentionable",
@@ -219,6 +218,9 @@ class Role(Hashable):
219218
"tags",
220219
"_flags",
221220
"_state",
221+
"_primary_color",
222+
"_secondary_color",
223+
"_tertiary_color",
222224
)
223225

224226
def __init__(self, *, guild: Guild, state: ConnectionState, data: RolePayload) -> None:
@@ -273,7 +275,10 @@ def _update(self, data: RolePayload) -> None:
273275
self.name: str = data["name"]
274276
self._permissions: int = int(data.get("permissions", 0))
275277
self.position: int = data.get("position", 0)
276-
self._colour: int = data.get("color", 0)
278+
colors = data["colors"]
279+
self._primary_color: int = colors["primary_color"]
280+
self._secondary_color: Optional[int] = colors["secondary_color"]
281+
self._tertiary_color: Optional[int] = colors["tertiary_color"]
277282
self.hoist: bool = data.get("hoist", False)
278283
self._icon: Optional[str] = data.get("icon")
279284
self._emoji: Optional[str] = data.get("unicode_emoji")
@@ -370,13 +375,75 @@ def permissions(self) -> Permissions:
370375

371376
@property
372377
def colour(self) -> Colour:
373-
""":class:`Colour`: Returns the role colour. An alias exists under ``color``."""
374-
return Colour(self._colour)
378+
""":class:`Colour`: Returns the role colour. An alias exists under ``color``.
379+
380+
.. note::
381+
382+
This is equivalent to :meth:`primary_colour`.
383+
"""
384+
return self.primary_colour
375385

376386
@property
377387
def color(self) -> Colour:
378-
""":class:`Colour`: Returns the role color. An alias exists under ``colour``."""
379-
return self.colour
388+
""":class:`Colour`: Returns the role color. An alias exists under ``colour``.
389+
390+
.. note::
391+
392+
This is equivalent to :meth:`primary_color`.
393+
"""
394+
return self.primary_colour
395+
396+
@property
397+
def primary_colour(self) -> Colour:
398+
""":class:`Colour`: Returns the primary colour for the role. An alias exists under ``primary_color``.
399+
400+
.. versionadded:: 2.11
401+
"""
402+
return Colour(self._primary_color)
403+
404+
@property
405+
def primary_color(self) -> Colour:
406+
""":class:`Colour`: Returns the primary color for the role. An alias exists under ``primary_colour``.
407+
408+
.. versionadded:: 2.11
409+
"""
410+
return self.primary_colour
411+
412+
@property
413+
def secondary_colour(self) -> Optional[Colour]:
414+
"""Optional[:class:`Colour`]: Returns the secondary colour for the role, if any. An alias exists under ``secondary_color``.
415+
416+
.. versionadded:: 2.11
417+
"""
418+
if self._secondary_color:
419+
return Colour(self._secondary_color)
420+
return None
421+
422+
@property
423+
def secondary_color(self) -> Optional[Colour]:
424+
"""Optional[:class:`Colour`]: Returns the secondary color for the role, if any. An alias exists under ``secondary_colour``.
425+
426+
.. versionadded:: 2.11
427+
"""
428+
return self.secondary_colour
429+
430+
@property
431+
def tertiary_colour(self) -> Optional[Colour]:
432+
"""Optional[:class:`Colour`]: Returns the tertiary colour for the role, if any. An alias exists under ``tertiary_color``.
433+
434+
.. versionadded:: 2.11
435+
"""
436+
if self._tertiary_color:
437+
return Colour(self._tertiary_color)
438+
return None
439+
440+
@property
441+
def tertiary_color(self) -> Optional[Colour]:
442+
"""Optional[:class:`Colour`]: Returns the tertiary color for the role, if any. An alias exists under ``tertiary_colour``.
443+
444+
.. versionadded:: 2.11
445+
"""
446+
return self.tertiary_colour
380447

381448
@property
382449
def icon(self) -> Optional[Asset]:
@@ -462,6 +529,12 @@ async def edit(
462529
permissions: Permissions = MISSING,
463530
colour: Union[Colour, int] = MISSING,
464531
color: Union[Colour, int] = MISSING,
532+
primary_colour: Union[Colour, int] = MISSING,
533+
primary_color: Union[Colour, int] = MISSING,
534+
secondary_colour: Optional[Union[Colour, int]] = MISSING,
535+
secondary_color: Optional[Union[Colour, int]] = MISSING,
536+
tertiary_colour: Optional[Union[Colour, int]] = MISSING,
537+
tertiary_color: Optional[Union[Colour, int]] = MISSING,
465538
hoist: bool = MISSING,
466539
icon: Optional[AssetBytes] = MISSING,
467540
emoji: Optional[str] = MISSING,
@@ -495,6 +568,25 @@ async def edit(
495568
The new permissions to change to.
496569
colour: Union[:class:`Colour`, :class:`int`]
497570
The new colour to change to. (aliased to ``color`` as well)
571+
572+
.. note::
573+
This is equivalent to ``primary_colour``.
574+
primary_colour: Union[:class:`Colour`, :class:`int`]
575+
The new primary_colour to change to. (aliased to ``primary_color`` as well)
576+
577+
.. versionadded:: 2.11
578+
secondary_colour: Optional[Union[:class:`Colour`, :class:`int`]]
579+
The new secondary_colour to change to. (aliased to ``secondary_color`` as well)
580+
581+
.. versionadded:: 2.11
582+
tertiary_colour: Optional[Union[:class:`Colour`, :class:`int`]]
583+
The new tertiary_colour to change to. (aliased to ``tertiary_color`` as well)
584+
585+
.. note::
586+
When passing this the only permitted values are the ones returned by
587+
:meth:`Colour.holographic_style`, any other color value will get rejected.
588+
589+
.. versionadded:: 2.11
498590
hoist: :class:`bool`
499591
Indicates if the role should be shown separately in the member list.
500592
icon: Optional[|resource_type|]
@@ -536,14 +628,52 @@ async def edit(
536628
await self._move(position, reason=reason)
537629

538630
payload: Dict[str, Any] = {}
631+
632+
colors: Dict[str, Any] = {
633+
"primary_color": self._primary_color,
634+
"secondary_color": self._secondary_color,
635+
"tertiary_color": self._tertiary_color,
636+
}
539637
if color is not MISSING:
540-
colour = color
638+
primary_colour = color
639+
elif colour is not MISSING:
640+
primary_colour = colour
641+
642+
if primary_color is not MISSING:
643+
primary_colour = primary_color
644+
645+
if primary_colour is not MISSING:
646+
if isinstance(primary_colour, int):
647+
colors["primary_color"] = primary_colour
648+
else:
649+
colors["primary_color"] = primary_colour.value
650+
651+
if secondary_color is not MISSING:
652+
secondary_colour = secondary_color
653+
654+
if secondary_colour is not MISSING:
655+
if isinstance(secondary_colour, Colour):
656+
colors["secondary_color"] = secondary_colour.value
657+
else:
658+
colors["secondary_color"] = secondary_colour
659+
660+
if tertiary_color is not MISSING:
661+
tertiary_colour = tertiary_color
541662

542-
if colour is not MISSING:
543-
if isinstance(colour, int):
544-
payload["color"] = colour
663+
if tertiary_colour is not MISSING:
664+
if isinstance(tertiary_colour, Colour):
665+
colors["tertiary_color"] = tertiary_colour.value
545666
else:
546-
payload["color"] = colour.value
667+
colors["tertiary_color"] = tertiary_colour
668+
669+
if any(
670+
[
671+
colors["primary_color"] != self._primary_color,
672+
colors["secondary_color"] != self._secondary_color,
673+
colors["tertiary_color"] != self._tertiary_color,
674+
]
675+
):
676+
payload["colors"] = colors
547677

548678
if name is not MISSING:
549679
payload["name"] = name

disnake/types/role.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Role(TypedDict):
1313
id: Snowflake
1414
name: str
1515
color: int
16+
colors: RoleColors
1617
hoist: bool
1718
icon: NotRequired[Optional[str]]
1819
unicode_emoji: NotRequired[Optional[str]]
@@ -33,10 +34,16 @@ class RoleTags(TypedDict, total=False):
3334
available_for_purchase: None
3435

3536

37+
class RoleColors(TypedDict):
38+
primary_color: int
39+
secondary_color: Optional[int]
40+
tertiary_color: Optional[int]
41+
42+
3643
class CreateRole(TypedDict, total=False):
3744
name: str
3845
permissions: str
39-
color: int
46+
colors: RoleColors
4047
hoist: bool
4148
icon: Optional[str]
4249
unicode_emoji: Optional[str]

0 commit comments

Comments
 (0)