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

Message interface declutter: Message#getMentions() #2015

Merged
merged 31 commits into from
May 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
29a5cad
Reworked mentions into Message#getMentions
DV8FromTheWorld Feb 5, 2022
e8e9d3b
Fixed examples
DV8FromTheWorld Feb 5, 2022
50e0214
Removed unneeded TODOs
DV8FromTheWorld Feb 5, 2022
b4c4734
Merge remote-tracking branch 'origin/master' into feature/mentions-re…
MinnDevelopment Apr 17, 2022
e931305
Finish mentions rework implementation
MinnDevelopment Apr 17, 2022
17185e4
Add interaction mentions
MinnDevelopment Apr 17, 2022
1c5b136
Fix errors
MinnDevelopment Apr 17, 2022
181fc16
Sort mentions in getMentions(...)
MinnDevelopment Apr 17, 2022
83e38bc
Add back synchronization and guild check
MinnDevelopment Apr 17, 2022
ea60fb7
Cleanup EntityBuilder#createMessage0
MinnDevelopment Apr 20, 2022
b09ce8f
Handle user mentions in interactions
MinnDevelopment Apr 20, 2022
88f7213
Fix parsing bug
MinnDevelopment Apr 20, 2022
8cfbad4
Improve mention parsing for members and update cache eagerly
MinnDevelopment Apr 20, 2022
8b7a4e1
Add missing null check
MinnDevelopment Apr 20, 2022
3597015
Parse user mentions on messages too
MinnDevelopment Apr 20, 2022
387bd73
Role mentions are only an id
MinnDevelopment Apr 20, 2022
c7392ad
Move matchEmote
MinnDevelopment Apr 20, 2022
370fbf3
Merge remote-tracking branch 'origin/master' into continued/mentions-…
MinnDevelopment Apr 21, 2022
c65d134
Make use of UserSnowflake and fix bags
MinnDevelopment Apr 21, 2022
00e6c95
Reduce code duplication
MinnDevelopment Apr 21, 2022
fd74ff3
Improve getMentions and isMentioned code
MinnDevelopment Apr 21, 2022
aa1647e
Add missing overrides
MinnDevelopment Apr 21, 2022
d7bdd6c
Rename interface
MinnDevelopment Apr 21, 2022
4702a18
Improve isRoleMentioned
MinnDevelopment Apr 21, 2022
2f5e2e4
Add missing documentation and fix a bunch of docs
MinnDevelopment Apr 22, 2022
ce61f92
Fix InteractionMentions#isUserMentioned
MinnDevelopment Apr 22, 2022
b7dbd5b
Remove Message#getEmotes
MinnDevelopment Apr 22, 2022
2053454
Fix wrong link tag
MinnDevelopment Apr 22, 2022
56bd13d
Added type-specific getChannels getters
DV8FromTheWorld Apr 27, 2022
5b99414
Apply suggestions from code review
DV8FromTheWorld Apr 28, 2022
cb24d6d
Added an example for type-specific channel list getter
DV8FromTheWorld Apr 28, 2022
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
4 changes: 2 additions & 2 deletions src/examples/java/MessageListenerExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ else if (msg.startsWith("!kick")) //Note, I used "startsWith, not equals.
if (message.isFromType(ChannelType.TEXT))
{
//If no users are provided, we can't kick anyone!
if (message.getMentionedUsers().isEmpty())
if (message.getMentions().getUsers().isEmpty())
{
channel.sendMessage("You must mention 1 or more Users to be kicked!").queue();
}
Expand All @@ -187,7 +187,7 @@ else if (msg.startsWith("!kick")) //Note, I used "startsWith, not equals.
}

//Loop over all mentioned users, kicking them one at a time. Mwauahahah!
List<User> mentionedUsers = message.getMentionedUsers();
List<User> mentionedUsers = message.getMentions().getUsers();
for (User user : mentionedUsers)
{
Member member = guild.getMember(user); //We get the member object for each mentioned user to kick them!
Expand Down
365 changes: 365 additions & 0 deletions src/main/java/net/dv8tion/jda/api/entities/Mentions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,365 @@
/*
* 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.entities;

import net.dv8tion.jda.api.JDA;
import org.apache.commons.collections4.Bag;

import javax.annotation.Nonnull;
import java.util.List;

/**
* Interface to access the mentions of various entities.
*/
public interface Mentions
{
/**
* The corresponding JDA instance
*
* @return The jda instance
*/
@Nonnull
JDA getJDA();

/**
* Indicates if everyone is mentioned, by either using {@code @everyone} or {@code @here}.
*
* <p>This is different from checking if {@code @everyone} is in the string, since mentions require additional flags to trigger.
*
* @return True, if everyone is mentioned
*/
boolean mentionsEveryone();

/**
* An immutable list of all mentioned {@link net.dv8tion.jda.api.entities.User Users}.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>If no user was mentioned, this list is empty. Elements are sorted in order of appearance. This only
* counts direct mentions of the user and not mentions through roles or everyone mentions.
*
* <p>This might also contain users which are not present in {@link #getMembers()}.
*
* @return Immutable list of mentioned users
*/
@Nonnull
List<User> getUsers();

/**
* A {@link org.apache.commons.collections4.Bag Bag} of mentioned {@link net.dv8tion.jda.api.entities.User Users}.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>This can be used to retrieve the amount of times a user was mentioned. This only
* counts direct mentions of the user and not mentions through roles or everyone mentions.
*
* <p>This might also contain users which are not present in {@link #getMembers()}.
*
* <h2>Example</h2>
* <pre>{@code
* void sendCount(Message msg)
* {
* List<User> mentions = msg.getMentions().getUsers(); // distinct list, in order of appearance
* Bag<User> count = msg.getMentions().getUsersBag();
* StringBuilder content = new StringBuilder();
* for (User user : mentions)
* {
* content.append(user.getAsTag())
* .append(": ")
* .append(count.getCount(user))
* .append("\n");
* }
* msg.getChannel().sendMessage(content.toString()).queue();
* }
* }</pre>
*
* @return {@link org.apache.commons.collections4.Bag Bag} of mentioned users
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* @see #getUsers()
*/
@Nonnull
Bag<User> getUsersBag();

/**
* An immutable list of all mentioned {@link net.dv8tion.jda.api.entities.GuildChannel GuildChannels}.
* <br>If none were mentioned, this list is empty. Elements are sorted in order of appearance.
*
* <p><b>This may include GuildChannels from other {@link net.dv8tion.jda.api.entities.Guild Guilds}</b>
*
* @return Immutable list of mentioned GuildChannels
*/
@Nonnull
List<GuildChannel> getChannels();

/**
* A {@link org.apache.commons.collections4.Bag Bag} of mentioned channels.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>This can be used to retrieve the amount of times a channel was mentioned.
*
* <p><b>This may include GuildChannels from other {@link net.dv8tion.jda.api.entities.Guild Guilds}</b>
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* <h2>Example</h2>
* <pre>{@code
* void sendCount(Message msg)
* {
* Bag<GuildChannel> mentions = msg.getMentions().getChannelsBag();
* StringBuilder content = new StringBuilder();
* for (GuildChannel channel : mentions.uniqueSet())
* {
* content.append("#")
* .append(channel.getName())
* .append(": ")
* .append(mentions.getCount(channel))
* .append("\n");
* }
* msg.getChannel().sendMessage(content.toString()).queue();
* }
* }</pre>
*
* @return {@link org.apache.commons.collections4.Bag Bag} of mentioned channels
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* @see #getChannels()
*/
@Nonnull
Bag<GuildChannel> getChannelsBag();

/**
* An immutable list of all mentioned {@link net.dv8tion.jda.api.entities.GuildChannel GuildChannels} of type {@code clazz}.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>If none were mentioned, this list is empty. Elements are sorted in order of appearance.
*
* <p><b>This may include GuildChannels from other {@link net.dv8tion.jda.api.entities.Guild Guilds}</b>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add an example

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 👍

DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* <h2>Example</h2>
* <pre>{@code
* List<GuildMessageChannel> getCoolMessageChannels(Message msg)
* {
* List<GuildMessageChannel> channels = msg.getMentions().getChannels(GuildMessageChannel.class);
* return channels.stream()
* .filter(channel -> channel.getName().contains("cool"))
* .collect(Collectors.toList());
* }
* }</pre>
*
* @param clazz
* The {@link GuildChannel} sub-class {@link Class class object} of the type of channel desired
*
* @throws java.lang.IllegalArgumentException
* If {@code clazz} is {@code null}
*
* @return Immutable list of mentioned GuildChannels that are of type {@code clazz}.
*/
@Nonnull
<T extends GuildChannel> List<T> getChannels(@Nonnull Class<T> clazz);

/**
* A {@link org.apache.commons.collections4.Bag Bag} of mentioned channels of type {@code clazz}.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>This can be used to retrieve the amount of times a channel was mentioned.
*
* <p><b>This may include GuildChannels from other {@link net.dv8tion.jda.api.entities.Guild Guilds}</b>
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* <h2>Example</h2>
* <pre>{@code
* void sendCount(Message msg)
* {
* Bag<GuildMessageChannel> mentions = msg.getMentions().getChannelsBag(GuildMessageChannel.class);
* StringBuilder content = new StringBuilder();
* for (GuildMessageChannel channel : mentions.uniqueSet())
* {
* content.append("#")
* .append(channel.getName())
* .append(": ")
* .append(mentions.getCount(channel))
* .append("\n");
* }
* msg.getChannel().sendMessage(content.toString()).queue();
* }
* }</pre>
*
* @param clazz
* The {@link GuildChannel} sub-class {@link Class class object} of the type of channel desired
*
* @throws java.lang.IllegalArgumentException
* If {@code clazz} is {@code null}
*
* @return {@link org.apache.commons.collections4.Bag Bag} of mentioned channels of type {@code clazz}
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* @see #getChannels(Class)
*/
@Nonnull
<T extends GuildChannel> Bag<T> getChannelsBag(@Nonnull Class<T> clazz);

/**
* An immutable list of all mentioned {@link net.dv8tion.jda.api.entities.Role Roles}.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>If none were mentioned, this list is empty. Elements are sorted in order of appearance. This only
* counts direct mentions of the role and not mentions through everyone mentions.
*
* <p><b>This may include Roles from other {@link net.dv8tion.jda.api.entities.Guild Guilds}</b>
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* @return immutable list of mentioned Roles
*/
@Nonnull
List<Role> getRoles();

/**
* A {@link org.apache.commons.collections4.Bag Bag} of mentioned roles.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>This can be used to retrieve the amount of times a role was mentioned. This only
* counts direct mentions of the role and not mentions through everyone mentions.
*
* <p><b>This may include Roles from other {@link net.dv8tion.jda.api.entities.Guild Guilds}</b>
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* <h2>Example</h2>
* <pre>{@code
* void sendCount(Message msg)
* {
* List<Role> mentions = msg.getMentions().getRoles(); // distinct list, in order of appearance
* Bag<Role> count = msg.getMentions().getRolesBag();
* StringBuilder content = new StringBuilder();
* for (Role role : mentions)
* {
* content.append(role.getName())
* .append(": ")
* .append(count.getCount(role))
* .append("\n");
* }
* msg.getChannel().sendMessage(content.toString()).queue();
* }
* }</pre>
*
* @return {@link org.apache.commons.collections4.Bag Bag} of mentioned roles
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* @see #getRoles()
*/
@Nonnull
Bag<Role> getRolesBag();

/**
* All {@link net.dv8tion.jda.api.entities.Emote Emotes} used.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br><b>This only includes Custom Emotes, not unicode Emojis.</b> JDA classifies Emotes as the Custom Emojis uploaded
* to a Guild and retrievable with {@link net.dv8tion.jda.api.entities.Guild#getEmotes()}. These are not the same
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* as the unicode emojis that Discord also supports. Elements are sorted in order of appearance.
*
* <p><b><u>Unicode emojis are not included as {@link net.dv8tion.jda.api.entities.Emote Emote}!</u></b>
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* @return An immutable list of the Emotes used (example match {@literal <:jda:230988580904763393>})
*/
@Nonnull
List<Emote> getEmotes();

/**
* A {@link org.apache.commons.collections4.Bag Bag} of emotes used.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>This can be used to retrieve the amount of times an emote was used.
*
* <h2>Example</h2>
* <pre>{@code
* void sendCount(Message msg)
* {
* List<Emote> emotes = msg.getMentions().getEmotes(); // distinct list, in order of appearance
* Bag<Emote> count = msg.getMentions().getEmotesBag();
* StringBuilder content = new StringBuilder();
* for (Emote emote : emotes)
* {
* content.append(emote.getName())
* .append(": ")
* .append(count.getCount(role))
* .append("\n");
* }
* msg.getChannel().sendMessage(content.toString()).queue();
* }
* }</pre>
*
* @return {@link org.apache.commons.collections4.Bag Bag} of used emotes
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* @see #getEmotes()
*/
@Nonnull
Bag<Emote> getEmotesBag();

/**
* An immutable list of all mentioned {@link net.dv8tion.jda.api.entities.Member Members}.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>If none were mentioned, this list is empty. Elements are sorted in order of appearance. This only
* counts direct mentions of the role and not mentions through everyone mentions.
*
* <p>This is always empty in {@link PrivateChannel PrivateChannels}.
*
* @return Immutable list of mentioned Members, or an empty list
*/
@Nonnull
List<Member> getMembers();

/**
* A {@link org.apache.commons.collections4.Bag Bag} of mentioned {@link net.dv8tion.jda.api.entities.Member Members}.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>This can be used to retrieve the amount of times a user was mentioned. This only
* counts direct mentions of the member and not mentions through roles or everyone mentions.
*
* <h2>Example</h2>
* <pre>{@code
* void sendCount(Message msg)
* {
* List<Member> mentions = msg.getMentions().getMembers(); // distinct list, in order of appearance
* Bag<Member> count = msg.getMentions().getMembersBag();
* StringBuilder content = new StringBuilder();
* for (Member user : mentions)
* {
* content.append(member.getUser().getAsTag())
* .append(": ")
* .append(count.getCount(member))
* .append("\n");
* }
* msg.getChannel().sendMessage(content.toString()).queue();
* }
* }</pre>
*
* @return {@link org.apache.commons.collections4.Bag Bag} of mentioned members
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
*
* @see #getMembers()
*/
@Nonnull
Bag<Member> getMembersBag();

/**
* Combines all instances of {@link net.dv8tion.jda.api.entities.IMentionable IMentionable}
* filtered by the specified {@link net.dv8tion.jda.api.entities.Message.MentionType MentionType} values.
DV8FromTheWorld marked this conversation as resolved.
Show resolved Hide resolved
* <br>If a {@link Member} is available, it will be taken in favor of a {@link User}.
* This only provides either the Member or the User instance, rather than both.
*
* <p>If no MentionType values are given, all types are used.
*
* @param types
* {@link net.dv8tion.jda.api.entities.Message.MentionType MentionTypes} to include
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* {@link net.dv8tion.jda.api.entities.Message.MentionType MentionTypes} to include
* {@link Message.MentionType MentionTypes} to include

*
* @throws java.lang.IllegalArgumentException
* If provided with {@code null}
*
* @return Immutable list of filtered {@link net.dv8tion.jda.api.entities.IMentionable IMentionable} instances
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @return Immutable list of filtered {@link net.dv8tion.jda.api.entities.IMentionable IMentionable} instances
* @return Immutable list of filtered {@link IMentionable} instances

*/
@Nonnull
List<IMentionable> getMentions(@Nonnull Message.MentionType... types);

/**
* Checks if given {@link net.dv8tion.jda.api.entities.IMentionable IMentionable}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Checks if given {@link net.dv8tion.jda.api.entities.IMentionable IMentionable}
* Checks if given {@link IMentionable}

* was mentioned in any way (@User, @everyone, @here, @Role).
* <br>If no filtering {@link net.dv8tion.jda.api.entities.Message.MentionType MentionTypes} are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* <br>If no filtering {@link net.dv8tion.jda.api.entities.Message.MentionType MentionTypes} are
* <br>If no filtering {@link Message.MentionType MentionTypes} are

* specified, all types are used.
*
* <p>{@link Message.MentionType#HERE MentionType.HERE} and {@link Message.MentionType#EVERYONE MentionType.EVERYONE}
* will only be checked, if the given {@link net.dv8tion.jda.api.entities.IMentionable IMentionable} is of type
* {@link net.dv8tion.jda.api.entities.User User} or {@link net.dv8tion.jda.api.entities.Member Member}.
Comment on lines +352 to +353
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* will only be checked, if the given {@link net.dv8tion.jda.api.entities.IMentionable IMentionable} is of type
* {@link net.dv8tion.jda.api.entities.User User} or {@link net.dv8tion.jda.api.entities.Member Member}.
* will only be checked, if the given {@link IMentionable} is of type
* {@link User} or {@link Member}.

* <br>Online status of Users/Members is <b>NOT</b> considered when checking {@link Message.MentionType#HERE MentionType.HERE}.
*
* @param mentionable
* The mentionable entity to check on.
* @param types
* The types to include when checking whether this type was mentioned.
* This will be used with {@link #getMentions(Message.MentionType...) getMentions(MentionType...)}
*
* @return True, if the given mentionable was mentioned in this message
*/
boolean isMentioned(@Nonnull IMentionable mentionable, @Nonnull Message.MentionType... types);
}
Loading