chore: apps/site/ > site/

This commit is contained in:
Skillz4Killz
2023-02-20 21:20:54 +00:00
parent 5f6a111492
commit 8536fc7150
110 changed files with 4 additions and 4 deletions

View File

@@ -0,0 +1,4 @@
{
"label": "Structures",
"position": 7
}

View File

@@ -0,0 +1,55 @@
---
sidebar_position: 5
---
# Create Collectors
Some of your commands or features are sometimes based on user interactions. E.g. if a user presses a button and you want
to know whether it was pressed. This is actually done by listening to the `interactionCreate` event.
But sometimes you need to access locale variables or don't want to "hardcode" the part.
That's why it's sometimes recommended to create collectors.
Collectors are listeners that listen to a specific event. In addition, you can provide a filter, so you only receive
certain interactions.
## Use a Collector
:::note Template The template code is used below. You must have the EventManager part to use the collector feature. :::
We have a pre-made class for collectors which you can find
[here](https://github.com/meister03/discordeno.js/blob/master/Util/Collectors.js).
```js
const Discord = require("discordeno.js");
const filter = (m) => m.data?.customId === "warn_modal" && m.user.id === interaction.user.id;
const listener = client.eventListener; // When the eventListener property is named different
const collector = new Discord.Collector("interactionCreate", {
client: client,
timeout: 60000,
filter,
max: 20,
listener,
});
collector.on("collect", (m) => {
const interaction = client.interactions.forge(m);
// Stop Collector
// collector.stop();
});
// Fires on a timeout, when the collector has reached the max amount of interactions or when it has been closed
collector.on("end", (collected) => {
// Map of Collected Interactions
console.log(collected);
});
```
As you can see, this opens up many possibilities. You can listen to any event and get the interaction you need.
### Collector Options
`filter`: Function, just fire the event if the filter returns true. `timeout`: Number, the time in milliseconds until
the collector times out. `max`: Number, the max amount of interactions the collector can collect. `listener`: Function,
the listener that will be fired when the collector collects an interaction. Just required when client property is named
differently.

View File

@@ -0,0 +1,223 @@
---
sidebar_position: 4
---
# Create Components
Since Discord has decided to make message content accessible only to privileged bots, components will play an
increasingly important role in the future. Discord has released some components already and many more will follow. Of
course, this opens up completely new possibilities. On the one hand, it improves the user experience and on the other
hand, the interactions can be easily handled by the developer.
To take advantage of this, we'll go into more detail on how to use them.
:::note Runtime Overhead
Constructor classes are nice to use and make your code look better, but they incur a slight runtime overhead compared to
just using raw data because they still execute methods, which takes more time to process.
:::
We already have a Template for `Components`, which can be found
[here](https://github.com/meister03/discordeno.js/tree/master/Structures/Component.js).
## Different Components:
There are many different components, which you can quickly read about here:
### Action Row (`type: 1`):
This is a top level component, which contains a limited amount of other components. It can be described as container.
An Action Row ...
- can not include an action row
- can maximal have 5 Buttons
- can have 1 SelectMenu
- can have 1 Text Input (only available in modal responses)
### Button (`type: 2`):
Buttons are interactive components, are bound to a message and they sent an interaction payload, when a user clicks on
it.
![Different Button Styles](https://i.imgur.com/jUE2Kp0.png)
- Needs a customId, except the Link Button
- An Action Row can have maximal 5 Buttons
There are different styles of buttons, which can be used:
- `1` - PRIMARY - blurple - customId required
- `2` - DEFAULT - grey - customId required
- `3` - SUCCESS - green - customId required
- `4` - DANGER - red - customId required
- `5` - LINK - grey - url required
### Select Menu (`type: 3`):
Select Menus are a simple drop-down with selectable options. They accept a set of allowed selects, which sends an
interaction payload, when a user selects sth. from the menu.
![Select Menu](https://i.imgur.com/42Hwiuw.png)
- You can specify a range of allowed selects (`minValue` and `maxValue`)
- Every Select Item can have an `emoji` and has a `value`, in order to identify the selected item
- A default Select Item can be set
- An Action Row can have maximal 1 Select Menu
### Text Input (`type: 4`):
Text Inputs are interactive components, which can just be sent with a modal response.
- You can specify a range of text length (`minLength` and `maxLength`)
- You can add a placeholder, a pre-filled value and specify whether the text input is required
- An Action Row can have maximal 1 Text Input
## Send Components
As mentioned above there are different types of components. This requires to define a type, so that Discord knows, which
component you want to use.
```js
class ActionRow {
constructor(options = {}) {
this.type = 1;
}
setComponents(...components) {
this.components = components;
return this;
}
}
```
```js
const button = new Button();
const button2 = new Button();
const actionRow = new ActionRow().setComponents(button, button2);
```
This code will obviously not work because it's a missing a lot required of data. The other reason is that we can't send
a class to Discord, we need sth. to transform it to a json object.
We have a pre-made class for components which you can find
[here](https://github.com/meister03/discordeno.js/tree/master/Structures/Component.js).
### Button
```js
const Discord = require("discordeno.js");
const message = client.messages.forge(rawMessage);
const button = new Discord.Component()
.setType("BUTTON")
.setStyle("LINK")
.setLabel("Click me!")
.setUrl("https://google.com")
.toJSON();
// Button with raw types
const button2 = new Discord.Component()
.setType(2)
.setStyle(4)
.setLabel("DO NOT CLICK")
.setCustomId("12345")
.toJSON();
const actionRow = new Discord.Component()
.setType("ACTION_ROW")
.setComponents(button, button2)
.toJSON();
// Message to send
const messageOptions = { content: "hello", components: [actionRow] };
// await client.helpers.sendMessage(channelId, messageOptions); // Do it the raw way
message.channel.send(messageOptions); // Do it with the structure
```
As you can see, for simplicity you can use strings instead of numbers (types), which are hard to remember.
### Select Menu
```js
const Discord = require("discordeno.js");
const message = client.messages.forge(rawMessage);
const selectMenu = new Discord.Component()
.setType("SELECT_MENU")
.setCustomId("12345")
.setOptions([
{
label: "Option 1",
value: "1",
description: `This is option 1`,
},
{
label: "Option 2",
value: "2",
description: `This is option 2`,
},
{
label: "Default Option",
value: "3",
description: `Default option...`,
default: true,
},
])
.setPlaceholder("Select an option")
.toJSON();
const actionRow = new Discord.Component()
.setType("ACTION_ROW")
.setComponents(selectMenu)
.toJSON();
const messageOptions = { content: "hello", components: [actionRow] };
// await client.helpers.sendMessage(channelId, messageOptions); // Do it the raw way
message.channel.send(messageOptions); // Do it with the structure
```
### Text Input
```js
const Discord = require("discordeno.js");
const interaction = client.messages.forge(rawInteraction);
const textInput = new Component()
.setType("TEXT_INPUT")
.setStyle("SHORT")
.setCustomId("t1")
.setLabel("User ID")
.setPlaceholder("User ID")
.setRequired(true)
.setMaxLength(20)
.setMinLength(1)
.toJSON();
const textInput2 = new Component()
.setType("TEXT_INPUT")
.setStyle("PARAGRAPH")
.setCustomId("t2")
.setLabel("Reason")
.setPlaceholder("Reason for Ban")
.setRequired(false)
.setMaxLength(300)
.toJSON();
const actionRow = new Component().setType("ACTION_ROW").setComponents(textInput).toJSON();
const actionRow2 = new Component().setType("ACTION_ROW").setComponents(textInput2).toJSON();
interaction.popupModal({
customId: "ban_modal",
title: "Ban User",
components: [actionRow, actionRow2],
});
```
### Receive Interactions
When a user clicks a button or selects an option from a Select Menu, Discord sends an `interactionCreate` event, which
contains the information necessary to process it.

View File

@@ -0,0 +1,100 @@
---
sidebar_position: 2
---
# Create Structure
Structures are often used to transform data and add methods to existing objects. To make it easier to work with them.
Imagine you have a channel object to which you want to send a message.
```js
const data = {
id: 806947972004839444n,
name: "spam-and-bots",
};
```
The recommended way would be:
```js
await client.helpers.sendMessage(data.id, { content: "hello" });
```
However, you probably want to use something shorter, such as the following:
```js
class Channel {
constructor(client, data) {
this.client = client;
this.id = data.id;
this.name = data.name;
}
async send(options) {
return await this.client.helpers.sendMessage(this.id, options);
}
}
```
Now you can use the `.send()` method on the channel object without using such a long code:
```js
const channel = new Channel(client, data);
await channel.send({ content: "hello" });
```
Moreover, you can modify the `.send()` method to better suit your use case e.g not send the message if the channel is
blacklisted.
This naturally opens a lot of opportunities and makes coding a lot easier. Because you decide what you want to do with
the data, how the methods are named and how you want to process the request.
## Using Template Structures:
When you are migrating from another library and you want to utilize the djs-like wrapper, you'll likely choose to
continue using special structures. Therefore we have ready-made structures for the wrapper `Discordeno.js`.
- [Guild](https://github.com/meister03/discordeno.js/tree/master/Structures/Guild.js)
- [Channel](https://github.com/meister03/discordeno.js/tree/master/Structures/Channel.js)
- [Role](https://github.com/meister03/discordeno.js/tree/master/Structures/Role.js)
- [Member](https://github.com/meister03/discordeno.js/tree/master/Structures/Member.js)
- [User](https://github.com/meister03/discordeno.js/tree/master/Structures/User.js)
- [Message](https://github.com/meister03/discordeno.js/tree/master/Structures/Message.js)
- [Interaction](https://github.com/meister03/discordeno.js/tree/master/Structures/Interaction.js)
- [Emoji](https://github.com/meister03/discordeno.js/tree/master/Structures/Emoji.js)
- [Webhook](https://github.com/meister03/discordeno.js/tree/master/Structures/Webhook.js)
- [Embed](https://github.com/meister03/discordeno.js/tree/master/Structures/Embed.js)
- [Component](https://github.com/meister03/discordeno.js/tree/master/Structures/Component.js)
- [Collection](https://github.com/meister03/discordeno.js/tree/master/Structures/Collection.js)
We recommend that you check the wrappers [Readme](https://github.com/meister03/discordeno.js#discordclient) in order to
construct the client for following the Guide
**Using the Structures:**
```js
const Discord = require("discordeno.js");
const client = new Discord.Client(clientOptions, cacheOptions); //See the Readme above
Discord.startBot(client);
const guild = client.guilds.forge(guildData);
const channel = guild.channels.forge(channelData);
const role = guild.roles.forge(roleData);
const member = guild.members.forge(memberData);
const user = guild.users.forge(userData);
const message = guild.messages.forge(messageData);
const interaction = guild.interactions.forge(interactionData);
const emoji = guild.emojis.forge(emojiData);
const webhook = new Discord.Webhook(client, webhookData);
const embed = new Discord.Embed(embedData); // embedData is optional
const component = new Discord.Component(componentData); // componentData is optional
const collection = new Discord.Collection();
```
Some popular methods have been added to the structures so that you can use them without having to come up with your own.
In order to use the Structures from the Wrapper, you need to invoke the `.forge` method with the raw discord data,
whereas it will construct the structure for you.
Next we're going to give a better insight into how create [`Embeds`](embeds) and [`Components`](components) with the
wrappers structures.

View File

@@ -0,0 +1,106 @@
---
sidebar_position: 3
---
# Create Embeds
Embeds are widely used by bots in order to display messages in a fancy way.
Unfortunately, the Discord API does not accept funky classes such as `new MessageEmbed().setTitle("hello")`, instead it
takes a json object, e.g. `{ title: "hello" }`. Therefore, we need to create an embed Structure that converts the
user-supplied data into the format which Discord uses.
:::note Runtime Overhead
Constructor classes are nice to use and make your code look better, but they incur a slight runtime overhead compared to
just using raw data because they still execute methods, which takes more time to process.
:::
```js
class Embed() {
constructor() {}
setTitle(title) {
this.title = title;
}
}
```
Now we have created a class which we can use to create embeds. But we can't just send this to Discord.
So we need an additional method which will convert the data from the class to the correct format.
```js
class Embed(){
constructor() {}
setTitle(title) {
this.title = title;
}
toJSON() {
return {
title: this.title
}
}
}
```
Wow, now you can create a embed and send it to Discord.
```js
const Channel = require("./structures/Channel"); // Path to structure
const channel = new Channel(client, data);
await channel.send({ embeds: [embed] });
```
You probably want more methods which you can use to create embeds.
[Here is how the Embed Structure looks like](https://github.com/meister03/discordeno.js/blob/master/Structures/Embed.js)
### Using the Embed Structure:
```js
const Discord = require("discordeno.js");
const channel = client.channels.forge(channelData);
const showCaseEmbed = new Discord.Embed()
.setColor(0x00AE86)
.setTitle("A Random Title")
.setURL("https://github.com/discordeno")
.setAuthor({
name: "Author name",
iconUrl: "https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png",
url: "https://github.com/discordeno",
})
.setDescription("A Random Description")
.setThumbnail("https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png")
.addFields(
{ name: "Field 1 Name", value: "Normal Field Value" },
{ name: "\u200B", value: "\u200B" },
{ name: "Field 2 Name", value: "Inline Field Value", inline: true },
{ name: "Field 3 Name", value: "Inline Field Value", inline: true },
)
.addField({ name: "Field 4", value: "Field Value" })
.setImage("https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png")
.setTimestamp()
.setFooter({
text: "A Footer Text",
iconUrl: "https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png",
})
.toJSON();
await channel.send({ embeds: [showCaseEmbed] });
```
### Embed Limits:
- Title: 256 characters
- Description: 4096 characters
- Field Name: 256 characters
- Field Value: 1024 characters
- Footer Text: 2048 characters
- Author Name: 256 characters
- 10 Embeds per message
- In total over all 10 Embeds not more than 6000 characters

View File

@@ -0,0 +1,30 @@
---
sidebar_position: 1
---
# Getting Started with Structures
As previously mentioned, Discordeno was built with as few classes as possible, this is in favor of performance.
For example, you cannot execute functions on objects.
```diff
- message.channel.send({content: "hello"})
+ client.helpers.sendMessage(message.channel.id, {content: "hello"})
```
This seems to be more complicated at first, but has many advantages:
- You get full control over the actions
- Errors are easier to debug
- A validation by classes does not have to take place
One of the disadvantages is that you have to change a lot in your code.
Of course, we recommend that you try out the upper way, but we will introduce structures in this guide because they are
used by many users who eventually want to migrate.
For example, if you want to get correctly formatted objects, structures are obviously beneficial, because they support
the readability of the code by their ease of use
In the following, we will introduce how to create your own structures and how to use the ones available in the template.