99import net .dv8tion .jda .api .interactions .commands .OptionType ;
1010import net .dv8tion .jda .api .interactions .components .Button ;
1111import net .dv8tion .jda .api .interactions .components .ButtonStyle ;
12+ import net .dv8tion .jda .api .requests .restaction .interactions .ReplyAction ;
1213import org .jetbrains .annotations .NotNull ;
1314import org .slf4j .Logger ;
1415import org .slf4j .LoggerFactory ;
1516import org .togetherjava .tjbot .commands .SlashCommandAdapter ;
1617import org .togetherjava .tjbot .commands .SlashCommandVisibility ;
1718
19+ import java .awt .*;
1820import java .time .Instant ;
1921import java .time .OffsetDateTime ;
2022import java .time .format .DateTimeFormatter ;
23+ import java .util .Collection ;
2124import java .util .Objects ;
2225import java .util .stream .Collectors ;
2326
24- public class WhoIsCommand extends SlashCommandAdapter {
27+ public final class WhoIsCommand extends SlashCommandAdapter {
2528 private static final Logger logger = LoggerFactory .getLogger (WhoIsCommand .class );
2629
2730 private static final String USER_OPTION = "user" ;
28- private static final String HIDE_MEMBER_INFO = "hide_member_info " ;
31+ private static final String SHOW_SERVER_SPECIFIC_INFO = "show_server_specific_info " ;
2932 private static final DateTimeFormatter DATE_TIME_FORMAT =
3033 DateTimeFormatter .ofPattern ("E, MMMM d, u, HH:mm:ss" );
3134
3235 public WhoIsCommand () {
33- super ("whois" , "who is the given user? " , SlashCommandVisibility .GUILD );
36+ super ("whois" , "Provides info about the given user" , SlashCommandVisibility .GUILD );
3437
35- getData ().addOption (OptionType .USER , USER_OPTION , "the user to look up" , true );
36- getData () .addOption (OptionType .BOOLEAN , HIDE_MEMBER_INFO ,
37- "whenever to show the member info of this user " , false );
38+ getData ().addOption (OptionType .USER , USER_OPTION , "the user to look up" , true )
39+ .addOption (OptionType .BOOLEAN , SHOW_SERVER_SPECIFIC_INFO ,
40+ "whenever to show info that is specific to this server, such as " , false );
3841 }
3942
4043 @ Override
4144 public void onSlashCommand (@ NotNull final SlashCommandEvent event ) {
4245 OptionMapping userOption = Objects .requireNonNull (event .getOption (USER_OPTION ),
4346 "The given user option cannot be null" );
47+ OptionMapping showServerSpecificInfoOption = event .getOption (SHOW_SERVER_SPECIFIC_INFO );
4448
4549 User user = userOption .getAsUser ();
4650 Member member = userOption .getAsMember ();
4751
48- if (null != member ) {
49- OptionMapping hideMemberInfoOption = event .getOption (HIDE_MEMBER_INFO );
5052
51- if (null != hideMemberInfoOption && hideMemberInfoOption .getAsBoolean ()) {
52- handleWhoIsUser (event , user );
53+ boolean showServerSpecificInfo = null != member && (null == showServerSpecificInfoOption
54+ || showServerSpecificInfoOption .getAsBoolean ());
55+
56+ user .retrieveProfile ().flatMap (profile -> {
57+ if (showServerSpecificInfo ) {
58+ return handleWhoIsMember (event , member , profile );
5359 } else {
54- handleWhoIsMember (event , member , user );
60+ return handleWhoIsUser (event , user , profile );
5561 }
56- } else {
57- handleWhoIsUser (event , user );
58- }
62+ }).queue ();
5963 }
6064
61- private static void handleWhoIsUser (final @ NotNull SlashCommandEvent event ,
62- final @ NotNull User user ) {
65+ private static ReplyAction handleWhoIsUser (final @ NotNull SlashCommandEvent event ,
66+ final @ NotNull User user , final @ NotNull User .Profile profile ) {
67+
6368 @ SuppressWarnings ("StringConcatenation" )
6469 EmbedBuilder embedBuilder = new EmbedBuilder ()
65- .setAuthor (user .getName (), user .getEffectiveAvatarUrl (), user .getEffectiveAvatarUrl ())
66- .setThumbnail (user .getEffectiveAvatarUrl ())
67- .appendDescription ("**Mention:** " + user .getAsMention ())
68- .appendDescription ("\n **Tag:** " + user .getAsTag ())
69- .appendDescription ("\n **ID:** " + user .getId ())
70- .appendDescription ("\n **Is bot:** " + (user .isBot ()))
71- .appendDescription (
72- "\n **Registration date:** " + DATE_TIME_FORMAT .format (user .getTimeCreated ()))
73- .setTimestamp (Instant .now ())
74- .setFooter ("Requested by " + event .getUser ().getAsTag (),
75- event .getMember ().getEffectiveAvatarUrl ());
76-
77-
78- event .replyEmbeds (embedBuilder .build ())
79- .addActionRow (Button .of (ButtonStyle .LINK , "discord://-/users/" + user .getId (),
80- "Click to see profile" ))
81- .queue ();
82-
70+ .setAuthor (user .getName (), user .getEffectiveAvatarUrl (), user .getEffectiveAvatarUrl ())
71+ .setThumbnail (user .getEffectiveAvatarUrl ())
72+ .setImage (profile .getBannerUrl () + "?size=4096" )
73+ .appendDescription (handleUserIdentification (user ))
74+ .appendDescription ("\n **Is bot:** " + (user .isBot ()))
75+ .appendDescription (handleUserFlags (user .getFlags ()))
76+ .appendDescription (
77+ "\n **Registration date:** " + DATE_TIME_FORMAT .format (user .getTimeCreated ()))
78+ .setTimestamp (Instant .now ())
79+ .setColor (profile .getAccentColorRaw ())
80+ .setFooter ("Requested by " + event .getUser ().getAsTag (),
81+ event .getMember ().getEffectiveAvatarUrl ());
82+
83+ return event .replyEmbeds (embedBuilder .build ())
84+ .addActionRow (Button .of (ButtonStyle .LINK , "discord://-/users/" + user .getId (),
85+ "Click to see profile" ));
8386 }
8487
85- private static void handleWhoIsMember (final @ NotNull SlashCommandEvent event ,
86- final @ NotNull Member member , final @ NotNull User user ) {
88+ private static @ NotNull ReplyAction handleWhoIsMember (final @ NotNull SlashCommandEvent event ,
89+ final @ NotNull Member member , final @ NotNull User .Profile profile ) {
90+ User user = member .getUser ();
91+
92+ Color memberColor = member .getColor ();
93+ Color effectiveColor = (null == memberColor ) ? profile .getAccentColor () : memberColor ;
8794
8895 @ SuppressWarnings ("StringConcatenation" )
8996 EmbedBuilder embedBuilder = new EmbedBuilder ()
90- .setAuthor (member .getEffectiveName (), member .getEffectiveAvatarUrl (),
91- member .getEffectiveAvatarUrl ())
92- .setThumbnail (user .getEffectiveAvatarUrl ())
93- .appendDescription ("**Mention:** " + user .getAsMention ())
94- .appendDescription ("\n **Tag:** " + user .getAsTag ())
95- .appendDescription ("\n **ID:** " + user .getId ())
96- .appendDescription ("\n **Is bot:** " + (user .isBot ()))
97- .appendDescription (boostingMemberToString (member ))
98- .appendDescription (
99- "\n **Join date:** " + DATE_TIME_FORMAT .format (member .getTimeJoined ()))
100- .appendDescription (
101- "\n **Registration date:** " + DATE_TIME_FORMAT .format (user .getTimeCreated ()))
102- .appendDescription ("\n **Roles:** " + formatRoles (member ))
103- .setColor (member .getColorRaw ())
104- .setTimestamp (Instant .now ())
105- .setFooter ("Requested by " + event .getUser ().getAsTag (),
106- event .getMember ().getEffectiveAvatarUrl ());
107-
108-
109- event .replyEmbeds (embedBuilder .build ())
110- .addActionRow (Button .of (ButtonStyle .LINK , "discord://-/users/" + user .getId (),
111- "Click to see profile" ))
112- .queue ();
97+ .setAuthor (member .getEffectiveName (), member .getEffectiveAvatarUrl (),
98+ member .getEffectiveAvatarUrl ())
99+ .setThumbnail (user .getEffectiveAvatarUrl ())
100+ .setColor (effectiveColor )
101+ .appendDescription (handleUserIdentification (user ))
102+ .appendDescription ("\n **Is bot:** " + (user .isBot ()))
103+ .appendDescription (handlePossibleBooster (member ))
104+ .appendDescription (handleUserFlags (user .getFlags ()))
105+ .appendDescription (
106+ "\n **Join date:** " + DATE_TIME_FORMAT .format (member .getTimeJoined ()))
107+ .appendDescription (
108+ "\n **Registration date:** " + DATE_TIME_FORMAT .format (user .getTimeCreated ()))
109+ .appendDescription ("\n **Roles:** " + formatRoles (member )).setImage (profile .getBannerUrl () + "?size=4096" )
110+ .setFooter ("Requested by " + event .getUser ().getAsTag (),
111+ event .getMember ().getEffectiveAvatarUrl ())
112+ .setTimestamp (Instant .now ());
113+
114+
115+ return event .replyEmbeds (embedBuilder .build ())
116+ .addActionRow (Button .of (ButtonStyle .LINK , "discord://-/users/" + user .getId (),
117+ "Click to see profile" ));
113118 }
114119
115- private static @ NotNull String boostingMemberToString (final @ NotNull Member member ) {
120+
121+ // TODO add doc
122+ private static @ NotNull String handlePossibleBooster (final @ NotNull Member member ) {
116123 OffsetDateTime timeBoosted = member .getTimeBoosted ();
117124 if (null != timeBoosted ) {
118- return "\n **Is booster:** true" + " \n **Boosting since:** "
125+ return "\n **Is booster:** true \n **Boosting since:** "
119126 + DATE_TIME_FORMAT .format (timeBoosted );
120127 } else {
121128 return "\n **Is booster:** false" ;
122129 }
123130 }
124131
125- /*
126- * .addField("Mention:", user.getAsMention(), false) .addField("Tag:", user.getAsTag(), false)
127- * .addField("ID", user.getId(), false) .addField("Join date",
128- * DATE_TIME_FORMAT.format(member.getTimeJoined()), true) .addField("Registration date",
129- * DATE_TIME_FORMAT.format(user.getTimeCreated()), true) .addField("Roles", formatRoles(member),
130- * false)
131- */
132+ private static @ NotNull StringBuilder handleUserIdentification (final @ NotNull User user ) {
133+ return new StringBuilder ("**Mention:** " ).append (user .getAsMention ())
134+ .append ("\n **Tag:** " ).append ( user .getAsTag ())
135+ .append ("\n **ID:** " ).append (user .getId ());
136+ }
132137
133- private static String formatRoles (final Member member ) {
138+ // TODO add doc
139+ private static String formatRoles (final @ NotNull Member member ) {
134140 return member .getRoles ().stream ().map (Role ::getAsMention ).collect (Collectors .joining (", " ));
135141 }
136- }
142+
143+ // TODO add doc and improve naming?
144+ private static @ NotNull StringBuilder handleUserFlags (final @ NotNull Collection <User .UserFlag > flags ) {
145+ return formatHypesquad (flags )
146+ .append ("\n **Flags:** " )
147+ .append (formatUserFlags (flags ));
148+ }
149+
150+ private static @ NotNull StringBuilder formatHypesquad (final @ NotNull Collection <User .UserFlag > flags ) {
151+ StringBuilder stringBuilder = new StringBuilder ("**Hypesquad:** " );
152+
153+ if (flags .contains (User .UserFlag .HYPESQUAD_BALANCE )) {
154+ stringBuilder .append (User .UserFlag .HYPESQUAD_BALANCE .getName ());
155+ } else if (flags .contains (User .UserFlag .HYPESQUAD_BRAVERY )) {
156+ stringBuilder .append (User .UserFlag .HYPESQUAD_BRAVERY .getName ());
157+ } else if (flags .contains (User .UserFlag .HYPESQUAD_BRILLIANCE )) {
158+ stringBuilder .append (User .UserFlag .HYPESQUAD_BRILLIANCE .getName ());
159+ } else {
160+ stringBuilder .append ("joined none" );
161+ }
162+
163+ return stringBuilder ;
164+ }
165+
166+ @ NotNull
167+ private static String formatUserFlags (final @ NotNull Collection <User .UserFlag > flags ) {
168+ return flags .stream ()
169+ .map (User .UserFlag ::getName )
170+ .filter (name -> (name .contains ("Hypesquad" )))
171+ .collect (Collectors .joining (", " ));
172+ }
173+ }
0 commit comments