mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2025-02-17 01:51:32 +01:00
Lots of interactions & commands
This commit is contained in:
parent
07554e8126
commit
d8f5f89c19
@ -21,10 +21,9 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.component;
|
||||
package com.discordsrv.api.discord.entity;
|
||||
|
||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.api.discord.entity.JDAEntity;
|
||||
import com.discordsrv.api.discord.entity.component.impl.Modal;
|
||||
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessage;
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of the DiscordSRV API, licensed under the MIT License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.channel;
|
||||
|
||||
import com.discordsrv.api.discord.entity.JDAEntity;
|
||||
import net.dv8tion.jda.api.entities.ChannelType;
|
||||
|
||||
/**
|
||||
* Represents a Discord channel type.
|
||||
*/
|
||||
public enum DiscordChannelType implements JDAEntity<ChannelType> {
|
||||
|
||||
TEXT(ChannelType.TEXT),
|
||||
PRIVATE(ChannelType.PRIVATE),
|
||||
VOICE(ChannelType.VOICE),
|
||||
GROUP(ChannelType.GROUP),
|
||||
CATEGORY(ChannelType.CATEGORY),
|
||||
NEWS(ChannelType.NEWS),
|
||||
STAGE(ChannelType.STAGE),
|
||||
GUILD_NEWS_THREAD(ChannelType.GUILD_NEWS_THREAD),
|
||||
GUILD_PUBLIC_THREAD(ChannelType.GUILD_PUBLIC_THREAD),
|
||||
GUILD_PRIVATE_THREAD(ChannelType.GUILD_PRIVATE_THREAD),
|
||||
;
|
||||
|
||||
private final ChannelType jda;
|
||||
|
||||
DiscordChannelType(ChannelType jda) {
|
||||
this.jda = jda;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelType asJDA() {
|
||||
return jda;
|
||||
}
|
||||
}
|
@ -40,4 +40,8 @@ public interface DiscordDMChannel extends DiscordMessageChannel, JDAEntity<Priva
|
||||
@Nullable
|
||||
DiscordUser getUser();
|
||||
|
||||
@Override
|
||||
default DiscordChannelType getType() {
|
||||
return DiscordChannelType.PRIVATE;
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,12 @@ import java.util.concurrent.CompletableFuture;
|
||||
*/
|
||||
public interface DiscordMessageChannel extends Snowflake {
|
||||
|
||||
/**
|
||||
* Returns the type of channel this is.
|
||||
* @return the type of the channel
|
||||
*/
|
||||
DiscordChannelType getType();
|
||||
|
||||
/**
|
||||
* Sends the provided message to the channel.
|
||||
*
|
||||
|
@ -26,4 +26,11 @@ package com.discordsrv.api.discord.entity.channel;
|
||||
import com.discordsrv.api.discord.entity.JDAEntity;
|
||||
import net.dv8tion.jda.api.entities.NewsChannel;
|
||||
|
||||
public interface DiscordNewsChannel extends DiscordGuildMessageChannel, DiscordThreadContainer, JDAEntity<NewsChannel> {}
|
||||
public interface DiscordNewsChannel extends DiscordGuildMessageChannel, DiscordThreadContainer, JDAEntity<NewsChannel> {
|
||||
|
||||
@Override
|
||||
default DiscordChannelType getType() {
|
||||
return DiscordChannelType.NEWS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,4 +39,8 @@ public interface DiscordTextChannel extends DiscordGuildMessageChannel, DiscordT
|
||||
@Nullable
|
||||
String getTopic();
|
||||
|
||||
@Override
|
||||
default DiscordChannelType getType() {
|
||||
return DiscordChannelType.TEXT;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,377 @@
|
||||
/*
|
||||
* This file is part of the DiscordSRV API, licensed under the MIT License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.command;
|
||||
|
||||
import com.discordsrv.api.discord.entity.JDAEntity;
|
||||
import net.dv8tion.jda.api.Permission;
|
||||
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Command implements JDAEntity<CommandData> {
|
||||
|
||||
/**
|
||||
* Creates a chat input or slash command builder.
|
||||
*
|
||||
* @param name the name of the command
|
||||
* @param description the description of the command
|
||||
* @return a new chat input command builder
|
||||
*/
|
||||
public static ChatInputBuilder chatInput(String name, String description) {
|
||||
return new ChatInputBuilder(name, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user context menu command.
|
||||
*
|
||||
* @param name the name of the command
|
||||
* @return a new command builder
|
||||
*/
|
||||
public static Builder user(String name) {
|
||||
return new Builder(Type.USER, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new message context menu command.
|
||||
*
|
||||
* @param name the name of the command
|
||||
* @return a new command builder
|
||||
*/
|
||||
public static Builder message(String name) {
|
||||
return new Builder(Type.MESSAGE, name);
|
||||
}
|
||||
|
||||
private final Type type;
|
||||
private final Map<Locale, String> nameTranslations;
|
||||
private final Map<Locale, String> descriptionTranslations;
|
||||
private final List<SubCommandGroup> subCommandGroups;
|
||||
private final List<Command> subCommands;
|
||||
private final List<CommandOption> options;
|
||||
private final boolean guildOnly;
|
||||
private final DefaultPermission defaultPermission;
|
||||
|
||||
private Command(
|
||||
Type type,
|
||||
Map<Locale, String> nameTranslations,
|
||||
Map<Locale, String> descriptionTranslations,
|
||||
List<SubCommandGroup> subCommandGroups,
|
||||
List<Command> subCommands,
|
||||
List<CommandOption> options,
|
||||
boolean guildOnly,
|
||||
DefaultPermission defaultPermission
|
||||
) {
|
||||
this.type = type;
|
||||
this.nameTranslations = nameTranslations;
|
||||
this.descriptionTranslations = descriptionTranslations;
|
||||
this.subCommandGroups = subCommandGroups;
|
||||
this.subCommands = subCommands;
|
||||
this.options = options;
|
||||
this.guildOnly = guildOnly;
|
||||
this.defaultPermission = defaultPermission;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return nameTranslations.get(Locale.ROOT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public Map<Locale, String> getNameTranslations() {
|
||||
return Collections.unmodifiableMap(nameTranslations);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDescription() {
|
||||
return descriptionTranslations.get(Locale.ROOT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public Map<Locale, String> getDescriptionTranslations() {
|
||||
return Collections.unmodifiableMap(descriptionTranslations);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public List<SubCommandGroup> getSubCommandGroups() {
|
||||
return Collections.unmodifiableList(subCommandGroups);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public List<CommandOption> getOptions() {
|
||||
return Collections.unmodifiableList(options);
|
||||
}
|
||||
|
||||
public boolean isGuildOnly() {
|
||||
return guildOnly;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DefaultPermission getDefaultPermission() {
|
||||
return defaultPermission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandData asJDA() {
|
||||
CommandData commandData;
|
||||
switch (type) {
|
||||
case USER:
|
||||
commandData = Commands.user(getName());
|
||||
break;
|
||||
case MESSAGE:
|
||||
commandData = Commands.message(getName());
|
||||
break;
|
||||
case CHAT_INPUT:
|
||||
SlashCommandData slashCommandData = Commands.slash(getName(), Objects.requireNonNull(getDescription()));
|
||||
slashCommandData.addSubcommandGroups(subCommandGroups.stream().map(JDAEntity::asJDA).toArray(SubcommandGroupData[]::new));
|
||||
slashCommandData.addSubcommands(subCommands.stream().map(Command::asJDASubcommand).toArray(SubcommandData[]::new));
|
||||
slashCommandData.addOptions(options.stream().map(JDAEntity::asJDA).toArray(OptionData[]::new));
|
||||
commandData = slashCommandData;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Missing switch case");
|
||||
}
|
||||
|
||||
commandData.setGuildOnly(guildOnly);
|
||||
commandData.setDefaultPermissions(defaultPermission.asJDA());
|
||||
|
||||
return commandData;
|
||||
}
|
||||
|
||||
public SubcommandData asJDASubcommand() {
|
||||
SubcommandData data = new SubcommandData(nameTranslations.get(Locale.ROOT), descriptionTranslations.get(Locale.ROOT));
|
||||
data.addOptions(options.stream().map(JDAEntity::asJDA).toArray(OptionData[]::new));
|
||||
return data;
|
||||
}
|
||||
|
||||
public static class ChatInputBuilder extends Builder {
|
||||
|
||||
private final Map<Locale, String> descriptionTranslations = new LinkedHashMap<>();
|
||||
private final List<SubCommandGroup> subCommandGroups = new ArrayList<>();
|
||||
private final List<Command> subCommands = new ArrayList<>();
|
||||
private final List<CommandOption> options = new ArrayList<>();
|
||||
|
||||
private ChatInputBuilder(String name, String description) {
|
||||
super(Type.CHAT_INPUT, name);
|
||||
this.descriptionTranslations.put(Locale.ROOT, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a description translation for this command.
|
||||
* @param locale the language
|
||||
* @param translation the translation
|
||||
* @return this builder, useful for chaining
|
||||
* @throws IllegalStateException if this isn't a {@link Type#CHAT_INPUT} command
|
||||
*/
|
||||
@NotNull
|
||||
public ChatInputBuilder addDescriptionTranslation(@NotNull Locale locale, @NotNull String translation) {
|
||||
if (type != Type.CHAT_INPUT) {
|
||||
throw new IllegalStateException("Descriptions are only available for CHAT_INPUT commands");
|
||||
}
|
||||
this.descriptionTranslations.put(locale, translation);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a sub command group to this command.
|
||||
*
|
||||
* @param subCommandGroup the sub command group
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public ChatInputBuilder addSubCommandGroup(@NotNull SubCommandGroup subCommandGroup) {
|
||||
this.subCommandGroups.add(subCommandGroup);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a sub command to this command.
|
||||
*
|
||||
* @param command the sub command
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public ChatInputBuilder addSubCommand(@NotNull Command command) {
|
||||
this.subCommands.add(command);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an option to this command.
|
||||
*
|
||||
* @param option the option
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public ChatInputBuilder addOption(@NotNull CommandOption option) {
|
||||
this.options.add(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command build() {
|
||||
return new Command(
|
||||
type,
|
||||
nameTranslations,
|
||||
descriptionTranslations,
|
||||
subCommandGroups,
|
||||
subCommands,
|
||||
options,
|
||||
guildOnly,
|
||||
defaultPermission
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
protected final Type type;
|
||||
protected final Map<Locale, String> nameTranslations = new LinkedHashMap<>();
|
||||
protected boolean guildOnly = true;
|
||||
protected DefaultPermission defaultPermission = DefaultPermission.EVERYONE;
|
||||
|
||||
private Builder(Type type, String name) {
|
||||
this.type = type;
|
||||
this.nameTranslations.put(Locale.ROOT, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a name translation for this command.
|
||||
* @param locale the language
|
||||
* @param translation the translation
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public Builder addNameTranslation(@NotNull Locale locale, @NotNull String translation) {
|
||||
this.nameTranslations.put(locale, translation);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this command is limited to Discord servers.
|
||||
* @param guildOnly if this command is limited to Discord servers
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public Builder setGuildOnly(boolean guildOnly) {
|
||||
this.guildOnly = guildOnly;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the permission level required to use the command by default.
|
||||
* @param defaultPermission the permission level
|
||||
*/
|
||||
@NotNull
|
||||
public Builder setDefaultPermission(@NotNull DefaultPermission defaultPermission) {
|
||||
this.defaultPermission = defaultPermission;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Command build() {
|
||||
return new Command(
|
||||
type,
|
||||
nameTranslations,
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
guildOnly,
|
||||
defaultPermission
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public interface DefaultPermission extends JDAEntity<DefaultMemberPermissions> {
|
||||
|
||||
DefaultPermission EVERYONE = new Simple(true);
|
||||
DefaultPermission ADMINISTRATOR = new Simple(false);
|
||||
|
||||
DefaultPermission BAN_MEMBERS = Permissions.fromJDA(Permission.BAN_MEMBERS);
|
||||
DefaultPermission MODERATE_MEMBERS = Permissions.fromJDA(Permission.MODERATE_MEMBERS);
|
||||
DefaultPermission MANAGE_PERMISSIONS = Permissions.fromJDA(Permission.MANAGE_PERMISSIONS);
|
||||
DefaultPermission MESSAGE_MANAGE = Permissions.fromJDA(Permission.MESSAGE_MANAGE);
|
||||
|
||||
class Simple implements DefaultPermission {
|
||||
|
||||
private final boolean value;
|
||||
|
||||
private Simple(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultMemberPermissions asJDA() {
|
||||
return value ? DefaultMemberPermissions.ENABLED : DefaultMemberPermissions.DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
class Permissions implements DefaultPermission {
|
||||
|
||||
public static Permissions fromJDA(Permission... permissions) {
|
||||
return new Permissions(Permission.getRaw(permissions));
|
||||
}
|
||||
|
||||
private final long permissions;
|
||||
|
||||
public Permissions(long permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultMemberPermissions asJDA() {
|
||||
return DefaultMemberPermissions.enabledFor(permissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Type implements JDAEntity<net.dv8tion.jda.api.interactions.commands.Command.Type> {
|
||||
|
||||
CHAT_INPUT(net.dv8tion.jda.api.interactions.commands.Command.Type.SLASH),
|
||||
USER(net.dv8tion.jda.api.interactions.commands.Command.Type.USER),
|
||||
MESSAGE(net.dv8tion.jda.api.interactions.commands.Command.Type.MESSAGE);
|
||||
|
||||
private final net.dv8tion.jda.api.interactions.commands.Command.Type jda;
|
||||
|
||||
Type(net.dv8tion.jda.api.interactions.commands.Command.Type jda) {
|
||||
this.jda = jda;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.dv8tion.jda.api.interactions.commands.Command.Type asJDA() {
|
||||
return jda;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* This file is part of the DiscordSRV API, licensed under the MIT License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.command;
|
||||
|
||||
import com.discordsrv.api.discord.entity.JDAEntity;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CommandOption implements JDAEntity<OptionData> {
|
||||
|
||||
/**
|
||||
* Creates a new command option builder.
|
||||
*
|
||||
* @param type the type of the command option
|
||||
* @param name the name of the command option
|
||||
* @param description the description of the command option
|
||||
* @return the new command option builder
|
||||
*/
|
||||
@NotNull
|
||||
public static Builder builder(@NotNull Type type, @NotNull String name, @NotNull String description) {
|
||||
return new Builder(type, name, description);
|
||||
}
|
||||
|
||||
private final Type type;
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final Map<String, Object> choices;
|
||||
|
||||
public CommandOption(Type type, String name, String description, Map<String, Object> choices) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.choices = choices;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public Map<String, Object> getChoices() {
|
||||
return Collections.unmodifiableMap(choices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionData asJDA() {
|
||||
OptionData data = new OptionData(type.asJDA(), name, description);
|
||||
for (Map.Entry<String, Object> entry : choices.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof String) {
|
||||
data.addChoice(key, (String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
data.addChoice(key, (Integer) value);
|
||||
} else if (value instanceof Double) {
|
||||
data.addChoice(key, (Double) value);
|
||||
} else {
|
||||
throw new IllegalStateException("Not a String, Integer or Double choice value");
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final Type type;
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final Map<String, Object> choices = new LinkedHashMap<>();
|
||||
|
||||
private Builder(Type type, String name, String description) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a String choice, type must be {@link Type#STRING}.
|
||||
*
|
||||
* @param name the name of the choice, this will be returned via the event
|
||||
* @param stringValue the choice
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public Builder addChoice(String name, String stringValue) {
|
||||
if (type != Type.DOUBLE) {
|
||||
throw new IllegalStateException("Must be of type STRING");
|
||||
}
|
||||
this.choices.put(name, stringValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a String choice, type must be {@link Type#INTEGER}.
|
||||
*
|
||||
* @param name the name of the choice, this will be returned via the event
|
||||
* @param integerValue the choice
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public Builder addChoice(String name, int integerValue) {
|
||||
if (type != Type.INTEGER) {
|
||||
throw new IllegalStateException("Must be of type INTEGER");
|
||||
}
|
||||
this.choices.put(name, integerValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a String choice, type must be {@link Type#DOUBLE}.
|
||||
*
|
||||
* @param name the name of the choice, this will be returned via the event
|
||||
* @param doubleValue the choice
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public Builder addChoice(String name, double doubleValue) {
|
||||
if (type != Type.DOUBLE) {
|
||||
throw new IllegalStateException("Must be of type DOUBLE");
|
||||
}
|
||||
this.choices.put(name, doubleValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CommandOption build() {
|
||||
return new CommandOption(type, name, description, choices);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Type implements JDAEntity<OptionType> {
|
||||
STRING(OptionType.STRING),
|
||||
INTEGER(OptionType.INTEGER),
|
||||
DOUBLE(OptionType.NUMBER),
|
||||
BOOLEAN(OptionType.BOOLEAN),
|
||||
|
||||
USER(OptionType.USER),
|
||||
CHANNEL(OptionType.CHANNEL),
|
||||
ROLE(OptionType.ROLE),
|
||||
MENTIONABLE(OptionType.MENTIONABLE),
|
||||
|
||||
ATTACHMENT(OptionType.ATTACHMENT);
|
||||
|
||||
private final OptionType optionType;
|
||||
|
||||
Type(OptionType optionType) {
|
||||
this.optionType = optionType;
|
||||
}
|
||||
|
||||
public boolean isSupportsChoices() {
|
||||
return optionType.canSupportChoices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionType asJDA() {
|
||||
return optionType;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of the DiscordSRV API, licensed under the MIT License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.command;
|
||||
|
||||
import com.discordsrv.api.discord.entity.JDAEntity;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class SubCommandGroup implements JDAEntity<SubcommandGroupData> {
|
||||
|
||||
/**
|
||||
* Creates a sub command group.
|
||||
*
|
||||
* @param name the sub command group name
|
||||
* @param description the sub command group description
|
||||
* @param commands the commands within the sub command group
|
||||
* @return a new sub command group
|
||||
*/
|
||||
@NotNull
|
||||
public static SubCommandGroup of(@NotNull String name, @NotNull String description, @NotNull Command... commands) {
|
||||
return new SubCommandGroup(name, description, Arrays.asList(commands));
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final List<Command> commands;
|
||||
|
||||
private SubCommandGroup(String name, String description, List<Command> commands) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public List<Command> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubcommandGroupData asJDA() {
|
||||
return new SubcommandGroupData(name, description)
|
||||
.addSubcommands(commands.stream().map(Command::asJDASubcommand).toArray(SubcommandData[]::new));
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* This file is part of the DiscordSRV API, licensed under the MIT License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.component;
|
||||
|
||||
import org.intellij.lang.annotations.Pattern;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An identifier for components to match up with interaction events.
|
||||
*/
|
||||
public class ComponentIdentifier {
|
||||
|
||||
public static final String ID_PREFIX = "DiscordSRV/";
|
||||
|
||||
private static final String REGEX = "[\\w\\d-_]{1,40}";
|
||||
private static final java.util.regex.Pattern PATTERN = java.util.regex.Pattern.compile(REGEX);
|
||||
|
||||
/**
|
||||
* Creates a new {@link ComponentIdentifier}.
|
||||
*
|
||||
* @param extensionName the name of the plugin or mod that owns this identifier (1-40 characters, a-z, A-Z, 0-9, -, _)
|
||||
* @param identifier the identifier of this component (1-40 characters, a-z, A-Z, 0-9, -, _)
|
||||
* @return a new {@link ComponentIdentifier}
|
||||
* @throws IllegalArgumentException if the extension name or identifier does not match the required constraints
|
||||
*/
|
||||
@NotNull
|
||||
public static ComponentIdentifier of(
|
||||
@NotNull @Pattern(REGEX) String extensionName,
|
||||
@NotNull @Pattern(REGEX) String identifier
|
||||
) {
|
||||
if (!PATTERN.matcher(extensionName).matches()) {
|
||||
throw new IllegalArgumentException("Extension name does not match the required pattern");
|
||||
} else if (!PATTERN.matcher(identifier).matches()) {
|
||||
throw new IllegalArgumentException("Identifier does not match the required pattern");
|
||||
}
|
||||
return new ComponentIdentifier(extensionName, identifier);
|
||||
}
|
||||
|
||||
private final String extensionName;
|
||||
private final String identifier;
|
||||
|
||||
private ComponentIdentifier(String extensionName, String identifier) {
|
||||
this.extensionName = extensionName;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public String getExtensionName() {
|
||||
return extensionName;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public String getDiscordIdentifier() {
|
||||
return ID_PREFIX + getExtensionName() + ":" + getIdentifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ComponentIdentifier that = (ComponentIdentifier) o;
|
||||
return Objects.equals(extensionName, that.extensionName) && Objects.equals(identifier, that.identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(extensionName, identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ComponentIdentifier{" +
|
||||
"extensionName='" + extensionName + '\'' +
|
||||
", identifier='" + identifier + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ import java.util.List;
|
||||
|
||||
public class MessageActionRow implements ActionRow<MessageComponent> {
|
||||
|
||||
public static MessageActionRow message(MessageComponent... components) {
|
||||
public static MessageActionRow of(MessageComponent... components) {
|
||||
if (components.length == 0) {
|
||||
throw new IllegalArgumentException("Must include at least one component");
|
||||
}
|
||||
|
@ -21,10 +21,12 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.component;
|
||||
package com.discordsrv.api.discord.entity.component.impl;
|
||||
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordEmote;
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
import com.discordsrv.api.discord.entity.component.ComponentIdentifier;
|
||||
import com.discordsrv.api.discord.entity.component.MessageComponent;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordCustomEmoji;
|
||||
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
||||
import net.dv8tion.jda.api.interactions.components.ItemComponent;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -35,7 +37,8 @@ import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A Discord button.
|
||||
* @see #builder(Style)
|
||||
* @see #builder(ComponentIdentifier, Style)
|
||||
* @see #urlBuilder(String)
|
||||
*/
|
||||
public class Button implements MessageComponent {
|
||||
|
||||
@ -44,8 +47,19 @@ public class Button implements MessageComponent {
|
||||
* @param style the style of the button
|
||||
* @return a new button builder
|
||||
*/
|
||||
public static Builder builder(@NotNull Button.Style style) {
|
||||
return new Builder(style);
|
||||
@NotNull
|
||||
public static Builder builder(@NotNull ComponentIdentifier id, @NotNull Button.Style style) {
|
||||
return new Builder(id.getDiscordIdentifier(), style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Link button builder.
|
||||
* @param url the link the button leads to
|
||||
* @return a new button builder
|
||||
*/
|
||||
@NotNull
|
||||
public static Builder urlBuilder(@NotNull String url) {
|
||||
return new Builder(null, Style.LINK).setUrl(url);
|
||||
}
|
||||
|
||||
private final Style buttonStyle;
|
||||
@ -53,22 +67,20 @@ public class Button implements MessageComponent {
|
||||
private final String label;
|
||||
private final Emoji emoji;
|
||||
private final boolean disabled;
|
||||
private final ClickHandler clickHandler;
|
||||
|
||||
private Button(
|
||||
String id,
|
||||
Style buttonStyle,
|
||||
String url,
|
||||
String label,
|
||||
Emoji emoji,
|
||||
boolean disabled,
|
||||
ClickHandler clickHandler
|
||||
boolean disabled
|
||||
) {
|
||||
this.buttonStyle = buttonStyle;
|
||||
this.idOrUrl = buttonStyle == Style.LINK ? url : UUID.randomUUID().toString();
|
||||
this.idOrUrl = buttonStyle == Style.LINK ? url : id;
|
||||
this.label = label;
|
||||
this.emoji = emoji;
|
||||
this.disabled = disabled;
|
||||
this.clickHandler = clickHandler;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -95,10 +107,6 @@ public class Button implements MessageComponent {
|
||||
return disabled;
|
||||
}
|
||||
|
||||
public ClickHandler getClickHandler() {
|
||||
return clickHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemComponent asJDA() {
|
||||
return net.dv8tion.jda.api.interactions.components.buttons.Button.of(
|
||||
@ -111,22 +119,18 @@ public class Button implements MessageComponent {
|
||||
|
||||
private static class Builder {
|
||||
|
||||
private final String id;
|
||||
private final Style style;
|
||||
private String url;
|
||||
private String label;
|
||||
private Emoji emoji;
|
||||
private boolean disabled;
|
||||
private ClickHandler clickHandler;
|
||||
|
||||
private Builder(Style style) {
|
||||
private Builder(String id, Style style) {
|
||||
this.id = id;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Style getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the url for this button, only works if the style is {@link Style#LINK}.
|
||||
*
|
||||
@ -142,10 +146,6 @@ public class Button implements MessageComponent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text shown on this button.
|
||||
* @param label the text
|
||||
@ -157,10 +157,6 @@ public class Button implements MessageComponent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the emoji to show on this button.
|
||||
* @param unicodeEmoji the unicode code point for the emoji
|
||||
@ -178,15 +174,11 @@ public class Button implements MessageComponent {
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public Builder setEmoji(DiscordEmote emote) {
|
||||
this.emoji = Emoji.fromEmote(emote.asJDA());
|
||||
public Builder setEmoji(DiscordCustomEmoji emote) {
|
||||
this.emoji = Emoji.fromCustom(emote.asJDA());
|
||||
return this;
|
||||
}
|
||||
|
||||
public Emoji getEmoji() {
|
||||
return emoji;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if this button is disabled or not. Default is {@code false}.
|
||||
* @param disabled if this button should be disabled
|
||||
@ -198,28 +190,6 @@ public class Button implements MessageComponent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the click handler for this button, does not work if the style is {@link Style#LINK}.
|
||||
* @param clickHandler the click handler
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public Builder setClickHandler(ClickHandler clickHandler) {
|
||||
if (style == Style.LINK) {
|
||||
throw new IllegalStateException("Cannot set click handler for LINK type button, use setUrl instead");
|
||||
}
|
||||
this.clickHandler = clickHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClickHandler getClickHandler() {
|
||||
return clickHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the button.
|
||||
* @return a new button
|
||||
@ -229,12 +199,12 @@ public class Button implements MessageComponent {
|
||||
throw new IllegalStateException("No style set");
|
||||
}
|
||||
return new Button(
|
||||
id,
|
||||
style,
|
||||
style == Style.LINK ? url : UUID.randomUUID().toString(),
|
||||
label,
|
||||
emoji,
|
||||
disabled,
|
||||
clickHandler
|
||||
disabled
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -256,11 +226,4 @@ public class Button implements MessageComponent {
|
||||
return style;
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ClickHandler {
|
||||
|
||||
void onClick(Interaction interaction);
|
||||
|
||||
}
|
||||
}
|
@ -21,20 +21,22 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.component;
|
||||
package com.discordsrv.api.discord.entity.component.impl;
|
||||
|
||||
import com.discordsrv.api.discord.entity.JDAEntity;
|
||||
import com.discordsrv.api.discord.entity.component.ComponentIdentifier;
|
||||
import com.discordsrv.api.discord.entity.component.actionrow.ActionRow;
|
||||
import com.discordsrv.api.discord.entity.component.actionrow.ModalActionRow;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A Discord modal.
|
||||
* @see #builder(String)
|
||||
* @see #builder(ComponentIdentifier, String)
|
||||
*/
|
||||
public class Modal implements JDAEntity<net.dv8tion.jda.api.interactions.components.Modal> {
|
||||
|
||||
@ -43,16 +45,17 @@ public class Modal implements JDAEntity<net.dv8tion.jda.api.interactions.compone
|
||||
* @param title the title of the modal
|
||||
* @return a new modal builder
|
||||
*/
|
||||
public static Builder builder(String title) {
|
||||
return new Builder(title);
|
||||
@NotNull
|
||||
public static Builder builder(@NotNull ComponentIdentifier id, @NotNull String title) {
|
||||
return new Builder(id.getDiscordIdentifier(), title);
|
||||
}
|
||||
|
||||
private final String id;
|
||||
private final String title;
|
||||
private final List<ModalActionRow> rows;
|
||||
|
||||
private Modal(String title, List<ModalActionRow> rows) {
|
||||
this.id = UUID.randomUUID().toString();
|
||||
private Modal(String id, String title, List<ModalActionRow> rows) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.rows = rows;
|
||||
}
|
||||
@ -79,10 +82,12 @@ public class Modal implements JDAEntity<net.dv8tion.jda.api.interactions.compone
|
||||
|
||||
private static class Builder {
|
||||
|
||||
private final String id;
|
||||
private final String title;
|
||||
private final List<ModalActionRow> rows = new ArrayList<>();
|
||||
|
||||
public Builder(String title) {
|
||||
public Builder(String id, String title) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@ -108,18 +113,12 @@ public class Modal implements JDAEntity<net.dv8tion.jda.api.interactions.compone
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public List<ModalActionRow> getRows() {
|
||||
return Collections.unmodifiableList(rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the modal.
|
||||
* @return a new modal
|
||||
*/
|
||||
public Modal build() {
|
||||
return new Modal(title, rows);
|
||||
return new Modal(id, title, rows);
|
||||
}
|
||||
}
|
||||
}
|
@ -21,21 +21,22 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.component;
|
||||
package com.discordsrv.api.discord.entity.component.impl;
|
||||
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordEmote;
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
import com.discordsrv.api.discord.entity.component.ComponentIdentifier;
|
||||
import com.discordsrv.api.discord.entity.component.MessageComponent;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordCustomEmoji;
|
||||
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
||||
import net.dv8tion.jda.api.interactions.components.ItemComponent;
|
||||
import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A Discord selection menu.
|
||||
* @see #builder()
|
||||
* @see #builder(ComponentIdentifier)
|
||||
*/
|
||||
public class SelectMenu implements MessageComponent {
|
||||
|
||||
@ -43,8 +44,8 @@ public class SelectMenu implements MessageComponent {
|
||||
* Creates a selection menu builder.
|
||||
* @return a new builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
public static Builder builder(@NotNull ComponentIdentifier id) {
|
||||
return new Builder(id.getDiscordIdentifier());
|
||||
}
|
||||
|
||||
private final String id;
|
||||
@ -53,16 +54,14 @@ public class SelectMenu implements MessageComponent {
|
||||
private final String placeholder;
|
||||
private final int minValues;
|
||||
private final int maxValues;
|
||||
private final SelectHandler handler;
|
||||
|
||||
private SelectMenu(List<Option> options, boolean disabled, String placeholder, int minValues, int maxValues, SelectHandler handler) {
|
||||
this.id = UUID.randomUUID().toString();
|
||||
private SelectMenu(String id, List<Option> options, boolean disabled, String placeholder, int minValues, int maxValues) {
|
||||
this.id = id;
|
||||
this.options = options;
|
||||
this.disabled = disabled;
|
||||
this.placeholder = placeholder;
|
||||
this.minValues = minValues;
|
||||
this.maxValues = maxValues;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -166,8 +165,8 @@ public class SelectMenu implements MessageComponent {
|
||||
* @return a new option
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public Option withEmoji(DiscordEmote emote) {
|
||||
return new Option(label, value, description, Emoji.fromEmote(emote.asJDA()), defaultSelected);
|
||||
public Option withEmoji(DiscordCustomEmoji emote) {
|
||||
return new Option(label, value, description, Emoji.fromCustom(emote.asJDA()), defaultSelected);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,12 +182,16 @@ public class SelectMenu implements MessageComponent {
|
||||
|
||||
private static class Builder {
|
||||
|
||||
private final String id;
|
||||
private final List<Option> options = new ArrayList<>();
|
||||
private boolean disabled = false;
|
||||
private String placeholder;
|
||||
private int minValues = 0;
|
||||
private int maxValues = 1;
|
||||
private SelectHandler handler;
|
||||
|
||||
public Builder(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an option to this selection menu.
|
||||
@ -213,12 +216,6 @@ public class SelectMenu implements MessageComponent {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public List<Option> getOptions() {
|
||||
return Collections.unmodifiableList(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this selection menu should be disabled. Default is {@code false}.
|
||||
* @param disabled if this selection menu should be disabled
|
||||
@ -230,10 +227,6 @@ public class SelectMenu implements MessageComponent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the placeholder text for this selection menu.
|
||||
* @param placeholder the placeholder text
|
||||
@ -244,10 +237,6 @@ public class SelectMenu implements MessageComponent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getPlaceholder() {
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum amount of values to select. The default is {@code 0}.
|
||||
* @param minValues the minimum value amount
|
||||
@ -258,10 +247,6 @@ public class SelectMenu implements MessageComponent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getMinValues() {
|
||||
return minValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum amount of values to select. The default is {@code 1}.
|
||||
* @param maxValues the maximum value amount
|
||||
@ -272,36 +257,12 @@ public class SelectMenu implements MessageComponent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getMaxValues() {
|
||||
return maxValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the handler for selection changes.
|
||||
* @param handler the handler
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public Builder setHandler(SelectHandler handler) {
|
||||
this.handler = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectHandler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the selection menu.
|
||||
* @return a new selection menu
|
||||
*/
|
||||
public SelectMenu build() {
|
||||
return new SelectMenu(options, disabled, placeholder, minValues, maxValues, handler);
|
||||
return new SelectMenu(id, options, disabled, placeholder, minValues, maxValues);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SelectHandler {
|
||||
void onSelect(Interaction interaction);
|
||||
}
|
||||
}
|
@ -21,17 +21,19 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.discord.entity.component;
|
||||
package com.discordsrv.api.discord.entity.component.impl;
|
||||
|
||||
import com.discordsrv.api.discord.entity.component.ComponentIdentifier;
|
||||
import com.discordsrv.api.discord.entity.component.ModalComponent;
|
||||
import net.dv8tion.jda.api.interactions.components.ItemComponent;
|
||||
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TextInput implements ModalComponent {
|
||||
|
||||
public static Builder builder(String label, Style style) {
|
||||
return new Builder(label, style);
|
||||
@NotNull
|
||||
public static Builder builder(@NotNull ComponentIdentifier id, @NotNull String label, @NotNull Style style) {
|
||||
return new Builder(id.getDiscordIdentifier(), label, style);
|
||||
}
|
||||
|
||||
private final String id;
|
||||
@ -43,8 +45,17 @@ public class TextInput implements ModalComponent {
|
||||
private final boolean required;
|
||||
private final String defaultValue;
|
||||
|
||||
public TextInput(String label, Style style, int minLength, int maxLength, String placeholder, boolean required, String defaultValue) {
|
||||
this.id = UUID.randomUUID().toString();
|
||||
public TextInput(
|
||||
String id,
|
||||
String label,
|
||||
Style style,
|
||||
int minLength,
|
||||
int maxLength,
|
||||
String placeholder,
|
||||
boolean required,
|
||||
String defaultValue
|
||||
) {
|
||||
this.id = id;
|
||||
this.label = label;
|
||||
this.style = style;
|
||||
this.minLength = minLength;
|
||||
@ -97,6 +108,7 @@ public class TextInput implements ModalComponent {
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final String id;
|
||||
private final String label;
|
||||
private final Style style;
|
||||
private int minLength = 0;
|
||||
@ -105,61 +117,47 @@ public class TextInput implements ModalComponent {
|
||||
private boolean required = true;
|
||||
private String defaultValue;
|
||||
|
||||
private Builder(String label, Style style) {
|
||||
private Builder(String id, String label, Style style) {
|
||||
this.id = id;
|
||||
this.label = label;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public Style getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public Builder setMinLength(int minLength) {
|
||||
this.minLength = minLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getMinLength() {
|
||||
return minLength;
|
||||
}
|
||||
|
||||
public Builder setMaxLength(int maxLength) {
|
||||
this.maxLength = maxLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getMaxLength() {
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
public Builder setPlaceholder(String placeholder) {
|
||||
this.placeholder = placeholder;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getPlaceholder() {
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
public Builder setRequired(boolean required) {
|
||||
this.required = required;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isRequired() {
|
||||
return required;
|
||||
}
|
||||
|
||||
public void setDefaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
public TextInput build() {
|
||||
return new TextInput(
|
||||
id,
|
||||
label,
|
||||
style,
|
||||
minLength,
|
||||
maxLength,
|
||||
placeholder,
|
||||
required,
|
||||
defaultValue
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ package com.discordsrv.api.discord.entity.guild;
|
||||
|
||||
import com.discordsrv.api.discord.entity.JDAEntity;
|
||||
import com.discordsrv.api.discord.entity.Snowflake;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.entities.emoji.CustomEmoji;
|
||||
|
||||
public interface DiscordEmote extends JDAEntity<Emote>, Snowflake {
|
||||
public interface DiscordCustomEmoji extends JDAEntity<CustomEmoji>, Snowflake {
|
||||
|
||||
String getName();
|
||||
|
@ -31,6 +31,7 @@ import com.discordsrv.api.discord.entity.channel.DiscordTextChannel;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuild;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@ -39,7 +40,28 @@ import java.util.concurrent.CompletableFuture;
|
||||
/**
|
||||
* A message received from Discord.
|
||||
*/
|
||||
public interface ReceivedDiscordMessage extends SendableDiscordMessage, Snowflake {
|
||||
public interface ReceivedDiscordMessage extends Snowflake {
|
||||
|
||||
/**
|
||||
* Gets the content of this message.
|
||||
* @return the message content
|
||||
*/
|
||||
@NotNull
|
||||
String getContent();
|
||||
|
||||
/**
|
||||
* Gets the embeds of this message.
|
||||
* @return the message embeds
|
||||
*/
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
List<DiscordMessageEmbed> getEmbeds();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this is a webhook message, {@link #getAuthor()} to get webhook username or avatar url.
|
||||
* @return {@code true} if this is a webhook message
|
||||
*/
|
||||
boolean isWebhookMessage();
|
||||
|
||||
/**
|
||||
* Gets the URL to jump to this message.
|
||||
|
@ -24,9 +24,11 @@
|
||||
package com.discordsrv.api.discord.entity.message;
|
||||
|
||||
import com.discordsrv.api.component.GameTextBuilder;
|
||||
import com.discordsrv.api.discord.entity.component.actionrow.MessageActionRow;
|
||||
import com.discordsrv.api.discord.entity.message.impl.SendableDiscordMessageImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -64,13 +66,23 @@ public interface SendableDiscordMessage {
|
||||
* @return the unmodifiable list of embeds in this message
|
||||
*/
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
List<DiscordMessageEmbed> getEmbeds();
|
||||
|
||||
/**
|
||||
* Gets the allowed mentions of the message.
|
||||
* @return the allowed mentions in this message
|
||||
* Gets the action rows.
|
||||
* @return an unmodifiable list of action rows in this message
|
||||
*/
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
List<MessageActionRow> getActionRows();
|
||||
|
||||
/**
|
||||
* Gets the allowed mentions of the message.
|
||||
* @return the unmodifiable list of allowed mentions in this message
|
||||
*/
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
Set<AllowedMention> getAllowedMentions();
|
||||
|
||||
/**
|
||||
@ -136,6 +148,33 @@ public interface SendableDiscordMessage {
|
||||
@NotNull
|
||||
Builder removeEmbed(DiscordMessageEmbed embed);
|
||||
|
||||
/**
|
||||
* Gets the action rows for this builder.
|
||||
* @return the action rows
|
||||
*/
|
||||
List<MessageActionRow> getActionRows();
|
||||
|
||||
/**
|
||||
* Sets the action rows for this builder.
|
||||
* @param rows the action rows
|
||||
* @return the builder, useful for chaining
|
||||
*/
|
||||
Builder setActionRows(MessageActionRow... rows);
|
||||
|
||||
/**
|
||||
* Adds an action row to this builder.
|
||||
* @param row the action row
|
||||
* @return the builder, useful for chaining
|
||||
*/
|
||||
Builder addActionRow(MessageActionRow row);
|
||||
|
||||
/**
|
||||
* Removes an action row from this builder.
|
||||
* @param row the action row
|
||||
* @return the builder, useful for chaining
|
||||
*/
|
||||
Builder removeActionRow(MessageActionRow row);
|
||||
|
||||
/**
|
||||
* Gets the allowed mentions in this builder.
|
||||
* @return the builder's current allowed mentions
|
||||
|
@ -24,6 +24,7 @@
|
||||
package com.discordsrv.api.discord.entity.message.impl;
|
||||
|
||||
import com.discordsrv.api.DiscordSRVApi;
|
||||
import com.discordsrv.api.discord.entity.component.actionrow.MessageActionRow;
|
||||
import com.discordsrv.api.discord.entity.message.AllowedMention;
|
||||
import com.discordsrv.api.discord.entity.message.DiscordMessageEmbed;
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
@ -44,21 +45,23 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
||||
|
||||
private final String content;
|
||||
private final List<DiscordMessageEmbed> embeds;
|
||||
private final List<MessageActionRow> actionRows;
|
||||
private final Set<AllowedMention> allowedMentions;
|
||||
private final String webhookUsername;
|
||||
private final String webhookAvatarUrl;
|
||||
|
||||
|
||||
protected SendableDiscordMessageImpl(
|
||||
String content,
|
||||
List<DiscordMessageEmbed> embeds,
|
||||
List<MessageActionRow> actionRows,
|
||||
Set<AllowedMention> allowedMentions,
|
||||
String webhookUsername,
|
||||
String webhookAvatarUrl
|
||||
) {
|
||||
this.content = content;
|
||||
this.embeds = embeds;
|
||||
this.allowedMentions = allowedMentions;
|
||||
this.embeds = Collections.unmodifiableList(embeds);
|
||||
this.actionRows = Collections.unmodifiableList(actionRows);
|
||||
this.allowedMentions = Collections.unmodifiableSet(allowedMentions);
|
||||
this.webhookUsername = webhookUsername;
|
||||
this.webhookAvatarUrl = webhookAvatarUrl;
|
||||
}
|
||||
@ -73,6 +76,12 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
||||
return embeds;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MessageActionRow> getActionRows() {
|
||||
return actionRows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<AllowedMention> getAllowedMentions() {
|
||||
return allowedMentions;
|
||||
@ -92,6 +101,7 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
||||
|
||||
private String content;
|
||||
private final List<DiscordMessageEmbed> embeds = new ArrayList<>();
|
||||
private final List<MessageActionRow> actionRows = new ArrayList<>();
|
||||
private final Set<AllowedMention> allowedMentions = new LinkedHashSet<>();
|
||||
private String webhookUsername;
|
||||
private String webhookAvatarUrl;
|
||||
@ -109,7 +119,7 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
||||
|
||||
@Override
|
||||
public @NotNull List<DiscordMessageEmbed> getEmbeds() {
|
||||
return embeds;
|
||||
return Collections.unmodifiableList(embeds);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -124,6 +134,30 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MessageActionRow> getActionRows() {
|
||||
return actionRows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder setActionRows(MessageActionRow... rows) {
|
||||
this.actionRows.clear();
|
||||
this.actionRows.addAll(Arrays.asList(rows));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder addActionRow(MessageActionRow row) {
|
||||
this.actionRows.add(row);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder removeActionRow(MessageActionRow row) {
|
||||
this.actionRows.remove(row);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<AllowedMention> getAllowedMentions() {
|
||||
return allowedMentions;
|
||||
@ -172,7 +206,7 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
||||
|
||||
@Override
|
||||
public @NotNull SendableDiscordMessage build() {
|
||||
return new SendableDiscordMessageImpl(content, embeds, allowedMentions, webhookUsername, webhookAvatarUrl);
|
||||
return new SendableDiscordMessageImpl(content, embeds, actionRows, allowedMentions, webhookUsername, webhookAvatarUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,7 +42,7 @@ public class DiscordChatMessageProcessingEvent implements Cancellable, Processab
|
||||
|
||||
public DiscordChatMessageProcessingEvent(@NotNull ReceivedDiscordMessage discordMessage, @NotNull DiscordMessageChannel channel) {
|
||||
this.discordMessage = discordMessage;
|
||||
this.messageContent = discordMessage.getContent().orElse(null);
|
||||
this.messageContent = discordMessage.getContent();
|
||||
this.channel = channel;
|
||||
if (!(channel instanceof DiscordTextChannel) && !(channel instanceof DiscordThreadChannel)) {
|
||||
throw new IllegalStateException("Cannot process messages that aren't from a text channel or thread");
|
||||
|
@ -35,7 +35,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AbstractDiscordThreadedGuildMessageChannel<T extends GuildMessageChannel & IThreadContainer>
|
||||
public abstract class AbstractDiscordThreadedGuildMessageChannel<T extends GuildMessageChannel & IThreadContainer>
|
||||
extends AbstractDiscordGuildMessageChannel<T>
|
||||
implements DiscordGuildMessageChannel, DiscordThreadContainer {
|
||||
|
||||
|
@ -19,11 +19,13 @@
|
||||
package com.discordsrv.common.discord.api.entity.channel;
|
||||
|
||||
import club.minnced.discord.webhook.WebhookClient;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordChannelType;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordTextChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordThreadChannel;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuild;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.discord.api.entity.guild.DiscordGuildImpl;
|
||||
import net.dv8tion.jda.api.entities.ChannelType;
|
||||
import net.dv8tion.jda.api.entities.IThreadContainer;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.entities.ThreadChannel;
|
||||
@ -77,4 +79,15 @@ public class DiscordThreadChannelImpl extends AbstractDiscordGuildMessageChannel
|
||||
public ThreadChannel asJDA() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscordChannelType getType() {
|
||||
ChannelType type = channel.getType();
|
||||
for (DiscordChannelType value : DiscordChannelType.values()) {
|
||||
if (value.asJDA() == type) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Unknown channel type");
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@
|
||||
package com.discordsrv.common.discord.api.entity.component;
|
||||
|
||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.api.discord.entity.component.Interaction;
|
||||
import com.discordsrv.api.discord.entity.component.Modal;
|
||||
import com.discordsrv.api.discord.entity.Interaction;
|
||||
import com.discordsrv.api.discord.entity.component.impl.Modal;
|
||||
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessage;
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
|
@ -22,7 +22,6 @@ import club.minnced.discord.webhook.WebhookClient;
|
||||
import club.minnced.discord.webhook.receive.ReadonlyAttachment;
|
||||
import club.minnced.discord.webhook.receive.ReadonlyEmbed;
|
||||
import club.minnced.discord.webhook.receive.ReadonlyMessage;
|
||||
import club.minnced.discord.webhook.receive.ReadonlyUser;
|
||||
import club.minnced.discord.webhook.send.WebhookEmbed;
|
||||
import com.discordsrv.api.color.Color;
|
||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
@ -34,7 +33,6 @@ import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
||||
import com.discordsrv.api.discord.entity.message.DiscordMessageEmbed;
|
||||
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessage;
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.api.discord.entity.message.impl.SendableDiscordMessageImpl;
|
||||
import com.discordsrv.api.discord.exception.RestErrorResponseException;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
||||
@ -49,18 +47,17 @@ import com.discordsrv.common.future.util.CompletableFutureUtil;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.requests.ErrorResponse;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl implements ReceivedDiscordMessage {
|
||||
public class ReceivedDiscordMessageImpl implements ReceivedDiscordMessage {
|
||||
|
||||
public static ReceivedDiscordMessage fromJDA(DiscordSRV discordSRV, Message message) {
|
||||
List<DiscordMessageEmbed> mappedEmbeds = new ArrayList<>();
|
||||
@ -69,9 +66,6 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
||||
}
|
||||
|
||||
boolean webhookMessage = message.isWebhookMessage();
|
||||
String webhookUsername = webhookMessage ? message.getAuthor().getName() : null;
|
||||
String webhookAvatarUrl = webhookMessage ? message.getAuthor().getEffectiveAvatarUrl() : null;
|
||||
|
||||
DiscordMessageChannel channel = AbstractDiscordMessageChannel.get(discordSRV, message.getChannel());
|
||||
DiscordUser user = new DiscordUserImpl(discordSRV, message.getAuthor());
|
||||
|
||||
@ -118,8 +112,7 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
||||
message.getIdLong(),
|
||||
message.getContentRaw(),
|
||||
mappedEmbeds,
|
||||
webhookUsername,
|
||||
webhookAvatarUrl
|
||||
webhookMessage
|
||||
);
|
||||
}
|
||||
|
||||
@ -155,13 +148,6 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
||||
));
|
||||
}
|
||||
|
||||
ReadonlyUser author = webhookMessage.getAuthor();
|
||||
String authorId = Long.toUnsignedString(author.getId());
|
||||
String avatarId = author.getAvatarId();
|
||||
String avatarUrl = avatarId != null
|
||||
? String.format(User.AVATAR_URL, authorId, avatarId, avatarId.startsWith("a_") ? "gif" : "png")
|
||||
: String.format(User.DEFAULT_AVATAR_URL, Integer.parseInt(author.getDiscriminator()) % 5);
|
||||
|
||||
DiscordMessageChannel channel = discordSRV.discordAPI().getMessageChannelById(
|
||||
webhookMessage.getChannelId()).orElse(null);
|
||||
DiscordUser user = discordSRV.discordAPI().getUserById(
|
||||
@ -191,8 +177,7 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
||||
webhookMessage.getId(),
|
||||
webhookMessage.getContent(),
|
||||
mappedEmbeds,
|
||||
author.getName(),
|
||||
avatarUrl
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
@ -203,6 +188,9 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
||||
private final ReceivedDiscordMessage replyingTo;
|
||||
private final DiscordGuildMember member;
|
||||
private final DiscordUser author;
|
||||
private final String content;
|
||||
private final List<DiscordMessageEmbed> embeds;
|
||||
private final boolean webhookMessage;
|
||||
private final long channelId;
|
||||
private final long id;
|
||||
|
||||
@ -218,10 +206,8 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
||||
long id,
|
||||
String content,
|
||||
List<DiscordMessageEmbed> embeds,
|
||||
String webhookUsername,
|
||||
String webhookAvatarUrl
|
||||
boolean webhookMessage
|
||||
) {
|
||||
super(content, embeds, Collections.emptySet(), webhookUsername, webhookAvatarUrl);
|
||||
this.discordSRV = discordSRV;
|
||||
this.attachments = attachments;
|
||||
this.fromSelf = fromSelf;
|
||||
@ -229,6 +215,9 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
||||
this.replyingTo = replyingTo;
|
||||
this.member = member;
|
||||
this.author = author;
|
||||
this.content = content;
|
||||
this.embeds = embeds;
|
||||
this.webhookMessage = webhookMessage;
|
||||
this.channelId = channelId;
|
||||
this.id = id;
|
||||
}
|
||||
@ -238,6 +227,21 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull @Unmodifiable List<DiscordMessageEmbed> getEmbeds() {
|
||||
return embeds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWebhookMessage() {
|
||||
return webhookMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getJumpUrl() {
|
||||
return String.format(
|
||||
@ -299,12 +303,12 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
||||
return CompletableFutureUtil.failed(new RestErrorResponseException(ErrorResponse.UNKNOWN_CHANNEL));
|
||||
}
|
||||
|
||||
return textChannel.deleteMessageById(getId(), fromSelf && getWebhookUsername().isPresent());
|
||||
return textChannel.deleteMessageById(getId(), fromSelf && webhookMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<ReceivedDiscordMessage> edit(SendableDiscordMessage message) {
|
||||
if (!isWebhookMessage() && message.isWebhookMessage()) {
|
||||
if (!webhookMessage && message.isWebhookMessage()) {
|
||||
throw new IllegalArgumentException("Cannot edit a non-webhook message into a webhook message");
|
||||
}
|
||||
|
||||
|
@ -269,8 +269,7 @@ public class DiscordMessageMirroringModule extends AbstractModule<DiscordSRV> {
|
||||
|
||||
ReceivedDiscordMessage replyMessage = message.getReplyingTo().orElse(null);
|
||||
String content = message.getContent()
|
||||
.map(c -> c.replace("[", "\\[")) // Block markdown urls
|
||||
.orElse("");
|
||||
.replace("[", "\\["); // Block markdown urls
|
||||
|
||||
if (replyMessage != null) {
|
||||
MessageReference matchingReference = null;
|
||||
|
@ -52,7 +52,7 @@ dependencyResolutionManagement {
|
||||
library('findbugs-annotations', 'com.google.code.findbugs', 'jsr305').version('3.0.2')
|
||||
|
||||
// JDA
|
||||
library('jda', 'net.dv8tion', 'JDA').version('5.0.0-alpha.11')
|
||||
library('jda', 'net.dv8tion', 'JDA').version('5.0.0-alpha.13')
|
||||
library('okhttp', 'com.squareup.okhttp3', 'okhttp').version {
|
||||
prefer '3.12.13'
|
||||
reject '[4,)' // Kotlin
|
||||
|
Loading…
Reference in New Issue
Block a user