Add /loop-queue command (#989)

This commit is contained in:
Reynard G 2024-01-16 19:44:44 -06:00 committed by GitHub
parent 45bdbd1494
commit 769f9da8a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 64 additions and 1 deletions

View file

@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Added `/loop-queue`
## [2.4.4] - 2023-12-21
- Optimized Docker container to run JS code directly with node instead of yarn, npm and tsx. Reduces memory usage.

View file

@ -0,0 +1,42 @@
import {ChatInputCommandInteraction} from 'discord.js';
import {TYPES} from '../types.js';
import {inject, injectable} from 'inversify';
import PlayerManager from '../managers/player.js';
import Command from '.';
import {SlashCommandBuilder} from '@discordjs/builders';
import {STATUS} from '../services/player.js';
@injectable()
export default class implements Command {
public readonly slashCommand = new SlashCommandBuilder()
.setName('loop-queue')
.setDescription('toggle looping the entire queue');
public requiresVC = true;
private readonly playerManager: PlayerManager;
constructor(@inject(TYPES.Managers.Player) playerManager: PlayerManager) {
this.playerManager = playerManager;
}
public async execute(interaction: ChatInputCommandInteraction): Promise<void> {
const player = this.playerManager.get(interaction.guild!.id);
if (player.status === STATUS.IDLE) {
throw new Error('no songs to loop!');
}
if (player.queueSize() < 2) {
throw new Error('not enough songs to loop a queue!');
}
if (player.loopCurrentSong) {
player.loopCurrentSong = false;
}
player.loopCurrentQueue = !player.loopCurrentQueue;
await interaction.reply((player.loopCurrentQueue ? 'looped queue :)' : 'stopped looping queue :('));
}
}

View file

@ -27,6 +27,10 @@ export default class implements Command {
throw new Error('no song to loop!');
}
if (player.loopCurrentQueue) {
player.loopCurrentQueue = false;
}
player.loopCurrentSong = !player.loopCurrentSong;
await interaction.reply((player.loopCurrentSong ? 'looped :)' : 'stopped looping :('));

View file

@ -21,6 +21,7 @@ import Config from './commands/config.js';
import Disconnect from './commands/disconnect.js';
import Favorites from './commands/favorites.js';
import ForwardSeek from './commands/fseek.js';
import LoopQueue from './commands/loop-queue.js';
import Loop from './commands/loop.js';
import Move from './commands/move.js';
import Next from './commands/next.js';
@ -68,6 +69,7 @@ container.bind<SpotifyAPI>(TYPES.Services.SpotifyAPI).to(SpotifyAPI).inSingleton
Disconnect,
Favorites,
ForwardSeek,
LoopQueue,
Loop,
Move,
Next,

View file

@ -63,6 +63,7 @@ export default class {
public status = STATUS.PAUSED;
public guildId: string;
public loopCurrentSong = false;
public loopCurrentQueue = false;
private queue: QueuedSong[] = [];
private queuePosition = 0;
@ -545,6 +546,17 @@ export default class {
return;
}
// Automatically re-add current song to queue
if (this.loopCurrentQueue && newState.status === AudioPlayerStatus.Idle && this.status === STATUS.PLAYING) {
const currentSong = this.getCurrent();
if (currentSong) {
this.add(currentSong);
} else {
throw new Error('No song currently playing.');
}
}
if (newState.status === AudioPlayerStatus.Idle && this.status === STATUS.PLAYING) {
await this.forward(1);
}

View file

@ -46,7 +46,7 @@ const getPlayerUI = (player: Player) => {
const button = player.status === STATUS.PLAYING ? '⏹️' : '▶️';
const progressBar = getProgressBar(15, position / song.length);
const elapsedTime = song.isLive ? 'live' : `${prettyTime(position)}/${prettyTime(song.length)}`;
const loop = player.loopCurrentSong ? '🔁' : '';
const loop = player.loopCurrentSong ? '🔂' : player.loopCurrentQueue ? '🔁' : '';
return `${button} ${progressBar} \`[${elapsedTime}]\` 🔉 ${loop}`;
};