Reputation: 41
I created a disabled button in my Discord.Net application. I would like to re-enable it in response to some user interaction. I already know how to respond to user interaction, and I can even get ahold of the components I've added to the message. But there doesn't seem to be any method or editable attribute to re-enable the button. The documentation doesn't seem to indicate any way of doing so, but it seems like a highly useless feature to disable a button if it can never be enabled again. Is it possible? Or did Discord.Net fail to implement this part of the Discord API? I can't find the answer or even the question elsewhere in StackOverflow, or in video tutorials or other websites I tried when I googled the answer.
Code to disable:
private async Task MyTask(SocketInteraction command, Foo bar) {
SelectMenuBuilder menuBuilder = RecurringSelectMenus.ServerUsers(Client, com, "Select...", "select-menu");
ComponentBuilder builder = new();
builder.WithSelectMenu(menuBuilder, 0);
builder.WithButton("Perform Action", "my-button", disabled : true, row : 1);
try {
await command.RespondAsync($"Managing {bar.Name}:", components: builder.Build(), ephemeral: true);
} catch (HttpException e) {
Console.WriteLine(JsonConvert.SerializeObject(e.Errors, Formatting.Indented));
}
}
As you can see, I created my button and disabled it inline. In theory, I could do the following:
ButtonBuilder button = new();
button.WithDisabled(false);
and that would disable the button. However, this is all pre-build. Once I build the components (which I have to do to send the message), it fundamentally transforms into what I presume is a ButtonComponent
. However, when I respond to a user interaction with the message and retrieve my component (in the more abstract form of IMessageComponent
), there doesn't seem to be any disabling or enabling method regardless of whether I cast to ButtonComponent
, and the button.IsDisabled
attribute of ButtonComponent
is read-only. Any answers, solutions, or work-arounds would be greatly appreciated.
Upvotes: 0
Views: 212
Reputation: 41
I found a workaround. It seems really clunky, but then again maybe it was the intended method. Regardless, it's done by modifying the message and replacing all the components entirely. (For me that means rebuilding a select menu, but this time finding the selected value and setting it as a default since replacing the components will overwrite the selection. Those are the primary reasons I find this clunky.)
public async Task SelectOwnerForNewTeam(SocketMessageComponent component) {
SelectMenuBuilder menuBuilder = RecurringSelectMenus.ServerUsers(Client, component, "Select...", "select-menu");
SelectMenuOptionBuilder? selection = menuBuilder.Options.Find(o => o.Value == component.Data.Values.First()); // Get the selected option
if (selection != null) selection.IsDefault = true;
ComponentBuilder builder = new();
builder.WithSelectMenu(menuBuilder, 0);
builder.WithButton("Perform Action", "my-button", row : 1);
await component.DeferAsync(); // Must be done prior to modifying
await component.ModifyOriginalResponseAsync(msg => msg.Components = builder.Build());
}
This really doesn't feel like it should be the right answer, but I guess for now it is. I saw something similar to this in a Discord.js question, so maybe it's something about the Discord API that won't let you modify an individual component.
Upvotes: 1