From 8acc4f23f245d1c8fc80992a7117d5f6af168357 Mon Sep 17 00:00:00 2001 From: xHyperElectric <71343435+xHyperElectric@users.noreply.github.com> Date: Sun, 26 Feb 2023 21:50:36 -0500 Subject: [PATCH] Add /replay command (#901) Co-authored-by: xHyperElectric Co-authored-by: xHyperElectric Co-authored-by: Max Isom --- CHANGELOG.md | 2 ++ src/commands/replay.ts | 42 +++++++++++++++++++++++++++++++++++++++++ src/inversify.config.ts | 12 +++++++----- 3 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 src/commands/replay.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e46c188..d05eedd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Added a '/replay' to restart the current song. Alias for '/seek time: 0' ## [2.1.9] - 2023-02-14 ### Fixed diff --git a/src/commands/replay.ts b/src/commands/replay.ts new file mode 100644 index 0000000..43b1057 --- /dev/null +++ b/src/commands/replay.ts @@ -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'; + +@injectable() +export default class implements Command { + public readonly slashCommand = new SlashCommandBuilder() + .setName('replay') + .setDescription('replay the current song'); + + public requiresVC = true; + + private readonly playerManager: PlayerManager; + + constructor(@inject(TYPES.Managers.Player) playerManager: PlayerManager) { + this.playerManager = playerManager; + } + + public async execute(interaction: ChatInputCommandInteraction): Promise { + const player = this.playerManager.get(interaction.guild!.id); + + const currentSong = player.getCurrent(); + + if (!currentSong) { + throw new Error('nothing is playing'); + } + + if (currentSong.isLive) { + throw new Error('can\'t replay a livestream'); + } + + await Promise.all([ + player.seek(0), + interaction.deferReply(), + ]); + + await interaction.editReply('👍 replayed the current song'); + } +} diff --git a/src/inversify.config.ts b/src/inversify.config.ts index 002d72c..1a3b85c 100644 --- a/src/inversify.config.ts +++ b/src/inversify.config.ts @@ -14,30 +14,31 @@ import GetSongs from './services/get-songs.js'; import YoutubeAPI from './services/youtube-api.js'; import SpotifyAPI from './services/spotify-api.js'; -// Comands +// Commands import Command from './commands'; import Clear from './commands/clear.js'; 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 Loop from './commands/loop'; import Move from './commands/move.js'; +import Next from './commands/next.js'; import NowPlaying from './commands/now-playing.js'; import Pause from './commands/pause.js'; import Play from './commands/play.js'; import QueueCommand from './commands/queue.js'; import Remove from './commands/remove.js'; +import Replay from './commands/replay.js'; import Resume from './commands/resume.js'; import Seek from './commands/seek.js'; import Shuffle from './commands/shuffle.js'; import Skip from './commands/skip.js'; -import Next from './commands/next.js'; import Stop from './commands/stop.js'; import Unskip from './commands/unskip.js'; import ThirdParty from './services/third-party.js'; import FileCacheProvider from './services/file-cache.js'; import KeyValueCacheProvider from './services/key-value-cache.js'; -import Loop from './commands/loop'; const container = new Container(); @@ -67,20 +68,21 @@ container.bind(TYPES.Services.SpotifyAPI).to(SpotifyAPI).inSingleton Disconnect, Favorites, ForwardSeek, + Loop, Move, + Next, NowPlaying, Pause, Play, QueueCommand, Remove, + Replay, Resume, Seek, Shuffle, Skip, - Next, Stop, Unskip, - Loop, ].forEach(command => { container.bind(TYPES.Command).to(command).inSingletonScope(); });