Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for role icons #1823

Merged
merged 16 commits into from
Nov 23, 2021
Merged
42 changes: 42 additions & 0 deletions src/main/java/net/dv8tion/jda/api/entities/Role.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public interface Role extends IMentionable, IPermissionHolder, Comparable<Role>
{
/** Used to keep consistency between color values used in the API */
int DEFAULT_COLOR_RAW = 0x1FFFFFFF; // java.awt.Color fills the MSB with FF, we just use 1F to provide better consistency
/** Template for {@link #getIconUrl()}. */
String ICON_URL = "https://cdn.discordapp.com/role-icons/%s/%s.png";

/**
* The hierarchical position of this {@link net.dv8tion.jda.api.entities.Role Role}
Expand Down Expand Up @@ -291,6 +293,46 @@ default RoleAction createCopy()
@Nonnull
RoleTags getTags();

/**
* The Discord hash-id of the {@link net.dv8tion.jda.api.entities.Role Role} icon image.
* If no icon has been set, this returns {@code null}.
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
* <p>The Role icon can be modified using {@link RoleManager#setIcon(Icon)}.
*
* @return Possibly-null String containing the Role's icon hash-id.
*
* @since 4.3.1
*/
@Nullable
String getIconId();

/**
* The URL of the {@link net.dv8tion.jda.api.entities.Role Role} icon image.
* If no icon has been set, this returns {@code null}.
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
* <p>The Role icon can be modified using {@link RoleManager#setIcon(Icon)} (Icon)}.
*
* @return Possibly-null String containing the Role's icon URL.
*
* @since 4.3.1
*/
@Nullable
default String getIconUrl()
{
String iconId = getIconId();
return iconId == null ? null : String.format(ICON_URL, getId(), iconId);
}

/**
* The Unicode Emoji of this {@link net.dv8tion.jda.api.entities.Role Role} that is used instead of a custom image.
* If no emoji has been set, this returns {@code null}.
* <p>The Role emoji can be modified using {@link RoleManager#setEmoji(String)}.
*
* @return Possibly-null String containing the Role's Unicode Emoji.
*
* @since 4.3.1
*/
@Nullable
String getEmoji();

/**
* Tags associated with this role.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.dv8tion.jda.api.events.role.update;

import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Role;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
* Indicates that the Unicode Emoji of a {@link net.dv8tion.jda.api.entities.Role Role} changed.
*
* <p>Can be used to detect when a role emoji changes and retrieve the old one
*
* <p>Identifier: {@code emoji}
*/
public class RoleUpdateEmojiEvent extends GenericRoleUpdateEvent<String>
{
public static final String IDENTIFIER = "emoji";

public RoleUpdateEmojiEvent(@Nonnull JDA api, long responseNumber, @Nonnull Role role, @Nullable String oldEmoji)
{
super(api, responseNumber, role, oldEmoji, role.getEmoji(), IDENTIFIER);
}

/**
* The old emoji
*
* @return The old emoji, or null
*/
@Nullable
public String getOldEmoji()
{
return getOldValue();
}

/**
* The old emoji
*
* @return The new emoji, or null
*/
@Nullable
public String getNewEmoji()
{
return getNewValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.dv8tion.jda.api.events.role.update;

import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Role;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
* Indicates that the Icon of a {@link net.dv8tion.jda.api.entities.Role Role} changed.
*
* <p>Can be used to detect when a role icon changes and retrieve the old one
*
* <p>Identifier: {@code icon}
*/
public class RoleUpdateIconEvent extends GenericRoleUpdateEvent<String>
{
public static final String IDENTIFIER = "icon";

public RoleUpdateIconEvent(@Nonnull JDA api, long responseNumber, @Nonnull Role role, @Nullable String oldIconId)
{
super(api, responseNumber, role, oldIconId, role.getIconId(), IDENTIFIER);
}

/**
* The old icon id
*
* @return The old icon id, or null
*/
@Nullable
public String getOldIconId()
{
return getOldValue();
}

/**
* The url of the old icon
*
* @return The url of the old icon, or null
*/
@Nullable
public String getOldIconUrl()
{
return previous == null ? null : String.format(Role.ICON_URL, role.getId(), previous);
}

/**
* The new icon id
*
* @return The new icon id, or null
*/
@Nullable
public String getNewIconId()
{
return getNewValue();
}

/**
* The url of the new icon
*
* @return The url of the new icon, or null
*/
@Nullable
public String getNewIconUrl()
{
return next == null ? null : String.format(Role.ICON_URL, role.getId(), next);
}
}
35 changes: 35 additions & 0 deletions src/main/java/net/dv8tion/jda/api/managers/RoleManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Icon;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.internal.utils.Checks;

Expand Down Expand Up @@ -56,6 +57,10 @@ public interface RoleManager extends Manager<RoleManager>
long HOIST = 0x8;
/** Used to reset the mentionable field */
long MENTIONABLE = 0x10;
/** Used to reset the icon field */
long ICON = 0x20;
/** Used to reset the unicode_emoji field */
long EMOJI = 0x40;

/**
* Resets the fields specified by the provided bit-flag pattern.
Expand All @@ -69,6 +74,8 @@ public interface RoleManager extends Manager<RoleManager>
* <li>{@link #PERMISSION}</li>
* <li>{@link #HOIST}</li>
* <li>{@link #MENTIONABLE}</li>
* <li>{@link #ICON}</li>
* <li>{@link #EMOJI}</li>
* </ul>
*
* @param fields
Expand All @@ -92,6 +99,8 @@ public interface RoleManager extends Manager<RoleManager>
* <li>{@link #PERMISSION}</li>
* <li>{@link #HOIST}</li>
* <li>{@link #MENTIONABLE}</li>
* <li>{@link #ICON}</li>
* <li>{@link #EMOJI}</li>
* </ul>
*
* @param fields
Expand Down Expand Up @@ -273,6 +282,32 @@ default RoleManager setColor(@Nullable Color color)
@CheckReturnValue
RoleManager setMentionable(boolean mentionable);

/**
* Sets the {@link net.dv8tion.jda.api.entities.Icon Icon} of this {@link net.dv8tion.jda.api.entities.Role Role}.
*
* @param icon
* The new icon for this {@link net.dv8tion.jda.api.entities.Role Role}
* or {@code null} to reset
*
* @return RoleManager for chaining convenience
*/
@Nonnull
@CheckReturnValue
RoleManager setIcon(@Nullable Icon icon);

/**
* Sets the Unicode Emoji of this {@link net.dv8tion.jda.api.entities.Role Role}.
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
*
* @param emoji
* The Unicode Emoji for this {@link net.dv8tion.jda.api.entities.Role Role}
* or {@code null} to reset
*
* @return RoleManager for chaining convenience
*/
@Nonnull
@CheckReturnValue
RoleManager setEmoji(@Nullable String emoji);

/**
* Adds the specified {@link net.dv8tion.jda.api.Permission Permissions} to the selected {@link net.dv8tion.jda.api.entities.Role Role}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Icon;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.internal.utils.Checks;

Expand Down Expand Up @@ -208,4 +209,32 @@ default RoleAction setPermissions(@Nullable Collection<Permission> permissions)
@Nonnull
@CheckReturnValue
RoleAction setPermissions(@Nullable Long permissions);

/**
* Sets the {@link net.dv8tion.jda.api.entities.Icon Icon} of this {@link net.dv8tion.jda.api.entities.Role Role}.
* This icon will be displayed next to the role's name in the members tab and in chat.
*
* @param icon
* The new icon for this {@link net.dv8tion.jda.api.entities.Role Role}
* or {@code null} to reset
*
* @return RoleManager for chaining convenience
*/
@Nonnull
@CheckReturnValue
RoleAction setIcon(@Nullable Icon icon);

/**
* Sets the Unicode Emoji of this {@link net.dv8tion.jda.api.entities.Role Role} instead of a custom image.
* This emoji will be displayed next to the role's name in the members tab and in chat.
*
* @param emoji
* The Unicode Emoji for this {@link net.dv8tion.jda.api.entities.Role Role}
* or {@code null} to reset
*
* @return RoleManager for chaining convenience
*/
@Nonnull
@CheckReturnValue
RoleAction setEmoji(@Nullable String emoji);
}
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,9 @@ public Role createRole(GuildImpl guild, DataObject roleJson, long guildId)
.setHoisted(roleJson.getBoolean("hoist"))
.setColor(color == 0 ? Role.DEFAULT_COLOR_RAW : color)
.setMentionable(roleJson.getBoolean("mentionable"))
.setTags(roleJson.optObject("tags").orElseGet(DataObject::empty));
.setTags(roleJson.optObject("tags").orElseGet(DataObject::empty))
.setIconId(roleJson.getString("icon", null))
.setEmoji(roleJson.getString("unicode_emoji", null));
if (playbackCache)
getJDA().getEventCache().playbackCache(EventCache.Type.ROLE, id);
return role;
Expand Down
32 changes: 31 additions & 1 deletion src/main/java/net/dv8tion/jda/internal/entities/RoleImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import net.dv8tion.jda.internal.utils.cache.SortedSnowflakeCacheViewImpl;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.awt.*;
import java.time.OffsetDateTime;
import java.util.Collection;
Expand All @@ -61,6 +62,8 @@ public class RoleImpl implements Role
private long rawPermissions;
private int color;
private int rawPosition;
private String iconId;
private String emoji;

public RoleImpl(long id, Guild guild)
{
Expand Down Expand Up @@ -288,7 +291,8 @@ public RoleAction createCopy(@Nonnull Guild guild)
.setHoisted(hoisted)
.setMentionable(mentionable)
.setName(name)
.setPermissions(rawPermissions);
.setPermissions(rawPermissions)
.setEmoji(emoji); // the icon is not cloneable, we don't have access to it
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
}

@Nonnull
Expand Down Expand Up @@ -330,6 +334,20 @@ public RoleTags getTags()
return tags == null ? RoleTagsImpl.EMPTY : tags;
}

@Nullable
@Override
public String getIconId()
{
return iconId;
}

@Nullable
@Override
public String getEmoji()
{
return emoji;
}

@Nonnull
@Override
public String getAsMention()
Expand Down Expand Up @@ -444,6 +462,18 @@ public RoleImpl setTags(DataObject tags)
return this;
}

public RoleImpl setIconId(String iconId)
{
this.iconId = iconId;
return this;
}

public RoleImpl setEmoji(String emoji)
{
this.emoji = emoji;
return this;
}

public static class RoleTagsImpl implements RoleTags
{
public static final RoleTags EMPTY = new RoleTagsImpl();
Expand Down
Loading