Skip to content

Commit

Permalink
Implement user banner & banner color (discord-jda#1736)
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Spieß <business@minn.dev>
  • Loading branch information
2 people authored and Stonedestroyer committed Nov 11, 2021
1 parent dbce817 commit fe4959d
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 1 deletion.
101 changes: 101 additions & 0 deletions src/main/java/net/dv8tion/jda/api/entities/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import javax.annotation.CheckReturnValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.awt.Color;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
Expand Down Expand Up @@ -84,6 +85,11 @@ public interface User extends IMentionable
String AVATAR_URL = "https://cdn.discordapp.com/avatars/%s/%s.%s";
/** Template for {@link #getDefaultAvatarUrl()} */
String DEFAULT_AVATAR_URL = "https://cdn.discordapp.com/embed/avatars/%s.png";
/** Template for {@link Profile#getBannerUrl()} */
String BANNER_URL = "https://cdn.discordapp.com/banners/%s/%s.%s";

/** Used to keep consistency between color values used in the API */
int DEFAULT_ACCENT_COLOR_RAW = 0x1FFFFFFF; // java.awt.Color fills the MSB with FF, we just use 1F to provide better consistency

/**
* Creates a User instance which only wraps an ID.
Expand Down Expand Up @@ -220,6 +226,21 @@ default String getEffectiveAvatarUrl()
return avatarUrl == null ? getDefaultAvatarUrl() : avatarUrl;
}

/**
* Loads the user's {@link User.Profile} data.
* Returns a completed RestAction if this User has been retrieved using {@link JDA#retrieveUserById(long)}.
*
* @throws UnsupportedOperationException
* If this User was created with {@link #fromId(long)}
*
* @return {@link RestAction} - Type: {@link User.Profile}
*
* @since 4.3.0
*/
@Nonnull
@CheckReturnValue
RestAction<Profile> retrieveProfile();

/**
* The "tag" for this user
* <p>This is the equivalent of calling {@link java.lang.String#format(String, Object...) String.format}("%#s", user)
Expand Down Expand Up @@ -344,6 +365,86 @@ default String getEffectiveAvatarUrl()
*/
int getFlagsRaw();

/**
* Represents the information contained in a {@link User User}'s profile.
*
* @since 4.3.0
*/
class Profile
{
private final long userId;
private final String bannerId;
private final int accentColor;

public Profile(long userId, String bannerId, int accentColor)
{
this.userId = userId;
this.bannerId = bannerId;
this.accentColor = accentColor;
}

/**
* The Discord Id for this user's banner image.
* If the user has not set a banner, this will return null.
*
* @return Possibly-null String containing the {@link User User} banner id.
*/
@Nullable
public String getBannerId()
{
return bannerId;
}

/**
* The URL for the user's banner image.
* If the user has not set a banner, this will return null.
*
* @return Possibly-null String containing the {@link User User} banner url.
*
* @see User#BANNER_URL
*/
@Nullable
public String getBannerUrl()
{
return bannerId == null ? null : String.format(BANNER_URL, Long.toUnsignedString(userId), bannerId, bannerId.startsWith("a_") ? "gif" : "png");
}

/**
* The user's accent color.
* If the user has not set an accent color, this will return null.
* The automatically calculated color is not returned.
* The accent color is not shown in the client if the user has set a banner.
*
* @return Possibly-null {@link java.awt.Color} containing the {@link User User} accent color.
*/
@Nullable
public Color getAccentColor()
{
return accentColor == DEFAULT_ACCENT_COLOR_RAW ? null : new Color(accentColor);
}

/**
* The raw RGB value of this user's accent color.
* <br>Defaults to {@link #DEFAULT_ACCENT_COLOR_RAW} if this user's banner color is not available.
*
* @return The raw RGB color value or {@link User#DEFAULT_ACCENT_COLOR_RAW}
*/
public int getAccentColorRaw()
{
return accentColor;
}

@Override
public String toString()
{
return "UserProfile(" +
"userId=" + userId +
", bannerId='" + bannerId + "'" +
", accentColor=" + accentColor +
')';
}
}

/**
* Represents the bit offsets used by Discord for public flags
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,10 @@ public UserImpl createUser(DataObject user)
}
}

User.Profile profile = user.hasKey("banner")
? new User.Profile(id, user.getString("banner", null), user.getInt("accent_color", User.DEFAULT_ACCENT_COLOR_RAW))
: null;

if (newUser)
{
// Initial creation
Expand All @@ -341,7 +345,8 @@ public UserImpl createUser(DataObject user)
.setAvatarId(user.getString("avatar", null))
.setBot(user.getBoolean("bot"))
.setSystem(user.getBoolean("system"))
.setFlags(user.getInt("public_flags", 0));
.setFlags(user.getInt("public_flags", 0))
.setProfile(profile);
}
else
{
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/net/dv8tion/jda/internal/entities/UserById.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ public String getAvatarId()
return null;
}

@Nonnull
@Override
public RestAction<Profile> retrieveProfile()
{
unsupported();
return null;
}

@Nonnull
@Override
public String getDefaultAvatarId()
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/net/dv8tion/jda/internal/entities/UserImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class UserImpl extends UserById implements User
protected short discriminator;
protected String name;
protected String avatarId;
protected Profile profile;
protected long privateChannel = 0L;
protected boolean bot;
protected boolean system;
Expand Down Expand Up @@ -73,6 +74,28 @@ public String getAvatarId()
return avatarId;
}

@Nonnull
@Override
public RestAction<Profile> retrieveProfile()
{
return new DeferredRestAction<>(getJDA(), Profile.class, this::getProfile, () -> {
Route.CompiledRoute route = Route.Users.GET_USER.compile(getId());
return new RestActionImpl<>(getJDA(), route, (response, request) -> {
DataObject json = response.getObject();

String bannerId = json.getString("banner", null);
int accentColor = json.getInt("accent_color", User.DEFAULT_ACCENT_COLOR_RAW);

return new Profile(getIdLong(), bannerId, accentColor);
});
});
}

public Profile getProfile()
{
return profile;
}

@Nonnull
@Override
public String getDefaultAvatarId()
Expand Down Expand Up @@ -182,6 +205,12 @@ public UserImpl setAvatarId(String avatarId)
return this;
}

public UserImpl setProfile(Profile profile)
{
this.profile = profile;
return this;
}

public UserImpl setPrivateChannel(PrivateChannel privateChannel)
{
if (privateChannel != null)
Expand Down

0 comments on commit fe4959d

Please sign in to comment.