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
30 changes: 30 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,34 @@ 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);
}

/**
* Tags associated with this role.
*
Expand Down
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 old icon id
*
* @return The old 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);
}
}
18 changes: 18 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,8 @@ 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;

/**
* Resets the fields specified by the provided bit-flag pattern.
Expand All @@ -69,6 +72,7 @@ public interface RoleManager extends Manager<RoleManager>
* <li>{@link #PERMISSION}</li>
* <li>{@link #HOIST}</li>
* <li>{@link #MENTIONABLE}</li>
* <li>{@link #ICON}</li>
* </ul>
*
* @param fields
Expand All @@ -92,6 +96,7 @@ public interface RoleManager extends Manager<RoleManager>
* <li>{@link #PERMISSION}</li>
* <li>{@link #HOIST}</li>
* <li>{@link #MENTIONABLE}</li>
* <li>{@link #ICON}</li>
* </ul>
*
* @param fields
Expand Down Expand Up @@ -273,6 +278,19 @@ 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);

/**
* 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 @@ -1121,7 +1121,8 @@ 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));
if (playbackCache)
getJDA().getEventCache().playbackCache(EventCache.Type.ROLE, id);
return role;
Expand Down
15 changes: 15 additions & 0 deletions 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,7 @@ public class RoleImpl implements Role
private long rawPermissions;
private int color;
private int rawPosition;
private String iconId;

public RoleImpl(long id, Guild guild)
{
Expand Down Expand Up @@ -330,6 +332,13 @@ public RoleTags getTags()
return tags == null ? RoleTagsImpl.EMPTY : tags;
}

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

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

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

public static class RoleTagsImpl implements RoleTags
{
public static final RoleTags EMPTY = new RoleTagsImpl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ protected Long handleInternally(DataObject content)
long permissions = rolejson.getLong("permissions");
boolean hoisted = rolejson.getBoolean("hoist");
boolean mentionable = rolejson.getBoolean("mentionable");
String iconId = rolejson.getString("icon", null);

if (!Objects.equals(name, role.getName()))
{
Expand Down Expand Up @@ -121,6 +122,15 @@ protected Long handleInternally(DataObject content)
getJDA(), responseNumber,
role, wasMentionable));
}
if (!Objects.equals(iconId, role.getIconId()))
{
String oldIconId = role.getIconId();
role.setIconId(iconId);
getJDA().handleEvent(
new RoleUpdateIconEvent(
getJDA(), responseNumber,
role, oldIconId));
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Icon;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.exceptions.HierarchyException;
Expand All @@ -43,6 +44,7 @@ public class RoleManagerImpl extends ManagerBase<RoleManager> implements RoleMan
protected long permissions;
protected boolean hoist;
protected boolean mentionable;
protected Icon icon;

/**
* Creates a new RoleManager instance
Expand Down Expand Up @@ -168,6 +170,15 @@ public RoleManagerImpl setMentionable(boolean mentionable)
return this;
}

@Nonnull
@Override
@CheckReturnValue
public RoleManagerImpl setIcon(Icon icon) {
sebm253 marked this conversation as resolved.
Show resolved Hide resolved
this.icon = icon;
set |= ICON;
return this;
}

@Nonnull
@Override
@CheckReturnValue
Expand Down Expand Up @@ -202,6 +213,8 @@ protected RequestBody finalizeData()
object.put("mentionable", mentionable);
if (shouldUpdate(COLOR))
object.put("color", color == Role.DEFAULT_COLOR_RAW ? 0 : color & 0xFFFFFF);
if (shouldUpdate(ICON))
object.put("icon", icon == null ? null : icon.getEncoding());
reset();
return getRequestBody(object);
}
Expand Down