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

Implement user banner & banner color #1736

Merged
merged 25 commits into from
Nov 7, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c63a55b
Initial pass on user banners
RedDaedalus Jul 19, 2021
d7bd584
Docs
RedDaedalus Jul 19, 2021
fdfb0d9
User update events, undefined state fixes
RedDaedalus Jul 19, 2021
a9542d7
Event docs
RedDaedalus Jul 19, 2021
4f79cd1
Update to accent color
RedDaedalus Jul 19, 2021
43f6a95
Remove old commented code
RedDaedalus Jul 19, 2021
03de1fd
Merge branch 'DV8FromTheWorld:development' into feature/user-banners
RedDaedalus Aug 29, 2021
3522a94
Merge branch 'DV8FromTheWorld:development' into feature/user-banners
RedDaedalus Sep 5, 2021
317bdc2
Apply requested changes
RedDaedalus Sep 5, 2021
be3d041
Fix BANNER_URL docs
RedDaedalus Sep 5, 2021
077057b
Remove profile update events
RedDaedalus Sep 7, 2021
c2a4dcc
Add retriever for user profile (docs needed)
RedDaedalus Sep 7, 2021
a8d0131
Docs
RedDaedalus Sep 7, 2021
2876166
Remove direct profile getters in User, profile optimizations
RedDaedalus Sep 27, 2021
6ed35d8
Docs
RedDaedalus Sep 27, 2021
2874566
Merge branch 'DV8FromTheWorld:development' into feature/user-banners
RedDaedalus Sep 27, 2021
d75aaf0
Fix import
RedDaedalus Oct 1, 2021
29fc83f
Update src/main/java/net/dv8tion/jda/internal/entities/UserImpl.java
RedDaedalus Nov 6, 2021
979c284
Update src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.…
RedDaedalus Nov 6, 2021
6c42d4f
Update src/main/java/net/dv8tion/jda/api/entities/User.java
RedDaedalus Nov 6, 2021
2f7e3a4
Update src/main/java/net/dv8tion/jda/api/entities/User.java
RedDaedalus Nov 6, 2021
2334d31
Update src/main/java/net/dv8tion/jda/api/entities/User.java
RedDaedalus Nov 6, 2021
444090d
Update src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.…
RedDaedalus Nov 6, 2021
de71fda
Update src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.…
RedDaedalus Nov 6, 2021
4d80271
Final cleanup
MinnDevelopment Nov 6, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 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.*;
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
Expand Down Expand Up @@ -84,6 +85,8 @@ 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 #getBannerUrl()} */
String BANNER_URL = "https://cdn.discordapp.com/banners/%s/%s.%s";

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

/**
* The Discord Id for this user's banner image.
* If the user has not set a banner, this will return null.
* If the user has not been retrieved using {@link JDA#retrieveUserById(long)}, this will return null.
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved
*
* @throws UnsupportedOperationException
* If this User was created with {@link #fromId(long)}
*
* @return Possibly-null String containing the {@link net.dv8tion.jda.api.entities.User User} banner id.
*/
@Nullable
String getBannerId();

/**
* The URL for the user's banner image.
* If the user has not set a banner, this will return null.
* If the user has not been retrieved using {@link JDA#retrieveUserById(long)}, this will return null.
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved
*
* @throws UnsupportedOperationException
* If this User was created with {@link #fromId(long)}
*
* @return Possibly-null String containing the {@link net.dv8tion.jda.api.entities.User User} banner url.
*/
@Nullable
default String getBannerUrl()
{
String bannerId = getBannerId();
return bannerId == null ? null : String.format(BANNER_URL, getId(), bannerId, bannerId.startsWith("a_") ? "gif" : "png");
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* 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.
* If the user has set a banner, this accent color will not be shown.
* If the user has not been retrieved using {@link JDA#retrieveUserById(long)}, this will return null.
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved
*
* @throws UnsupportedOperationException
* If this User was created with {@link #fromId(long)}
*
* @return Possibly-null {@link java.awt.Color} containing the {@link net.dv8tion.jda.api.entities.User User} accent color.
*/
@Nullable
Color getAccentColor();
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.dv8tion.jda.api.events.user.update;
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved

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

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.awt.*;

/**
* Indicates that the accent color of a {@link net.dv8tion.jda.api.entities.User User} changed.
*
* <p>Can be used to retrieve the user who changed their accent color and their previous accent color.
*
* <p>Identifier: {@code accent_color}
*
* <h2>Requirements</h2>
* <p>This event requires that the user be fetched by the {@link net.dv8tion.jda.api.JDA#retrieveUserById(long)} method
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved
* as the user's profile data is not sent directly. Thus, the old value will be null even if the user has an accent color
* unless previously fetched.
*/
public class UserUpdateAccentColorEvent extends GenericUserUpdateEvent<Color>
{
public static final String IDENTIFIER = "accent_color";

public UserUpdateAccentColorEvent(@Nonnull JDA api, long responseNumber, @Nonnull User user, @Nullable Color oldValue)
{
super(api, responseNumber, user, oldValue, user.getAccentColor(), IDENTIFIER);
}

/**
* The old banner color
*
* @return The old banner color, null if previously unknown or unset.
*/
public Color getOldAccentColor()
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved
{
return getOldValue();
}

/**
* The new banner color
*
* @return The new banner color
*/
public Color getNewAccentColor()
{
return getNewValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package net.dv8tion.jda.api.events.user.update;
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved

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

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

/**
* Indicates that the banner of a {@link net.dv8tion.jda.api.entities.User User} changed.
*
* <p>Can be used to retrieve the user who changed their banner and their previous banner.
*
* <p>Identifier: {@code banner}
*
* <h2>Requirements</h2>
* <p>This event requires that the user be fetched by the {@link net.dv8tion.jda.api.JDA#retrieveUserById(long)} method
* as the user's profile data is not sent directly. Thus, the old value will be null even if the user has a banner unless
* previously fetched.
*/
public class UserUpdateBannerEvent extends GenericUserUpdateEvent<String>
{
public static final String IDENTIFIER = "user_banner";

public UserUpdateBannerEvent(@Nonnull JDA api, long responseNumber, @Nonnull User user, @Nullable String oldBanner)
{
super(api, responseNumber, user, oldBanner, user.getBannerId(), IDENTIFIER);
}

/**
* The previous banner id
*
* @return The previous banner id, null if previously unknown or unset.
*/
@Nullable
public String getOldBannerId()
{
return getOldValue();
}

/**
* The previous banner url
*
* @return The previous banner url, null if previously unknown or unset.
*/
@Nullable
public String getOldBannerUrl()
{
return previous == null ? null : String.format(User.BANNER_URL, getUser().getId(), previous, previous.startsWith("a_") ? "gif" : "png");
}

/**
* The new banner id
*
* @return The new banner id
*/
@Nullable
public String getNewBannerId()
{
return getNewValue();
}

/**
* The new banner url
*
* @return The new banner url
*/
@Nullable
public String getNewBannerUrl()
{
return next == null ? null : String.format(User.BANNER_URL, getUser().getId(), next, next.startsWith("a_") ? "gif" : "png");
}
}
2 changes: 2 additions & 0 deletions src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ public void onApplicationCommandCreate(@Nonnull ApplicationCommandCreateEvent ev
public void onUserUpdateName(@Nonnull UserUpdateNameEvent event) {}
public void onUserUpdateDiscriminator(@Nonnull UserUpdateDiscriminatorEvent event) {}
public void onUserUpdateAvatar(@Nonnull UserUpdateAvatarEvent event) {}
public void onUserUpdateBanner(@Nonnull UserUpdateBannerEvent event) {}
public void onUserUpdateBannerColor(@Nonnull UserUpdateAccentColorEvent event) {}
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved
public void onUserUpdateOnlineStatus(@Nonnull UserUpdateOnlineStatusEvent event) {}
public void onUserUpdateActivityOrder(@Nonnull UserUpdateActivityOrderEvent event) {}
public void onUserUpdateFlags(@Nonnull UserUpdateFlagsEvent event) {}
Expand Down
33 changes: 29 additions & 4 deletions src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateBoostTimeEvent;
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent;
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdatePendingEvent;
import net.dv8tion.jda.api.events.user.update.UserUpdateAvatarEvent;
import net.dv8tion.jda.api.events.user.update.UserUpdateDiscriminatorEvent;
import net.dv8tion.jda.api.events.user.update.UserUpdateFlagsEvent;
import net.dv8tion.jda.api.events.user.update.UserUpdateNameEvent;
import net.dv8tion.jda.api.events.user.update.*;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.utils.cache.CacheFlag;
import net.dv8tion.jda.api.utils.cache.CacheView;
Expand All @@ -60,11 +57,13 @@
import org.slf4j.Logger;

import javax.annotation.Nullable;
import java.awt.*;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.*;
import java.util.List;
import java.util.function.Function;
import java.util.function.ToLongFunction;
import java.util.function.UnaryOperator;
Expand Down Expand Up @@ -128,6 +127,8 @@ public SelfUser createSelfUser(DataObject self)
.setName(self.getString("username"))
.setDiscriminator(self.getString("discriminator"))
.setAvatarId(self.getString("avatar", null))
.setBannerId(self.getString("banner", null))
.setAccentColor(self.getInt("accent_color", -1))
.setBot(self.getBoolean("bot"))
.setSystem(false);

Expand Down Expand Up @@ -337,6 +338,8 @@ public UserImpl createUser(DataObject user)
userObj.setName(user.getString("username"))
.setDiscriminator(user.get("discriminator").toString())
.setAvatarId(user.getString("avatar", null))
.setBannerId(user.getString("banner", null))
.setAccentColor(user.getInt("accent_color", -1))
.setBot(user.getBoolean("bot"))
.setSystem(user.getBoolean("system"))
.setFlags(user.getInt("public_flags", 0));
Expand All @@ -358,6 +361,11 @@ public void updateUser(UserImpl userObj, DataObject user)
String newDiscriminator = user.get("discriminator").toString();
String oldAvatar = userObj.getAvatarId();
String newAvatar = user.getString("avatar", null);
String oldBanner = userObj.getBannerId();
String newBanner = user.hasKey("banner") ? user.getString("banner", null) : "";
// -1 = unset, -2 = unknown
int oldAccentColor = userObj.getAccentColor() == null ? -1 : userObj.getAccentColor().getRGB();
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved
int newAccentColor = user.hasKey("accent_color") ? user.getInt("accent_color", -1) : -2;
int oldFlags = userObj.getFlagsRaw();
int newFlags = user.getInt("public_flags", 0);

Expand Down Expand Up @@ -390,6 +398,23 @@ public void updateUser(UserImpl userObj, DataObject user)
userObj, oldAvatar));
}

if (!Objects.equals(oldBanner, newBanner) && !Objects.equals(newBanner, ""))
{
userObj.setBannerId(newBanner);
jda.handleEvent(
new UserUpdateBannerEvent(
jda, responseNumber,
userObj, oldBanner));
}
if (oldAccentColor != newAccentColor && newAccentColor != -2)
{
userObj.setAccentColor(newAccentColor);
jda.handleEvent(
new UserUpdateAccentColorEvent(
jda, responseNumber,
userObj, oldAccentColor == -1 ? null : new Color(oldAccentColor)));
}

if (oldFlags != newFlags)
{
userObj.setFlags(newFlags);
Expand Down
17 changes: 17 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 @@ -25,6 +25,7 @@

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.awt.*;
import java.util.EnumSet;
import java.util.List;

Expand Down Expand Up @@ -102,6 +103,22 @@ public String getAvatarId()
return null;
}

@Nullable
@Override
public String getBannerId()
{
unsupported();
return null;
}

@Nullable
@Override
public Color getAccentColor()
{
unsupported();
return null;
}

@Nonnull
@Override
public String getDefaultAvatarId()
Expand Down
30 changes: 30 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 @@ -27,8 +27,10 @@
import net.dv8tion.jda.internal.requests.RestActionImpl;
import net.dv8tion.jda.internal.requests.Route;
import net.dv8tion.jda.internal.utils.Helpers;
import org.jetbrains.annotations.Nullable;
RedDaedalus marked this conversation as resolved.
Show resolved Hide resolved

import javax.annotation.Nonnull;
import java.awt.*;
import java.util.EnumSet;
import java.util.FormattableFlags;
import java.util.Formatter;
Expand All @@ -41,6 +43,8 @@ public class UserImpl extends UserById implements User
protected short discriminator;
protected String name;
protected String avatarId;
protected String bannerId;
protected int accentColor;
protected long privateChannel = 0L;
protected boolean bot;
protected boolean system;
Expand Down Expand Up @@ -73,6 +77,20 @@ public String getAvatarId()
return avatarId;
}

@Nullable
@Override
public String getBannerId()
{
return bannerId;
}

@Nullable
@Override
public Color getAccentColor()
{
return accentColor == -1 ? null : new Color(accentColor);
}

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

public UserImpl setBannerId(String bannerId)
{
this.bannerId = bannerId;
return this;
}

public UserImpl setAccentColor(int accentColor)
{
this.accentColor = accentColor;
return this;
}

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