19 |
20 | TODO: show how to make a bot account
21 |
22 | ## Project setup
23 |
24 | Now that you have your bot application you need to program and run it.
25 |
26 | First you will need to download and install [Node.JS](https://nodejs.org/en/download/). You might notice two different versions, LTS and Current. LTS means Long Term Support, it'll be supported for as long as the developers can. Current is the most stable version. There is also nightly builds which are previews of whats to come, these shouldn't be used as there's no guarantee it will function normally.
27 |
28 | Secondly you will need either a code editor or a IDE to edit the code. You can find some editors and IDEs [here](/topics/discordjs/#editors-and-ides). Some might require a add-on for syntax or linting support with JavaScript, if it does not it should prompt you to add it or you can search how to add it. Personally I use Visual Studio Code Insiders and **_will be throughout this guide_** but you're free to use any you like.
29 |
30 | Once you have both installed you can start setting up the project files by creating a new folder or use a existing one for the bot files to reside, you can name it anything you like. Next is to open the folder in your editor, usually this can be done by right-clicking the folder and selecting `Open with ` or clicking `File` at the top left in the editor and selecting `Open Folder`.
31 |
32 | After you have the editor open it's time to do the first step for any Node.JS project, creating a `package.json` and installing Node modules through the command line. If your editor has a integrated terminal you can open that, it does not or you prefer to use your OS terminal then you can open that. For Windows you can open the folder and click the path URL and write `cmd` and hit enter to open a Command Prompt. For Linux you usually can open the terminal from a dropdown button in the folder or right click in the empty space (TODO: improve this).
33 |
34 | Once you have a terminal open you can run your first command.
35 |
36 | ```shell
37 | npm init
38 | ```
39 |
40 | What is `npm` though? NPM is **N**ode.JS **P**ackage **M**anager that you can use to manage your projects packages or "dependencies" as it's called when your project "depends" on another. Here we are using the main command `npm` with a sub-command `init` which will run through a few questions and create a `package.json` file once complete. This file will store some basic information and dependencies. When you get a question it will look like `package name: (discordjs-tutorial)`, for some it will show parentheses and some content inside them, that is the default answer if you do not give one. Some wont have parentheses such as `description:` because it does not have a default answer, it's optional and can be left blank. You can edit any of this in the `package.json` later on.
41 |
42 | If you are curious about the other sub-commands you can look at [NPM's command line documentation](https://docs.npmjs.com/cli-documentation/cli) but we will only cover a few throughout this guide.
43 |
44 | After that process is finished you can now install a package.
45 |
46 | ```shell
47 | npm install discord.js
48 | ```
49 |
50 | As said before we are using the main command `npm` with a sub-command `install` and a package to install which is `discord.js`. You'll see the terminal fly through some lines and a new folder called `node_modules`, this is where your dependencies are stored to be used in your code.
51 |
52 | Next you can create a file named `index.js`, it must end in `.js` for two reasons, one for your editor to properly highlight the syntax, and two for Node.JS to know it's a JavaScript file.
53 |
54 | Congratulations, you've completed the first steps to making a Discord bot!
55 |
56 | ## Writing your first program
57 |
58 | Now that you have your project setup you can start coding. By being at this section you know at least the basics of [JavaScript and Node.JS](/topics/discordjs/#javascript-and-node-js), if not then I highly suggest you follow that hyperlink and read one of those resources. In this beginning part of this guide I will be explaining all the code I provide.
59 |
60 | Copy and paste this into your editor.
61 |
62 | ```javascript
63 | const { Client } = require("discord.js");
64 |
65 | const client = new Client();
66 |
67 | client.once("ready", () => console.log("I am ready!"));
68 |
69 | client.login("token");
70 | ```
71 |
72 | Replace `token` with your bot token found in the Discord Applications page when you created your bot and save the file. Next in your open terminal run this command.
73 |
74 | ```shell
75 | node index.js
76 | ```
77 |
78 | You should see the terminal show `I am ready!`. Congratulations, you just programmed your first Discord bot. But what does all of that do and what command is `node`?
79 |
80 | First I'll explain what the `node` command is. Every application on your computer has a main command, for Node.JS it's `node`, running this command with a JavaScript file will execute the code inside of it. If you do not like typing the command every time you can do two things, one is use `node .` which will use the `entry point` set in the `package.json`, by default it is `index.js`, if you named your file something else or it is in a sub directory you can rename that value accordingly. The other thing you can do is press the up arrow on your keyboard, this usually scrolls through the terminal history, you can use it to quickly get the command back and run it. There are other options like using `nodemon` to restart your program every time a file is saved but we'll get to that later on.
81 |
82 | Now what does all of that code do? If you know the basics of [JavaScript and Node.JS](/topics/discordjs/#javascript-and-node-js) you should understand some, if not most of it.
83 |
84 | The first line requires the `discord.js` module and assigns the deconstructed value `Client` by its name as a constant. `require` is only available in Node.JS and it can import files, [directories](https://stackoverflow.com/a/5365577/13257043) or modules. A constant is a variable that cannot be re-declared and must have a value assigned to it. Deconstructing is taking a value by name from a object and using it by itself, an is example below.
85 |
86 | ```javascript
87 | // Define a constant with a object as the value that has it's own property and value.
88 | const foo = { bar: "bar" };
89 |
90 | // Extract the foo variable and define it as its own.
91 | const { bar } = foo;
92 |
93 | // Print the variable to the terminal without doing "console.log(foo.bar)".
94 | console.log(bar) // bar
95 | ```
96 |
97 | I know that was big explanation so let's move to the second line. There you initiate the `Client` class and assign it to the `client` variable as a constant.
98 |
99 | The third line is a bit special, since you have to know when the bot is ready you need an event listener, thats what this line does. The `Client` class extends `EventEmitter` and lets you listen to events using `on` and `once` methods. Here we listen to the `ready` event which is sent every time your bot becomes ready, but since we don't want our terminal being spammed with messages so we'll use `once` so it only runs `once`. The second parameter is an inline [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) that prints a message to the console letting us know the bot is ready.
100 |
101 | The last line is a method that logins into the Discord WebSocket with your bot token to receive events and to make HTTP requests for sending message, adding roles, etc.
102 |
103 | Now that you understand what that snippet of code we can dive into more.
104 |
--------------------------------------------------------------------------------
/guide/topics/discordjs/tableOfContents.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Table of Contents
3 | ---
4 |
5 | Here are all of the available topics -
6 |
7 | - [Getting Started](gettingStarted.md) - The first steps to making a Discord bot.
8 | - [Creating your first command](firstCommand.md) - Learn how to create your first command.
9 |
--------------------------------------------------------------------------------
/guide/topics/erelajs/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction to Erela.js
3 | authors:
4 | - Solaris9
5 | - MenuDocs
6 | categories:
7 | - Javascript
8 | tags:
9 | - Erela.js
10 | - Bot Development
11 | ---
12 |
13 | ## What is Erela.js?
14 |
15 | Erela.js is a Lavalink client was made after seeing how others were made, most are bare bones and require the user to add much more complicated code.
16 |
17 | Erela.js is designed to be as easy to use and offer as many features as possible including easy to read documentation, easy overall usage, many events to listen to, extendable classes and plugins.
18 |
19 | ## Resources
20 |
21 | ### JavaScript and Node.JS
22 |
23 | Modernized JavaScript Tutorials: \
24 | Learn Viral JavaScript Courses: \
25 | CodeCademy online course: \
26 | Eloquent JavaScript, free book: \
27 | MDN's JavaScript guide: \
28 | You Don't Know JS (free book series): \
29 | Some Node.JS: \
30 | JavaScript reference/docs: \
31 | A page with Node.JS resources: \
32 | Node.JS docs: (Main page: )
33 |
34 | ### Discord
35 |
36 | Discord API Docs: \
37 | Discord Applications: \
38 | Discord.JS Docs: \
39 | Eris Docs:
40 |
--------------------------------------------------------------------------------
/guide/topics/erelajs/advanced.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Advanced
3 | displayHeaders: true
4 | sidebarDepth: 1
5 | ---
6 |
7 | ## Player data
8 |
9 | Players can hold custom data like the text channel object or more.
10 | All of this data is similar to a Map and can be referenced easily as shown below.
11 |
12 | ```javascript
13 | const player = manager.create(/* options */);
14 |
15 | // Settings data
16 | player.set("textChannel", message.channel);
17 |
18 | // Getting data
19 | const textChannel = player.get("textChannel");
20 | ```
21 |
22 | Now the type will show as `any` for typings, but you can add some JSDoc in your editor to give it a proper type for your editor.
23 |
24 | ```javascript
25 | /** @type {import("discord.js").TextChannel} */
26 | const textChannel = player.get("textChannel");
27 | ```
28 |
29 | ## Track Partials
30 |
31 | If you only need a part of the track object then you can provide an array with the properties to keep.
32 | The [`track`](/docs/typedefs/Track.html#track) property will always be present as it's required to play tracks.
33 |
34 | ```javascript
35 | const { Manager } = require("erela.js");
36 |
37 | const manager = new Manager({
38 | trackPartial: [ "title", "duration", "requester" ] // Every track object will have these properties.
39 | })
40 | ```
41 |
42 | ## UnresolvedTrack
43 |
44 | Lavalink will only play from the sources enabled, if you want to use Spotify links you'll have to get the YouTube equivalent.
45 | Erela offers a UnresolvedTrack option that will resolve into a playable track before its played.
46 | This is useful for supporting other sources without sending dozens of requests to YouTube for playlists in a short time.
47 |
48 | ```javascript
49 | const { TrackUtils } = require("erela.js");
50 |
51 | // Basic way using just a query.
52 | const unresolvedTrack = TrackUtils.buildUnresolved("Never gonna give you up - Rick Astley", message.author.tag);
53 |
54 | // Advanced way using the title, author, and duration for a precise search.
55 | const unresolvedTrack = TrackUtils.buildUnresolved({
56 | title: "Never gonna give you up",
57 | author: "Rick Astley",
58 | duration: 213000
59 | }, message.author.tag);
60 |
61 | player.queue.add(unresolvedTrack);
62 | // Or.
63 | player.play(unresolvedTrack);
64 | ```
65 |
66 | ## Extending
67 |
68 | You can extend Erela.js' classes to add more functionality like adding some extra handy methods.
69 |
70 | ::: tip
71 | You should not do exactly this as it is a waste of resources, a better way would be to slice the array before formatting it, but for space here I omitted it.
72 | :::
73 |
74 | ```javascript
75 | const { Structure } = require("erela.js");
76 |
77 | Structure.extend("Queue", Queue => class extends Queue {
78 | format(string, ...vars) {
79 | return this.map(track => {
80 | let local = string;
81 | for (let i in vars) local = local.replace(`{${i}}`, track[vars[i]]);
82 | return local;
83 | })
84 | }
85 | })
86 | ```
87 |
88 | Then you can use it as so.
89 |
90 | ```javascript
91 | const tracks = player.queue.format("[{0}]({1})", "title", "uri");
92 | ```
93 |
94 | ## Plugins
95 |
96 | Erela.js' functionality can be expanded even more with the use of plugins, they can add all sorts of new functions such as saving the queue as a playlist and more.
97 |
98 | ### Using plugins
99 |
100 | ```javascript
101 | const { Manager } = require("erela.js");
102 | const MyPlugin = require("my-erela.js-plugin");
103 |
104 | const manager = new Manager({
105 | plugins: [ new MyPlugin({ foo: "bar" }) ]
106 | })
107 | ```
108 |
109 | ### Writing plugins
110 |
111 | ```javascript
112 | const { Plugin } = require("erela.js");
113 |
114 | module.exports = class MyPlugin extends Plugin {
115 | constructor(options) {
116 | super();
117 | this.options = options; // will be { foo: 'bar' }
118 | }
119 |
120 | load(manager) {}
121 | }
122 | ```
123 |
124 | ### Spotify
125 |
126 | You can search using Spotify URL's using the [Spotify plugin](https://github.com/Solaris9/erela.js-spotify) for Erela.JS.
127 |
--------------------------------------------------------------------------------
/guide/topics/erelajs/basics.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Basics
3 | displayHeaders: true
4 | sidebarDepth: 1
5 | ---
6 |
7 | ## Installation
8 |
9 | ::: tip
10 | This guide assumes you already have knowledge about JavaScript and a Discord API library installed, for this guide Discord.JS will be used.
11 | :::
12 |
13 | To start using Erela.js you first have to install it using NPM or Yarn.
14 |
15 | :::: tabs type:border-card stretch:true
16 |
17 | ::: tab NPM
18 | ```bash
19 | npm install erela.js
20 | ```
21 | :::
22 |
23 | ::: tab Yarn
24 | ```bash
25 | yarn add erela.js
26 | ```
27 | :::
28 | ::::
29 |
30 | ## First start
31 |
32 | The first place to start with Erela.js is the Manager class with some [options](/docs/typedefs/ManagerOptions.html).
33 |
34 | ```javascript
35 | // Require both libraries
36 | const { Client } = require("discord.js");
37 | const { Manager } = require("erela.js");
38 |
39 | // Initiate both main classes
40 | const client = new Client();
41 |
42 | // Define some options for the node
43 | const nodes = [
44 | {
45 | host: "localhost",
46 | password: "youshallnotpass",
47 | port: 2333,
48 | }
49 | ];
50 |
51 | // Assign Manager to the client variable
52 | client.manager = new Manager({
53 | // The nodes to connect to, optional if using default lavalink options
54 | nodes,
55 | // Method to send voice data to Discord
56 | send: (id, payload) => {
57 | const guild = client.guilds.cache.get(id);
58 | // NOTE: FOR ERIS YOU NEED JSON.stringify() THE PAYLOAD
59 | if (guild) guild.shard.send(payload);
60 | }
61 | });
62 |
63 | // Emitted whenever a node connects
64 | client.manager.on("nodeConnect", node => {
65 | console.log(`Node "${node.options.identifier}" connected.`)
66 | })
67 |
68 | // Emitted whenever a node encountered an error
69 | client.manager.on("nodeError", (node, error) => {
70 | console.log(`Node "${node.options.identifier}" encountered an error: ${error.message}.`)
71 | })
72 |
73 | // Listen for when the client becomes ready
74 | client.once("ready", () => {
75 | // Initiates the manager and connects to all the nodes
76 | client.manager.init(client.user.id);
77 | console.log(`Logged in as ${client.user.tag}`);
78 | });
79 |
80 | // THIS IS REQUIRED. Send raw events to Erela.js
81 | client.on("raw", d => client.manager.updateVoiceState(d));
82 |
83 | // Finally login at the END of your code
84 | client.login("your bot token here");
85 | ```
86 |
87 | ## The play command
88 |
89 | The whole idea of a music bot is to play music right? So let's write a command to play songs.
90 |
91 | First you want to listen to the message event.
92 |
93 | ```javascript
94 | // Add the previous code block to this
95 |
96 | client.on("message", async message => {
97 | // Some checks to see if it's a valid message
98 | if (!message.content.startsWith("!") || !message.guild || message.author.bot) return;
99 |
100 | // Get the command name and arguments
101 | const [command, ...args] = message.content.slice(1).split(/\s+/g);
102 |
103 | // Check if it's the play command
104 | if (command === "play") {
105 | if (!message.member.voice.channel) return message.reply("you need to join a voice channel.");
106 | if (!args.length) return message.reply("you need to give me a URL or a search term.");
107 |
108 | const search = args.join(" ");
109 | let res;
110 |
111 | try {
112 | // Search for tracks using a query or url, using a query searches youtube automatically and the track requester object
113 | res = await client.manager.search(search, message.author);
114 | // Check the load type as this command is not that advanced for basics
115 | if (res.loadType === "LOAD_FAILED") throw res.exception;
116 | else if (res.loadType === "PLAYLIST_LOADED") throw { message: "Playlists are not supported with this command." };
117 | } catch (err) {
118 | return message.reply(`there was an error while searching: ${err.message}`);
119 | }
120 |
121 | if (res.loadType === "NO_MATCHES") return message.reply("there was no tracks found with that query.");
122 |
123 | // Create the player
124 | const player = client.manager.create({
125 | guild: message.guild.id,
126 | voiceChannel: message.member.voice.channel.id,
127 | textChannel: message.channel.id,
128 | });
129 |
130 | // Connect to the voice channel and add the track to the queue
131 | player.connect();
132 | player.queue.add(res.tracks[0]);
133 |
134 | // Checks if the client should play the track if it's the first one added
135 | if (!player.playing && !player.paused && !player.queue.size) player.play()
136 |
137 | return message.reply(`enqueuing ${res.tracks[0].title}.`);
138 | }
139 | });
140 | ```
141 |
142 | ## Events
143 |
144 | You can play songs but what about knowing when a song starts or end? Those are events that the Manager class emits.
145 |
146 | ```javascript
147 | client.manager = new Manager(/* options above */)
148 | // Chain it off of the Manager instance
149 | // Emitted when a node connects
150 | .on("nodeConnect", node => console.log(`Node "${node.options.identifier}" connected.`));
151 |
152 | // Or each listener on their own
153 | // Emitted when a track starts
154 | client.manager.on("trackStart", (player, track) => {
155 | const channel = client.channels.cache.get(player.textChannel);
156 | // Send a message when the track starts playing with the track name and the requester's Discord tag, e.g. username#discriminator
157 | channel.send(`Now playing: \`${track.title}\`, requested by \`${track.requester.tag}\`.`);
158 | });
159 |
160 | // Emitted the player queue ends
161 | client.manager.on("queueEnd", player => {
162 | const channel = client.channels.cache.get(player.textChannel);
163 | channel.send("Queue has ended.");
164 | player.destroy();
165 | });
166 | ```
167 |
--------------------------------------------------------------------------------
/guide/topics/erelajs/moreCommands.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: More Commands
3 | displayHeaders: true
4 | sidebarDepth: 1
5 | ---
6 |
7 |
8 | A music bot with one command isn't really the best so let's add a few more! This will go through most commands including an improved play command.
9 |
10 | ## Before you start
11 |
12 | Writing every command in the main file will get a bit chaotic so let's move each command to its own file.
13 |
14 | First we need to modify the code a bit to add a map of the commands.
15 |
16 | ```diff
17 | - const { Client } = require("discord.js");
18 | + const { Client, Collection } = require("discord.js");
19 | + const { readdirSync } = require("fs");
20 | const { Manager } = require("erela.js");
21 |
22 | const client = new Client();
23 | client.manager = new Manager(/* options */);
24 |
25 | + client.commands = new Collection();
26 | ```
27 |
28 | ## Loading commands
29 |
30 | We have to find and load all the commands in the `commands` folder so add the following below `client.commands`.
31 |
32 | ```javascript
33 | // Read all the files in the ./commands directory
34 | const files = readdirSync("./commands").filter(file => file.endsWith(".js"));
35 |
36 | // Iterate over all the found files
37 | for (const file of files) {
38 | // Require the file
39 | const command = require(`./commands/${file}`);
40 | // Set the command in the commands collection
41 | client.commands.set(command.name, command);
42 | }
43 | ```
44 |
45 | ## Running commands
46 |
47 | Then we have to run the command in the message event. Remove the current event as we'll be rewriting it.
48 |
49 | ```javascript
50 | // Previous code blocks in #basics before the message event with the modified code above
51 |
52 | client.on("message", async message => {
53 | if (!message.content.startsWith("!") || !message.guild || message.author.bot) return;
54 | const [name, ...args] = message.content.slice(1).split(/\s+/g);
55 |
56 | // Get the command and check if it exists
57 | const command = client.commands.get(name);
58 | if (!command) return;
59 |
60 | // Run the command and catch any errors
61 | try {
62 | command.run(message, args);
63 | } catch (e) {
64 | message.reply(`an error occurred while running the command: ${err.message}`);
65 | }
66 | });
67 | ```
68 |
69 | ## Adding commands
70 |
71 | Lastly, we need a command to load. Let's start with a simple `ping` command to make sure the command handler works.
72 |
73 | In the `commands` folder add a `ping.js` file with the following contents.
74 |
75 | ::: tip
76 | Here I omitted the `args` parameter as it is not used, Node.js will not throw an error if you do not have a parameter passed in the function call.
77 | :::
78 |
79 | ```javascript
80 | module.exports = {
81 | // The name of the command, this has to be different in every command
82 | name: "ping",
83 | // The function to run every time the command is ran by a user
84 | run: (message) => {
85 | message.reply("Pong!")
86 | }
87 | }
88 | ```
89 |
90 | Now start your bot and run `!ping`, you should see the bot reply with `@User, Pong!`, congratulations!
91 |
92 | ## More Commands
93 |
94 | A music bot with only a ping command isn't really that great, so I've created some basic commands you can find in the [examples folder](https://github.com/Solaris9/erela.js/tree/HEAD/examples).
95 |
96 | Those aren't the only commands you can have. You can make some clear the queue, remove tracks, skip the current track and even more!
97 |
98 |
--------------------------------------------------------------------------------
/guide/topics/erelajs/updating.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Updating
3 | displayHeaders: true
4 | sidebarDepth: 1
5 | ---
6 |
7 | ::: tip
8 | Anything not specified means it was not changed or forgotten to be added here. Feel free to send a PR with the changed item.
9 | :::
10 |
11 | ## ErelaClient
12 |
13 | Previously:
14 | ```javascript
15 | const { ErelaClient } = require("erela.js");
16 | const { Client } = require("discord.js");
17 |
18 | const client = new Client();
19 | const nodes = [
20 | {
21 | host: "localhost",
22 | password: "youshallnotpass",
23 | port: 2333
24 | }
25 | ];
26 |
27 | const options = {};
28 |
29 | client.music = new ErelaClient(client, nodes, options)
30 | ```
31 | New:
32 | ```javascript
33 | const { Manager } = require("erela.js");
34 | const { Client } = require("discord.js");
35 |
36 | const client = new Client();
37 | const nodes = [
38 | {
39 | host: "localhost",
40 | password: "youshallnotpass",
41 | port: 2333
42 | }
43 | ];
44 |
45 | client.music = new Manager({
46 | nodes,
47 | send: (id, payload) => {
48 | const guild = client.guilds.cache.get(id);
49 | if (guild) guild.shard.send(payload);
50 | }
51 | })
52 | ```
53 |
54 | Previous in Erela.js v1 you would initiate the ErelaClient class, this was changed to Manager with different parameters.
55 |
56 |
What changed
57 |
58 | - ErelaClient was renamed to Manager
59 | - You no longer need to pass the client
60 | - Most of the node options can be omitted
61 | - You no longer need to provide a node if you're using completely default lavalink options
62 | - You ***need*** provide a `send` function to send voice data to Discord
63 |
64 | ## Player
65 |
66 | ## Creating players
67 |
68 | Before you had to get the PlayerStore and use the `spawn` method to create a Player, now PlayerStore was removed as it's completely useless and bloated the package.
69 |
70 | You can still create players using a similar method named `create` like so:
71 |
72 | ```javascript
73 | const player = manager.create(options);
74 | ```
75 |
76 | Or directly off the Player class:
77 |
78 | ```javascript
79 | const player = new Player(options);
80 | ```
81 |
82 | In both these examples the [`options`](/docs/typedefs/ManagerOptions.html) is same as before.
83 |
84 | ## Destroying players
85 |
86 | In v1 you had to destroy players using the PlayerStore `destroy` method, now you use it off of the Manager class or directly on the Player class.
87 |
88 | ```javascript
89 | const player = manager.get("guildId")
90 |
91 | manager.destroy("guildId");
92 |
93 | // Or
94 |
95 | player.destroy();
96 | ```
97 |
98 | ## Setting equalizer
99 |
100 | Before v2 you had to provide an array of objects to set the equalizer, now you just have to put each object on their own.
101 | If your band objects are in an array you can use the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) to *spread* the objects out.
102 |
103 | ```javascript
104 | // Before
105 | player.setEQ([{ band: 0, gain: .25}, { band: 2, gain: .25}])
106 |
107 | // After
108 | player.setEQ({ band: 0, gain: .25}, { band: 1, gain: .25})
109 | ```
110 |
111 | ## Connecting to voice
112 |
113 | Before Erela.js would automatically connect to the voice channel. Now you must use the Player#connect() method.
114 |
115 | ```javascript
116 | const player = new Player(options);
117 | player.connect();
118 | ```
119 |
120 | ## Queue
121 |
122 | The Queue class had some changed regarding the current song, before it was the first element in the array but was changed to the `current` property.
123 |
124 | ## Utils
125 |
126 | The utils was removed as it bloated the package and didn't offer as much flexibility. There are some packages below to parse and format times.
127 |
128 | ## Format time
129 |
130 | - [https://www.npmjs.com/package/humanize-duration](https://www.npmjs.com/package/humanize-duration)
131 |
132 | ## Parse time
133 |
134 | - [https://www.npmjs.com/package/timestring](https://www.npmjs.com/package/timestring)
135 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "menudocs-guide",
3 | "version": "0.0.2",
4 | "description": "This is the long awaited guide for menudocs",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "dev": "vuepress dev guide",
8 | "build": "vuepress build guide"
9 | },
10 | "author": "Connor Moriarty",
11 | "license": "MIT",
12 | "dependencies": {
13 | "vuepress": "^1.5.0",
14 | "vuepress-plugin-element-tabs": "^0.2.8",
15 | "vuepress-theme-dart": "git+https://github.com/MenuDocs/vuepress-theme-dart.git"
16 | },
17 | "devDependencies": {
18 | "eslint": "^7.1.0",
19 | "eslint-config-tesseract": "^0.0.2",
20 | "watchpack": "^1.6.1"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------