Skip to content

Commit

Permalink
Merge pull request #48 from Joehoel/music
Browse files Browse the repository at this point in the history
feat: ✨ Music update
  • Loading branch information
Joehoel authored Sep 17, 2021
2 parents 398acab + 9e2b88d commit b341a84
Show file tree
Hide file tree
Showing 21 changed files with 626 additions and 1,354 deletions.
20 changes: 6 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,35 @@
"@discordjs/builders": "^0.6.0",
"@discordjs/opus": "^0.6.0",
"@discordjs/rest": "^0.1.0-canary.0",
"@joehoel/discord-reply": "^1.0.4",
"@distube/spotify": "^0.6.3",
"axios": "^0.21.1",
"bad-words": "^3.0.4",
"consola": "^2.15.3",
"cron": "^1.8.2",
"cross-fetch": "^3.1.4",
"discord-api-types": "^0.22.0",
"discord-paginationembed": "^2.1.0",
"discord-reply": "^0.1.2",
"discord-paginationembed": "Androz2091/discord-paginationembed#support-djs-v13",
"discord-player": "^5.1.0",
"discord-xp": "^1.1.16",
"discord.js": "^13.1.0",
"distube": "^2.8.18",
"discord.js-embed-pagination": "^0.5.4",
"distube": "^3.0.0-beta.38",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"ffmpeg-static": "^4.4.0",
"genius-lyrics": "^4.2.9",
"jest": "^27.1.0",
"module-alias": "^2.2.2",
"mongoose": "^6.0.2",
"ms": "^2.1.3",
"mysql": "^2.14.1",
"node-fetch": "^2.6.1",
"pg": "^8.7.1",
"redis": "^3.1.2",
"reflect-metadata": "^0.1.10",
"toml": "^3.0.0",
"typeorm": "0.2.37"
},
"devDependencies": {
"@joehoel/eslint-config": "1.0.1",
"@types/bad-words": "^3.0.1",
"@types/colors": "^1.2.1",
"@types/cron": "^1.7.3",
"@types/glob": "^7.1.4",
"@types/jest": "^27.0.1",
"@types/ms": "^0.7.31",
"@types/node": "16.7.5",
Expand All @@ -50,11 +46,7 @@
"cross-env": "^7.0.3",
"eslint": "7.32.0",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-import": "2.24.2",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-prettier": "3.4.1",
"eslint-plugin-react": "7.25.0",
"eslint-plugin-react-hooks": "4.2.0",
"gen-env-types": "^1.3.0",
"husky": "^7.0.2",
"jest-fetch-mock": "^3.0.3",
Expand Down
45 changes: 45 additions & 0 deletions src/_commands/music/play.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import SlashCommand, { OptionType } from "@/modules/SlashCommand";
import { Guild, GuildMember, VoiceChannel } from "discord.js";

export default new SlashCommand({
name: "play",
description: "Play a song",
options: [
{
name: "query",
type: OptionType.STRING,
description: "The song you want to play",
required: true,
},
],
async execute(interaction) {
const player = interaction.client.player;
const query = interaction.options.getString("query")!;
const member = interaction.member as GuildMember;
const queue = player.createQueue(interaction.guild!, {
metadata: {
channel: interaction.channel,
},
});

try {
if (!queue.connection) await queue.connect(member.voice.channel as VoiceChannel);
} catch {
queue.destroy();
return await interaction.reply({ content: "🚫 | Could not join your voice channel!", ephemeral: true });
}

await interaction.deferReply();

const track = await player
.search(query, {
requestedBy: interaction.user,
})
.then((x) => x.tracks[0]);
if (!track) return await interaction.followUp({ content: `❌ | Track **${query}** not found!` });

queue.play(track);

return await interaction.followUp({ content: `⏱️ | Loading track **${track.title}**!` });
},
});
28 changes: 28 additions & 0 deletions src/_commands/music/queue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { chunk, embed } from "@/lib/helpers";
import SlashCommand, { OptionType } from "@/modules/SlashCommand";
import { GuildMember, MessageEmbed, VoiceChannel } from "discord.js";
import { sendPaginatedEmbeds } from "discord.js-embed-pagination";

export default new SlashCommand({
name: "queue",
description: "Get the queue",
async execute(interaction) {
const client = interaction.client;
const queue = client.player.getQueue(interaction.guild!);

// if (queue.tracks.length > 1) {
// }
// if (queue && queue.songs.length > 1) {
// const formattedQueue = queue?.songs?.map((song, i) => {
// return `**${i + 1}**. \`${song?.name}\` - \`${song?.formattedDuration}\``;
// });

// // const paginatedEmbed = new MessageEmbed({
// // title: "Queue",
// // footer: { text: `${queue?.songs.length} songs in queue | ${queue?.formattedDuration} total length` },
// // });

// await sendPaginatedEmbeds(interaction, embeds);
// }
},
});
2 changes: 1 addition & 1 deletion src/commands/music/empty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ export default new Command({
exclusive: true,
execute(client, message) {
if (!message.member?.voice.channel) throw new Error("NotInVoice");
client.music.getQueue(message).songs.length = 0;
client.music.getQueue(message)!.songs.length = 0;
},
});
2 changes: 1 addition & 1 deletion src/commands/music/loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default new Command({
fields: [
{
name: "Status",
value: status(client.music.getQueue(message)),
value: status(client.music.getQueue(message)!),
},
],
});
Expand Down
38 changes: 19 additions & 19 deletions src/commands/music/lyrics.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import Command from "../../modules/Command";
import { embed } from "../../lib/helpers";
import { getLyrics } from "../../lib/lyrics";
import { init } from "../../lib/lyrics";

const { GENIUS_TOKEN } = process.env;

export default new Command({
name: "lyrics",
description: "Search for the song lyrics",
usage: "<song - artist>",
exclusive: true,
async execute(client, message, args) {
const { search } = init(GENIUS_TOKEN);
let song = "";
const queue = client.music.getQueue(message);
if (queue?.songs.length) {
song = queue.songs[0].name;

if (queue?.songs) {
song = queue.songs[0].name!;
}

if (args.length >= 1) {
Expand All @@ -20,22 +24,18 @@ export default new Command({
song = song.split("(")[0];
}

try {
const { lyrics, name, artist, album_art, url } = await getLyrics(song);
if (lyrics.trim().length) {
return await message.channel.send({
embeds: [
embed({
title: `${name} - ${artist}`,
description: lyrics,
thumbnail: { url: album_art },
url,
}),
],
});
}
} catch (error) {
client.logger.error(error);
const { lyrics, title, artist, thumbnail, url } = await search(song);
if (lyrics?.trim().length) {
return await message.channel.send({
embeds: [
embed({
title: `${title} - ${artist.name}`,
description: lyrics,
thumbnail: { url: thumbnail },
url,
}),
],
});
}
},
});
6 changes: 3 additions & 3 deletions src/commands/music/move.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export default new Command({
if (from > to) {
queue.songs.splice(to, 0, queue.songs[from]);
queue.songs.splice(from + 1, 1);
} else {
queue.songs.splice(to + 1, 0, queue.songs[from]);
queue.songs.splice(from - 1, 1);
}

queue.songs.splice(to + 1, 0, queue.songs[from]);
queue.songs.splice(from - 1, 1);
},
});
6 changes: 3 additions & 3 deletions src/commands/music/now.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { MessageEmbed } from "discord.js";
export default new Command({
name: "now",
description: "Shows the current playing song",
aliases: ["np", "nowplaying"],
aliases: ["np", "nowplaying", "playing"],
exclusive: true,
execute(client, message) {
if (!message.member?.voice.channel) throw new Error("NotInVoice");
const queue = client.music.getQueue(message);
const queue = client.music.getQueue(message)!;
const song = queue.songs[0];
if (song && queue)
return message.channel.send({
Expand All @@ -24,7 +24,7 @@ export default new Command({
},
{
name: "Requested by",
value: song.user.username,
value: song.user!.username,
},
{
name: "Status",
Expand Down
10 changes: 6 additions & 4 deletions src/commands/music/playtop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ export default new Command({
exclusive: true,
async execute(client, message, args) {
if (!message.member?.voice.channel) throw new Error("NotInVoice");
await client.music.play(message, args.join(" "));
const from = client.music.getQueue(message).songs.length;
move.execute(client, message, [from.toString(), "1"]);
console.log(`Moving ${from} to 1`);
await client.music.play(message, args.join(" "), {
unshift: true,
});
// const from = client.music.getQueue(message)!.songs.length;
// move.execute(client, message, [from.toString(), "1"]);
// console.log(`Moving ${from} to 1`);
},
});
68 changes: 36 additions & 32 deletions src/commands/music/queue.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Command from "../../modules/Command";
import { FieldsEmbed } from "discord-paginationembed";
import { TextChannel } from "discord.js";
import Song from "distube/typings/Song";
import { embed } from "../../lib/helpers";
import { Embeds } from "discord-paginationembed";
import { MessageEmbed, TextChannel } from "discord.js";
import { chunk, embed } from "../../lib/helpers";
import { sendPaginatedEmbeds } from "discord.js-embed-pagination";

export default new Command({
name: "queue",
Expand All @@ -11,40 +11,44 @@ export default new Command({
exclusive: true,
async execute(client, message) {
const queue = client.music.getQueue(message);
const playing = queue?.songs.shift();

if (queue && queue.songs.length > 1) {
try {
const formattedQueue = queue?.songs?.map((song: Song, i) => {
return `**${i + 1}**. \`${song?.name}\` - \`${song?.formattedDuration}\``;
});
const paginatedEmbed = new FieldsEmbed()
.setArray(formattedQueue)
.setElementsPerPage(10)
.setDisabledNavigationEmojis(["delete"])
.setChannel(message.channel as TextChannel)
.formatField("Queue", (el) => el);
const formattedQueue = queue.songs.map((song, i) => {
return `**${i}**. \`${song?.name}\` - \`${song?.formattedDuration}\``;
});

const playing = formattedQueue.shift()?.split(".")[1];

paginatedEmbed.embed
.setColor("#ffc600")
.setTitle("Music")
.setFooter(`${queue?.songs.length} songs in queue | ${queue?.formattedDuration} total length`);
const embeds = chunk(formattedQueue, 10).map((chunk) => {
const content = chunk.join("\n");
return new MessageEmbed({
title: "Music",
footer: {
text: `${queue?.songs.length} song(s) in queue | ${queue?.formattedDuration} total length`,
},
color: "#ffc600",
fields: [
{
name: "Now playing",
value: playing!,
inline: true,
},
{
name: "Queue",
value: content,
},
],
});
});

queue?.songs.unshift(playing!);
const paginatedEmbed = new Embeds()
.setArray(embeds)
.setDisabledNavigationEmojis(["delete"])
.setChannel(message.channel as TextChannel);

await paginatedEmbed.build();
} catch (error) {
client.logger.error(error);
}
await paginatedEmbed.build();
} else {
return message.channel.send({
embeds: [
embed({
title: "Music",
description: "Queue is empty 🐱",
}),
],
});
return message.channel.send("🗑 | Queue is empty ");
}
},
});
4 changes: 2 additions & 2 deletions src/commands/music/remove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import Command from "../../modules/Command";
export default new Command({
name: "remove",
description: "Remove a specific song or songs from queue",
aliases: ["delete", "del"],
aliases: ["delete", "del", "rm"],
args: true,
usage: "<song number(s)>",
exclusive: true,
execute(client, message, args) {
if (!message.member?.voice.channel) throw new Error("NotInVoice");
const indeces = args.map((arg) => parseInt(arg));
const songs = client.music.getQueue(message).songs;
const songs = client.music.getQueue(message)!.songs;

if (args.length === 1) {
const songIdx = indeces[0];
Expand Down
2 changes: 1 addition & 1 deletion src/commands/music/stop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default new Command({
},
{
name: "Status",
value: status(client.music.getQueue(message)),
value: status(client.music.getQueue(message)!),
},
],
});
Expand Down
Loading

0 comments on commit b341a84

Please sign in to comment.