Anslean
Anslean

Reputation: 41

How can I re-enable a button in Discord.Net after it's already been built?

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

Answers (1)

Anslean
Anslean

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

Related Questions