Browse Source

Add component docs and few SOL changes to components

pull/1923/head
quin lynch 3 years ago
parent
commit
4efc907bf2
34 changed files with 325 additions and 0 deletions
  1. +0
    -0
      docs/guides/interactions/application-commands/01-getting-started.md
  2. +0
    -0
      docs/guides/interactions/application-commands/context-menu-commands/creating-context-menu-commands.md
  3. +0
    -0
      docs/guides/interactions/application-commands/context-menu-commands/receiving-context-menu-command-events.md
  4. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/02-creating-slash-commands.md
  5. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/03-responding-to-slash-commands.md
  6. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/04-parameters.md
  7. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/05-responding-ephemerally.md
  8. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/06-subcommands.md
  9. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/07-choice-slash-command.md
  10. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/README.md
  11. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/ephemeral1.png
  12. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/feedback1.png
  13. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/feedback2.png
  14. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/listroles1.png
  15. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/listroles2.png
  16. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/oauth.png
  17. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/settings1.png
  18. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/settings2.png
  19. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/settings3.png
  20. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/slashcommand1.png
  21. +0
    -0
      docs/guides/interactions/application-commands/slash-commands/images/slashcommand2.png
  22. +61
    -0
      docs/guides/interactions/message-components/01-getting-started.md
  23. +54
    -0
      docs/guides/interactions/message-components/02-responding-to-buttons.md
  24. +40
    -0
      docs/guides/interactions/message-components/03-buttons-in-depth.md
  25. +71
    -0
      docs/guides/interactions/message-components/04-select-menus.md
  26. +75
    -0
      docs/guides/interactions/message-components/05-advanced.md
  27. BIN
      docs/guides/interactions/message-components/images/image1.png
  28. BIN
      docs/guides/interactions/message-components/images/image2.png
  29. BIN
      docs/guides/interactions/message-components/images/image3.png
  30. BIN
      docs/guides/interactions/message-components/images/image4.png
  31. BIN
      docs/guides/interactions/message-components/images/image5.png
  32. BIN
      docs/guides/interactions/message-components/images/image6.png
  33. +9
    -0
      src/Discord.Net.Core/Entities/Interactions/Message Components/ButtonComponent.cs
  34. +15
    -0
      src/Discord.Net.Core/Entities/Interactions/Message Components/SelectMenu.cs

docs/guides/application-commands/01-getting-started.md → docs/guides/interactions/application-commands/01-getting-started.md View File


docs/guides/application-commands/context-menu-commands/creating-context-menu-commands.md → docs/guides/interactions/application-commands/context-menu-commands/creating-context-menu-commands.md View File


docs/guides/application-commands/context-menu-commands/receiving-context-menu-command-events.md → docs/guides/interactions/application-commands/context-menu-commands/receiving-context-menu-command-events.md View File


docs/guides/application-commands/slash-commands/02-creating-slash-commands.md → docs/guides/interactions/application-commands/slash-commands/02-creating-slash-commands.md View File


docs/guides/application-commands/slash-commands/03-responding-to-slash-commands.md → docs/guides/interactions/application-commands/slash-commands/03-responding-to-slash-commands.md View File


docs/guides/application-commands/slash-commands/04-parameters.md → docs/guides/interactions/application-commands/slash-commands/04-parameters.md View File


docs/guides/application-commands/slash-commands/05-responding-ephemerally.md → docs/guides/interactions/application-commands/slash-commands/05-responding-ephemerally.md View File


docs/guides/application-commands/slash-commands/06-subcommands.md → docs/guides/interactions/application-commands/slash-commands/06-subcommands.md View File


docs/guides/application-commands/slash-commands/07-choice-slash-command.md → docs/guides/interactions/application-commands/slash-commands/07-choice-slash-command.md View File


docs/guides/application-commands/slash-commands/README.md → docs/guides/interactions/application-commands/slash-commands/README.md View File


docs/guides/application-commands/slash-commands/images/ephemeral1.png → docs/guides/interactions/application-commands/slash-commands/images/ephemeral1.png View File


docs/guides/application-commands/slash-commands/images/feedback1.png → docs/guides/interactions/application-commands/slash-commands/images/feedback1.png View File


docs/guides/application-commands/slash-commands/images/feedback2.png → docs/guides/interactions/application-commands/slash-commands/images/feedback2.png View File


docs/guides/application-commands/slash-commands/images/listroles1.png → docs/guides/interactions/application-commands/slash-commands/images/listroles1.png View File


docs/guides/application-commands/slash-commands/images/listroles2.png → docs/guides/interactions/application-commands/slash-commands/images/listroles2.png View File


docs/guides/application-commands/slash-commands/images/oauth.png → docs/guides/interactions/application-commands/slash-commands/images/oauth.png View File


docs/guides/application-commands/slash-commands/images/settings1.png → docs/guides/interactions/application-commands/slash-commands/images/settings1.png View File


docs/guides/application-commands/slash-commands/images/settings2.png → docs/guides/interactions/application-commands/slash-commands/images/settings2.png View File


docs/guides/application-commands/slash-commands/images/settings3.png → docs/guides/interactions/application-commands/slash-commands/images/settings3.png View File


docs/guides/application-commands/slash-commands/images/slashcommand1.png → docs/guides/interactions/application-commands/slash-commands/images/slashcommand1.png View File


docs/guides/application-commands/slash-commands/images/slashcommand2.png → docs/guides/interactions/application-commands/slash-commands/images/slashcommand2.png View File


+ 61
- 0
docs/guides/interactions/message-components/01-getting-started.md View File

@@ -0,0 +1,61 @@
# Message Components

Message components are a framework for adding interactive elements to a message your app or bot sends. They;re accessible, customizable, and easy to use.

## What is a Component

Components are a new parameter you can use when sending messages with your bot. There are currently 2 different types of components you can use: Buttons and Select Menus.

## Creating components

Lets create a simple component that has a button. First thing we need is a way to trigger the message, this can be done via commands or simply a ready event. Lets make a command that triggers our button message.

```cs
[Command("spawner")]
public async Task Spawn()
{
// Reply with some components
}
```

We now have our command, but we need to actually send the buttons with the command. To do that, lets look at the `ComponentBuilder` class:

| Name | Description |
| ---------------- | --------------------------------------------------------------------------- |
| `FromMessage` | Creates a new builder from a message. |
| `FromComponents` | Creates a new builder from the provided list of components. |
| `WithSelectMenu` | Adds a `SelectMenuBuilder` to the `ComponentBuilder` at the specific row. |
| `WithButton` | Adds a `ButtonBuilder` to the `ComponentBuilder` at the specific row. |
| `Build` | Builds this builder into a `MessageComponent` used to send your components. |

We see that we can use the `WithButton` function so lets do that. looking at its parameters it takes:

- `label` - The display text of the button.
- `customId` - The custom id of the button, this is whats sent by discord when your button is clicked.
- `style` - The discord defined style of the button.
- `emote` - An emote to be displayed with the button.
- `url` - The url of the button if its a link button.
- `disabled` - Whether or not the button is disabled.
- `row` - The row the button will occupy.

Since were just making a busic button, we dont have to specify anything else besides the label and custom id.

```cs
var builder = new ComponentBuilder()
.WithButton("label", "custom-id");
```

Lets add this to our command:

```cs
[Command("spawner")]
public async Task Spawn()
{
var builder = new ComponentBuilder()
.WithButton("label", "custom-id");

await ReplyAsync("Here is a button!", components: builder.Build());
}
```

![](images\image1.png)

+ 54
- 0
docs/guides/interactions/message-components/02-responding-to-buttons.md View File

@@ -0,0 +1,54 @@
# Responding to button clicks

Responding to buttons is pretty simple, there are a couple ways of doing it and we can cover both.

### Method 1: Hooking the InteractionCreated Event

We can hook the `InteractionCreated` event since button clicks are a form of interactions:

```cs
client.IntreactionCreated += MyInteractionHandler;
```

Now, lets write our handler.

```cs
public async Task MyInteractionHandler(SocketInteraction arg)
{
// first we check the type of the interaction, this can be done with a switch statement
switch(arg)
{
case SocketMessageComponent component:
// we now have a variable defined as 'component' which contains our component data, lets pass it to a different handler.

break;
}
}

public async Task MyButtonHandler(SocketMessageComponent component)
{
// We can now check for our custom id
switch(component.Data.CustomId)
{
// Since we set our buttons custom id as 'custom-id', we can check for it like this:
case "custom-id":
// Lets respond by sending a message saying they clicked the button
await component.RespondAsync($"{component.User.Mention} has clicked the button!");
break;
}
}
```

Running it and clicking the button:

![](Images/image2.png)

### Method 2: Hooking the ButtonExecuted Event

This method skips the first switch statement because the `ButtonExecuted` event is only fired when a button is clicked, meaning we dont have to check the type of the interaction.

```cs
client.ButtonExecuted += MyButtonHandler;
```

The rest of the code is the same and produces the same result.

+ 40
- 0
docs/guides/interactions/message-components/03-buttons-in-depth.md View File

@@ -0,0 +1,40 @@
# Buttons in depth

There are many changes you can make to buttons, lets take a look at the parameters in the `WithButton` function"
| Name | Type | Description |
|----------|---------------|----------------------------------------------------------------|
| label | `string` | The label text for the button. |
| customId | `string` | The custom id of the button. |
| style | `ButtonStyle` | The style of the button. |
| emote | `IEmote` | A IEmote to be used with this button. |
| url | `string` | A URL to be used only if the `ButtonStyle` is a Link. |
| disabled | `bool` | Whether or not the button is disabled. |
| row | `int` | The row to place the button if it has enough room, otherwise 0 |

### Label

This is the front facing text that the user sees. The maximum length is 80 characters.

### CustomId

This is the property sent to you by discord when a button is clicked. It is not required for link buttons as they do not emit an event. The maximum length is 100 characters.

### Style

Styling your buttons are important for indicating different actions:

![](Images/image3.png)

You can do this by using the `ButtonStyle` which has all the styles defined.

### Emote

You can specify an `IEmote` when creating buttons to add them to your button. They have the same restrictions as putting guild based emotes in messages.

### Url

If you use the link style with your button you can specify a url. When this button is clicked the user is taken to that url.

### Disabled

You can specify if your button is disabled, meaning users won't be able to click on it.

+ 71
- 0
docs/guides/interactions/message-components/04-select-menus.md View File

@@ -0,0 +1,71 @@
# Select menus

Select menus allow users to select from a range of options, this can be quite useful with configuration commands etc.

## Creating a select menu

We can use a `SelectMenuBuilder` to create our menu.

```cs
var menuBuilder = new SelectMenuBuilder()
.WithPlaceholder("Select an option")
.WithCustomId("menu-1")
.WithMinValues(1)
.WithMaxValues(1)
.AddOption("Option A", "opt-a", "Option B is lying!")
.AddOption("Option B", "opt-b", "Option A is telling the truth!");

var builder = new ComponentBuilder()
.WithSelectMenu(menuBuilder);
```

Lets add this to a command:

```cs
[Command("spawner")]
public async Task Spawn()
{
var menuBuilder = new SelectMenuBuilder()
.WithPlaceholder("Select an option")
.WithCustomId("menu-1")
.WithMinValues(1)
.WithMaxValues(1)
.AddOption("Option A", "opt-a", "Option B is lying!")
.AddOption("Option B", "opt-b", "Option A is telling the truth!");

var builder = new ComponentBuilder()
.WithSelectMenu(menuBuilder);

await ReplyAsync("Whos really lying?", components: builder.Build());
}
```

Running this produces this result:

![](Images/image4.png)

And opening the menu we see:

![](Images/image5.png)

Lets handle the selection of an option, as before we can hook the `InteractionCreated` event and check the type ourself but for this example im just going to use the `SelectMenuExecuted` event

```cs
client.SelectMenuExecuted += MyMenuHandler;
```

The `SelectMenuExecuted` also supplies a `SocketMessageComponent` argument, we can confirm that its a select menu by checking the `ComponentType` inside of the data field if we need, but the library will do that for us and only execute our handler if its a select menu.

The values that the user has selected will be inside of the `Values` collection in the Data field. we can list all of them back to the user for this example.

```cs
public async Task MyMenuHandler(SocketMessageComponent arg)
{
var text = string.Join(", ", arg.Data.Values);
await arg.RespondAsync($"You have selected {text}");
}
```

Running this produces this result:

![](Images/image6.png)

+ 75
- 0
docs/guides/interactions/message-components/05-advanced.md View File

@@ -0,0 +1,75 @@
# Advanced

Lets say you have some components on an ephemeral slash command, and you want to modify the message that the button is on. The issue with this is that ephemeral messages are not stored and can not be get via rest or other means.

Luckily, Discord thought of this and introduced a way to modify them with interactions.

### Using the UpdateAsync method

Components come with an `UpdateAsync` method that can update the message that the component was on. You can use it like a `ModifyAsync` method.

Lets use it with a command, we first create our command, in this example im just going to use a message command:

```cs
var command = new MessageCommandBuilder()
.WithName("testing").Build();

await client.GetGuild(guildId).BulkOverwriteApplicationCommandAsync(new [] { command, buttonCommand });
```

Next, we listen for this command, and respond with some components when its used:

```cs
var menu = new SelectMenuBuilder()
{
CustomId = "select-1",
Placeholder = "Select Somthing!",
MaxValues = 1,
MinValues = 1,
};

menu.AddOption("Meh", "1", "Its not gaming.")
.AddOption("Ish", "2", "Some would say that this is gaming.")
.AddOption("Moderate", "3", "It could pass as gaming")
.AddOption("Confirmed", "4", "We are gaming")
.AddOption("Excellent", "5", "It is renowned as gaming nation wide", new Emoji("🔥"));

var components = new ComponentBuilder()
.WithSelectMenu(menu);


await arg.RespondAsync("On a scale of one to five, how gaming is this?", component: componBuild(), ephemeral: true);
break;
```

Now, let's listen to the select menu executed event and add a case for `select-1`

```cs
switch (arg.Data.CustomId)
{
case "select-1":
var value = arg.Data.Values.First();
var menu = new SelectMenuBuilder()
{
CustomId = "select-1",
Placeholder = $"{(arg.Message.Components.First().Components.First() as SelectMenu).Options.FirstOrDefault(x => x.Value == value).Label}",
MaxValues = 1,
MinValues = 1,
Disabled = true
};

menu.AddOption("Meh", "1", "Its not gaming.")
.AddOption("Ish", "2", "Some would say that this is gaming.")
.AddOption("Moderate", "3", "It could pass as gaming")
.AddOption("Confirmed", "4", "We are gaming")
.AddOption("Excellent", "5", "It is renowned as gaming nation wide", new Emoji("🔥"));

// We use UpdateAsync to update the message and its original content and components.
await arg.UpdateAsync(x =>
{
x.Content = $"Thank you {arg.User.Mention} for rating us {value}/5 on the gaming scale";
x.Components = new ComponentBuilder().WithSelectMenu(menu).Build();
});
break;
}
```

BIN
docs/guides/interactions/message-components/images/image1.png View File

Before After
Width: 390  |  Height: 154  |  Size: 17 KiB

BIN
docs/guides/interactions/message-components/images/image2.png View File

Before After
Width: 413  |  Height: 100  |  Size: 19 KiB

BIN
docs/guides/interactions/message-components/images/image3.png View File

Before After
Width: 849  |  Height: 508  |  Size: 40 KiB

BIN
docs/guides/interactions/message-components/images/image4.png View File

Before After
Width: 584  |  Height: 161  |  Size: 20 KiB

BIN
docs/guides/interactions/message-components/images/image5.png View File

Before After
Width: 587  |  Height: 201  |  Size: 17 KiB

BIN
docs/guides/interactions/message-components/images/image6.png View File

Before After
Width: 620  |  Height: 288  |  Size: 38 KiB

+ 9
- 0
src/Discord.Net.Core/Entities/Interactions/Message Components/ButtonComponent.cs View File

@@ -48,6 +48,15 @@ namespace Discord
/// </summary>
public bool Disabled { get; }

/// <summary>
/// Turns this button into a button builder.
/// </summary>
/// <returns>
/// A newly created button builder with the same properties as this button.
/// </returns>
public ButtonBuilder ToBuilder()
=> new ButtonBuilder(this.Label, this.CustomId, this.Style, this.Url, this.Emote, this.Disabled);

internal ButtonComponent(ButtonStyle style, string label, IEmote emote, string customId, string url, bool disabled)
{
this.Style = style;


+ 15
- 0
src/Discord.Net.Core/Entities/Interactions/Message Components/SelectMenu.cs View File

@@ -44,6 +44,21 @@ namespace Discord
/// </summary>
public bool Disabled { get; }

/// <summary>
/// Turns this select menu into a builder.
/// </summary>
/// <returns>
/// A newly create builder with the same properties as this select menu.
/// </returns>
public SelectMenuBuilder ToBuilder()
=> new SelectMenuBuilder(
this.CustomId,
this.Options.Select(x => new SelectMenuOptionBuilder(x.Label, x.Value, x.Description, x.Emote, x.Default)).ToList(),
this.Placeholder,
this.MaxValues,
this.MinValues,
this.Disabled);

internal SelectMenu(string customId, List<SelectMenuOption> options, string placeholder, int minValues, int maxValues, bool disabled)
{
this.CustomId = customId;


Loading…
Cancel
Save