mirror of
https://github.com/BluemediaDev/muse.git
synced 2025-05-11 12:21:37 +02:00
parent
da72cd708b
commit
59cbc8b474
12 changed files with 317 additions and 190 deletions
127
src/utils/build-embed.ts
Normal file
127
src/utils/build-embed.ts
Normal file
|
@ -0,0 +1,127 @@
|
|||
import getYouTubeID from 'get-youtube-id';
|
||||
import {MessageEmbed} from 'discord.js';
|
||||
import Player, {QueuedSong, STATUS} from '../services/player.js';
|
||||
import getProgressBar from './get-progress-bar.js';
|
||||
import {prettyTime} from './time.js';
|
||||
import {truncate} from './string.js';
|
||||
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
const getMaxSongTitleLength = (title: string) => {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const nonASCII = /[^\x00-\x7F]+/;
|
||||
return nonASCII.test(title) ? 28 : 48;
|
||||
};
|
||||
|
||||
const getSongTitle = ({title, url}: QueuedSong, shouldTruncate = false) => {
|
||||
const cleanSongTitle = title.replace(/\[.*\]/, '').trim();
|
||||
|
||||
const songTitle = shouldTruncate ? truncate(cleanSongTitle, getMaxSongTitleLength(cleanSongTitle)) : cleanSongTitle;
|
||||
const youtubeId = url.length === 11 ? url : getYouTubeID(url) ?? '';
|
||||
|
||||
return `[${songTitle}](https://www.youtube.com/watch?v=${youtubeId})`;
|
||||
};
|
||||
|
||||
const getQueueInfo = (player: Player) => {
|
||||
const queueSize = player.queueSize();
|
||||
if (queueSize === 0) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return queueSize === 1 ? '1 song' : `${queueSize} songs`;
|
||||
};
|
||||
|
||||
const getPlayerUI = (player: Player) => {
|
||||
const song = player.getCurrent();
|
||||
|
||||
if (!song) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const position = player.getPosition();
|
||||
const button = player.status === STATUS.PLAYING ? '⏹️' : '▶️';
|
||||
const progressBar = getProgressBar(15, position / song.length);
|
||||
const elapsedTime = `${prettyTime(position)}/${song.isLive ? 'live' : prettyTime(song.length)}`;
|
||||
|
||||
return `${button} ${progressBar} \`[${elapsedTime}]\` 🔉`;
|
||||
};
|
||||
|
||||
export const buildPlayingMessageEmbed = (player: Player): MessageEmbed => {
|
||||
const currentlyPlaying = player.getCurrent();
|
||||
|
||||
if (!currentlyPlaying) {
|
||||
throw new Error('No playing song found');
|
||||
}
|
||||
|
||||
const {artist, thumbnailUrl, requestedBy} = currentlyPlaying;
|
||||
const message = new MessageEmbed();
|
||||
|
||||
message
|
||||
.setColor('DARK_GREEN')
|
||||
.setTitle('Now Playing')
|
||||
.setDescription(`
|
||||
**${getSongTitle(currentlyPlaying)}**
|
||||
Requested by: <@${requestedBy}>\n
|
||||
${getPlayerUI(player)}
|
||||
`)
|
||||
.setFooter({text: `Source: ${artist}`});
|
||||
|
||||
if (thumbnailUrl) {
|
||||
message.setThumbnail(thumbnailUrl);
|
||||
}
|
||||
|
||||
return message;
|
||||
};
|
||||
|
||||
export const buildQueueEmbed = (player: Player, page: number): MessageEmbed => {
|
||||
const currentlyPlaying = player.getCurrent();
|
||||
|
||||
if (!currentlyPlaying) {
|
||||
throw new Error('queue is empty');
|
||||
}
|
||||
|
||||
const queueSize = player.queueSize();
|
||||
const maxQueuePage = Math.ceil((queueSize + 1) / PAGE_SIZE);
|
||||
|
||||
if (page > maxQueuePage) {
|
||||
throw new Error('the queue isn\'t that big');
|
||||
}
|
||||
|
||||
const queuePageBegin = (page - 1) * PAGE_SIZE;
|
||||
const queuePageEnd = queuePageBegin + PAGE_SIZE;
|
||||
const queuedSongs = player
|
||||
.getQueue()
|
||||
.slice(queuePageBegin, queuePageEnd)
|
||||
.map((song, index) => `\`${index + 1 + queuePageBegin}.\` ${getSongTitle(song, true)} \`[${prettyTime(song.length)}]\``)
|
||||
.join('\n');
|
||||
|
||||
const {artist, thumbnailUrl, playlist, requestedBy} = currentlyPlaying;
|
||||
const playlistTitle = playlist ? `(${playlist.title})` : '';
|
||||
const totalLength = player.getQueue().reduce((accumulator, current) => accumulator + current.length, 0);
|
||||
|
||||
const message = new MessageEmbed();
|
||||
|
||||
let description = `**${getSongTitle(currentlyPlaying)}**\n`;
|
||||
description += `Requested by: <@${requestedBy}>\n\n`;
|
||||
description += `${getPlayerUI(player)}\n\n`;
|
||||
|
||||
if (player.getQueue().length > 0) {
|
||||
description += '**Up next:**\n';
|
||||
description += queuedSongs;
|
||||
}
|
||||
|
||||
message
|
||||
.setTitle(player.status === STATUS.PLAYING ? 'Now Playing' : 'Queued songs')
|
||||
.setColor(player.status === STATUS.PLAYING ? 'DARK_GREEN' : 'NOT_QUITE_BLACK')
|
||||
.setDescription(description)
|
||||
.addField('In queue', getQueueInfo(player), true)
|
||||
.addField('Total length', `${totalLength > 0 ? prettyTime(totalLength) : '-'}`, true)
|
||||
.addField('Page', `${page} out of ${maxQueuePage}`, true)
|
||||
.setFooter({text: `Source: ${artist} ${playlistTitle}`});
|
||||
|
||||
if (thumbnailUrl) {
|
||||
message.setThumbnail(thumbnailUrl);
|
||||
}
|
||||
|
||||
return message;
|
||||
};
|
2
src/utils/string.ts
Normal file
2
src/utils/string.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export const truncate = (text: string, maxLength = 50) =>
|
||||
text.length > maxLength ? `${text.slice(0, maxLength - 3)}...` : text;
|
Loading…
Add table
Add a link
Reference in a new issue