From 88fc915f3b2c8888e7bc138765d87649e8b9fe9e Mon Sep 17 00:00:00 2001 From: FernandoJVideira <03.pleaser-minster@icloud.com> Date: Fri, 23 Oct 2026 12:16:20 +0100 Subject: [PATCH] Music: only /music remove and /music move are commands Pause, skip, repeat and stop are already buttons on the now-playing message. Co-Authored-By: Claude Sonnet 5.5 --- docs/commands.md | 6 +-- docs/features.md | 2 +- internal/commands/help/help.go | 2 +- internal/commands/music/public/player.go | 48 ++++-------------------- internal/music/manager.go | 17 --------- 5 files changed, 10 insertions(+), 65 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index 3115f80..cb87fad 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -60,14 +60,10 @@ Anyone can use these. `/rps`, `/rpsstats` and `/rpsleaderboard` work in servers | `/queue` | | **DJ** role | Shows the queue | | `/volume` | `value`* (0 to 150) | **DJ** role | Sets the volume | | `/music toggle` | | Manage Server | Turns music on or off in this server | -| `/music skip` | | **DJ** role | Skips the current song | -| `/music pause`, `/music resume` | | **DJ** role | Pauses or resumes | -| `/music stop` | | **DJ** role | Stops and clears the queue | -| `/music repeat` | `mode`* (off, song, queue) | **DJ** role | Repeats the song, the queue, or nothing | | `/music remove` | `position`* (its number in `/queue`) | **DJ** role | Removes a queued song | | `/music move` | `from`*, `to`* | **DJ** role | Moves a queued song | -Requires Lavalink. See [Getting started](getting-started.md#optional-music-with-lavalink). +Pause, skip, repeat and stop are buttons on the now-playing message. Requires Lavalink. See [Getting started](getting-started.md#optional-music-with-lavalink). ## Meeting rooms diff --git a/docs/features.md b/docs/features.md index 555b794..d0544a9 100644 --- a/docs/features.md +++ b/docs/features.md @@ -68,7 +68,7 @@ Lavalink-powered playback. Code: `internal/music`, commands in `internal/command - `/play` takes a name or a URL, `/queue` shows the queue, `/volume` sets 0 to 150 percent. These need a role called **DJ**. - The now-playing message has buttons for playback and repeat. Buttons also check for the DJ role. -- `/music toggle` (Manage Server) turns music on or off in a server. `/music skip`, `pause`, `resume`, `stop`, `repeat`, `remove` and `move` control playback and the queue (DJ role). +- `/music toggle` (Manage Server) turns music on or off in a server. `/music remove` and `/music move` edit the queue (DJ role). - The queue and now-playing state are kept in the database, and playback can also be controlled by writing to the `music_commands` table. The hosted Velox dashboard uses this (see [Database](database.md)); you never need it, the commands above do the same. - Music needs a Lavalink server. Without `LAVALINK_HOST` the rest of the bot works and music does not. diff --git a/internal/commands/help/help.go b/internal/commands/help/help.go index b8bad42..82b9230 100644 --- a/internal/commands/help/help.go +++ b/internal/commands/help/help.go @@ -44,7 +44,7 @@ func fields() []*discordgo.MessageEmbedField { col("Fun", "`/ping` `/joke` `/coinflip`", "`/dice` `/rps` `/rpsstats`", "`/rpsleaderboard`"), col("Music (DJ role)", - "`/play` `/queue` `/volume`", "`/music skip` `pause` `resume`", "`/music stop` `repeat`", "`/music remove` `move`", "`/music toggle` (Manage Server)"), + "`/play` `/queue` `/volume`", "`/music remove` `move`", "`/music toggle` (Manage Server)"), col("Sessions and time", "`/schedule create`", "`/schedule list`", "`/schedule reschedule`", "`/timezone set` `show`"), col("Tickets", diff --git a/internal/commands/music/public/player.go b/internal/commands/music/public/player.go index ae30bc6..b7d333b 100644 --- a/internal/commands/music/public/player.go +++ b/internal/commands/music/public/player.go @@ -10,10 +10,10 @@ import ( "github.com/bwmarrin/discordgo" ) -// The player controls. Everything a dashboard can do to the queue (skip, pause, -// resume, stop, repeat, remove and move a track) is also a command, so a -// server never needs one. They need the DJ role, like /play, /queue and -// /volume. Turning music on or off needs Manage Server. +// Queue editing. Pausing, skipping, repeating and stopping are buttons on the +// now-playing message, so the only queue controls that need commands are +// removing a song and moving one. They need the DJ role, like /play, /queue +// and /volume. Turning music on or off needs Manage Server. func positionOption(name, desc string) *discordgo.ApplicationCommandOption { return &discordgo.ApplicationCommandOption{ @@ -27,15 +27,6 @@ func playerOptions() []*discordgo.ApplicationCommandOption { return &discordgo.ApplicationCommandOption{Type: discordgo.ApplicationCommandOptionSubCommand, Name: name, Description: desc, Options: o} } return []*discordgo.ApplicationCommandOption{ - sub("skip", "Skip the current song (DJ)"), - sub("pause", "Pause playback (DJ)"), - sub("resume", "Resume playback (DJ)"), - sub("stop", "Stop playback and clear the queue (DJ)"), - sub("repeat", "Repeat the current song, the whole queue, or nothing (DJ)", - &discordgo.ApplicationCommandOption{ - Type: discordgo.ApplicationCommandOptionString, Name: "mode", Description: "What repeats", Required: true, - Choices: []*discordgo.ApplicationCommandOptionChoice{{Name: "off", Value: "off"}, {Name: "song", Value: "song"}, {Name: "queue", Value: "queue"}}, - }), sub("remove", "Remove a song from the queue (DJ)", positionOption("position", "Its number in /queue")), sub("move", "Move a song to another place in the queue (DJ)", positionOption("from", "Its number in /queue"), positionOption("to", "The number it should have")), @@ -57,44 +48,19 @@ func title(e *music.TrackEntry) string { return strings.TrimSpace(e.Track.Info.Title) } -// handlePlayer runs a player subcommand. The caller has checked that music is -// on and that the member has the DJ role. +// handlePlayer runs a queue subcommand. The caller has checked that music is +// on and that the member has the DJ role. Pause, skip, repeat and stop are +// buttons on the now-playing message, so only what has no button is a command. func handlePlayer(s *discordgo.Session, i *discordgo.InteractionCreate, sub *discordgo.ApplicationCommandInteractionDataOption) { g := i.GuildID args := map[string]*discordgo.ApplicationCommandInteractionDataOption{} for _, o := range sub.Options { args[o.Name] = o } - current, _ := music.GetQueue(g) - needsPlayer := sub.Name != "repeat" && sub.Name != "remove" && sub.Name != "move" - if needsPlayer && current == nil { - shared.RespondEphemeral(s, i, "Nothing is playing.") - return - } var err error var msg string switch sub.Name { - case "skip": - err, msg = music.Skip(g), "Skipped." - case "pause": - err, msg = music.Pause(g, true), "Paused. `/music resume` continues." - case "resume": - err, msg = music.Pause(g, false), "Resumed." - case "stop": - err, msg = music.Stop(g), "Stopped, and the queue is cleared." - case "repeat": - switch args["mode"].StringValue() { - case "song": - music.SetRepeat(g, true, false) - msg = "The current song repeats." - case "queue": - music.SetRepeat(g, false, true) - msg = "The whole queue repeats." - default: - music.SetRepeat(g, false, false) - msg = "Nothing repeats." - } case "remove": n := int(args["position"].IntValue()) e, size := queueEntry(g, n) diff --git a/internal/music/manager.go b/internal/music/manager.go index 615466b..e740543 100644 --- a/internal/music/manager.go +++ b/internal/music/manager.go @@ -686,23 +686,6 @@ func ToggleRepeatQueue(guildID string) (bool, bool) { return repeatSong, repeatQueue } -// RepeatFlags reports whether the current song or the whole queue repeats. -func RepeatFlags(guildID string) (song, queue bool) { return repeatFlags(guildID) } - -// SetRepeat sets the repeat mode directly. At most one of the two applies; -// asking for both repeats the song. -func SetRepeat(guildID string, song, queue bool) { - if manager == nil { - return - } - gp := getOrCreateGuildPlayer(guildID) - manager.mu.Lock() - gp.RepeatSong = song - gp.RepeatQueue = queue && !song - manager.mu.Unlock() - syncState(guildID) -} - func repeatFlags(guildID string) (bool, bool) { if manager == nil { return false, false