Skip to content

Commit 40fc3b5

Browse files
committed
autocomplete and modals for /config set
1 parent 271070b commit 40fc3b5

File tree

4 files changed

+98
-12
lines changed

4 files changed

+98
-12
lines changed

src/main/java/net/javadiscord/javabot/systems/configuration/ConfigSubcommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import xyz.dynxsty.dih4jda.interactions.commands.application.SlashCommand;
44
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
5-
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
5+
import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction;
66
import net.javadiscord.javabot.data.config.BotConfig;
77
import net.javadiscord.javabot.data.config.GuildConfig;
88
import net.javadiscord.javabot.data.config.UnknownPropertyException;
@@ -44,5 +44,5 @@ public void execute(@NotNull SlashCommandInteractionEvent event) {
4444
}
4545
}
4646

47-
protected abstract ReplyCallbackAction handleConfigSubcommand(@Nonnull SlashCommandInteractionEvent event, @Nonnull GuildConfig config) throws UnknownPropertyException;
47+
protected abstract InteractionCallbackAction<?> handleConfigSubcommand(@Nonnull SlashCommandInteractionEvent event, @Nonnull GuildConfig config) throws UnknownPropertyException;
4848
}

src/main/java/net/javadiscord/javabot/systems/configuration/ExportConfigSubcommand.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public class ExportConfigSubcommand extends ConfigSubcommand {
2222
public ExportConfigSubcommand(BotConfig botConfig) {
2323
super(botConfig);
2424
setCommandData(new SubcommandData("export", "Exports a list of all configuration properties, and their current values."));
25-
setRequiredUsers(botConfig.getSystems().getAdminConfig().getAdminUsers());
2625
}
2726

2827
@Override

src/main/java/net/javadiscord/javabot/systems/configuration/GetConfigSubcommand.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public GetConfigSubcommand(BotConfig botConfig) {
2525
setCommandData(new SubcommandData("get", "Get the current value of a configuration property.")
2626
.addOption(OptionType.STRING, "property", "The name of a property.", true)
2727
);
28-
setRequiredUsers(botConfig.getSystems().getAdminConfig().getAdminUsers());
2928
}
3029

3130
@Override
Lines changed: 96 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,132 @@
11
package net.javadiscord.javabot.systems.configuration;
22

3+
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
4+
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
35
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
6+
import net.dv8tion.jda.api.interactions.AutoCompleteQuery;
7+
import net.dv8tion.jda.api.interactions.commands.Command;
8+
import net.dv8tion.jda.api.interactions.commands.Command.Choice;
49
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
510
import net.dv8tion.jda.api.interactions.commands.OptionType;
611
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
7-
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
12+
import net.dv8tion.jda.api.interactions.components.text.TextInput;
13+
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
14+
import net.dv8tion.jda.api.interactions.modals.Modal;
15+
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
16+
import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction;
17+
import net.javadiscord.javabot.annotations.AutoDetectableComponentHandler;
818
import net.javadiscord.javabot.data.config.BotConfig;
919
import net.javadiscord.javabot.data.config.GuildConfig;
1020
import net.javadiscord.javabot.data.config.UnknownPropertyException;
1121
import net.javadiscord.javabot.util.Responses;
22+
import xyz.dynxsty.dih4jda.interactions.AutoCompletable;
23+
import xyz.dynxsty.dih4jda.interactions.components.ModalHandler;
24+
import xyz.dynxsty.dih4jda.util.AutoCompleteUtils;
25+
import xyz.dynxsty.dih4jda.util.ComponentIdBuilder;
26+
27+
import java.lang.reflect.Field;
28+
import java.lang.reflect.Modifier;
29+
import java.util.Arrays;
30+
import java.util.List;
31+
import java.util.stream.Collectors;
1232

1333
import javax.annotation.Nonnull;
1434

1535
/**
1636
* Subcommand that allows staff-members to edit the bot's configuration.
1737
*/
18-
public class SetConfigSubcommand extends ConfigSubcommand {
38+
@AutoDetectableComponentHandler("config-set")
39+
public class SetConfigSubcommand extends ConfigSubcommand implements ModalHandler, AutoCompletable {
1940
/**
2041
* The constructor of this class, which sets the corresponding {@link SubcommandData}.
2142
* @param botConfig The main configuration of the bot
2243
*/
2344
public SetConfigSubcommand(BotConfig botConfig) {
2445
super(botConfig);
2546
setCommandData(new SubcommandData("set", "Sets the value of a configuration property.")
26-
.addOption(OptionType.STRING, "property", "The name of a property.", true)
27-
.addOption(OptionType.STRING, "value", "The value to set for the property.", true)
47+
.addOption(OptionType.STRING, "property", "The name of a property.", true, true)
48+
.addOption(OptionType.STRING, "value", "The value to set for the property.", false)
2849
);
29-
setRequiredUsers(botConfig.getSystems().getAdminConfig().getAdminUsers());
3050
}
3151

3252
@Override
33-
public ReplyCallbackAction handleConfigSubcommand(@Nonnull SlashCommandInteractionEvent event, @Nonnull GuildConfig config) throws UnknownPropertyException {
53+
public InteractionCallbackAction<?> handleConfigSubcommand(@Nonnull SlashCommandInteractionEvent event, @Nonnull GuildConfig config) throws UnknownPropertyException {
3454
OptionMapping propertyOption = event.getOption("property");
3555
OptionMapping valueOption = event.getOption("value");
36-
if (propertyOption == null || valueOption == null) {
56+
if (propertyOption == null) {
3757
return Responses.replyMissingArguments(event);
3858
}
3959
String property = propertyOption.getAsString().trim();
60+
GuildConfig guildConfig = botConfig.get(event.getGuild());
61+
if (valueOption == null) {
62+
Object resolved = guildConfig.resolve(property);
63+
if (resolved == null) {
64+
return Responses.error(event, "Config `%s` not found", property);
65+
}
66+
return event.replyModal(
67+
Modal.create(ComponentIdBuilder.build("config-set", property), "Change configuration value")
68+
.addActionRow(TextInput.create("value", "new value", TextInputStyle.PARAGRAPH)
69+
.setValue(String.valueOf(resolved))
70+
.build())
71+
.build());
72+
}
4073
String valueString = valueOption.getAsString().trim();
41-
botConfig.get(event.getGuild()).set(property, valueString);
74+
guildConfig.set(property, valueString);
4275
return Responses.success(event, "Configuration Updated", "The property `%s` has been set to `%s`.", property, valueString);
4376
}
77+
78+
@Override
79+
public void handleModal(ModalInteractionEvent event, List<ModalMapping> values) {
80+
String[] id = ComponentIdBuilder.split(event.getModalId());
81+
String property = id[1];
82+
String valueString = event.getValue("value").getAsString();
83+
GuildConfig guildConfig = botConfig.get(event.getGuild());
84+
try {
85+
guildConfig.set(property, valueString);
86+
Responses.success(event, "Configuration Updated", "The property `%s` has been set to `%s`.", property, valueString).queue();
87+
} catch (UnknownPropertyException e) {
88+
Responses.error(event, "Property not found: %s", property).queue();
89+
}
90+
}
91+
92+
@Override
93+
public void handleAutoComplete(CommandAutoCompleteInteractionEvent event, AutoCompleteQuery target) {
94+
if (target.getName().equals("property")) {
95+
String partialText = target.getValue();
96+
int lastDot = partialText.lastIndexOf('.');
97+
String parentPropertyName;
98+
String childPropertyName;
99+
if (lastDot == -1) {
100+
parentPropertyName = "";
101+
childPropertyName = partialText;
102+
} else {
103+
parentPropertyName = partialText.substring(0,lastDot);
104+
childPropertyName = partialText.substring(lastDot+1);
105+
}
106+
107+
GuildConfig guildConfig = botConfig.get(event.getGuild());
108+
try {
109+
Object resolved;
110+
if(parentPropertyName.isEmpty()) {
111+
resolved = guildConfig;
112+
} else {
113+
resolved = guildConfig.resolve(parentPropertyName);
114+
}
115+
if (resolved == null || !resolved.getClass().getPackageName().startsWith(GuildConfig.class.getPackageName())) {
116+
event.replyChoices().queue();
117+
return;
118+
}
119+
List<Choice> choices = Arrays.stream(resolved.getClass().getDeclaredFields())
120+
.filter(f -> !Modifier.isTransient(f.getModifiers()))
121+
.map(Field::getName)
122+
.map(name -> parentPropertyName.isEmpty() ? name : parentPropertyName+"."+name)
123+
.map(name -> new Command.Choice(name, name))
124+
.collect(Collectors.toList());
125+
126+
event.replyChoices(AutoCompleteUtils.filterChoices(childPropertyName, choices)).queue();
127+
} catch (UnknownPropertyException e) {
128+
event.replyChoices().queue();
129+
}
130+
}
131+
}
44132
}

0 commit comments

Comments
 (0)