aboutsummaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
authorThongrapee Panyapatiphan <[email protected]>2022-01-22 01:50:57 +0700
committerGitHub <[email protected]>2022-01-21 12:50:57 -0600
commit59cbc8b474425225f7f188ce54bc19d5f1193ecb (patch)
treee218db77455d935fed39e112dcd1807d53ea8352 /src/utils
parentda72cd708bcfbba6e0a91da4878aaef10d2532e2 (diff)
downloadmuse-59cbc8b474425225f7f188ce54bc19d5f1193ecb.tar.xz
muse-59cbc8b474425225f7f188ce54bc19d5f1193ecb.zip
Announce current song (#470)
Co-authored-by: Max Isom <[email protected]>
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/build-embed.ts127
-rw-r--r--src/utils/string.ts2
2 files changed, 129 insertions, 0 deletions
diff --git a/src/utils/build-embed.ts b/src/utils/build-embed.ts
new file mode 100644
index 0000000..5a2f758
--- /dev/null
+++ b/src/utils/build-embed.ts
@@ -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;
+};
diff --git a/src/utils/string.ts b/src/utils/string.ts
new file mode 100644
index 0000000..0b49114
--- /dev/null
+++ b/src/utils/string.ts
@@ -0,0 +1,2 @@
+export const truncate = (text: string, maxLength = 50) =>
+ text.length > maxLength ? `${text.slice(0, maxLength - 3)}...` : text;