Files
FernandoJVideiraandClaude Sonnet 5.5 88fc915f3b 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 <[email protected]>
2026-10-23 12:16:20 +01:00

93 lines
3.2 KiB
Go

package public
import (
"fmt"
"strings"
"velox-bot/internal/commands/music/shared"
"velox-bot/internal/music"
"github.com/bwmarrin/discordgo"
)
// 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{
Type: discordgo.ApplicationCommandOptionInteger, Name: name, Description: desc,
Required: true, MinValue: ptrFloat(1), MaxValue: 1000,
}
}
func playerOptions() []*discordgo.ApplicationCommandOption {
sub := func(name, desc string, o ...*discordgo.ApplicationCommandOption) *discordgo.ApplicationCommandOption {
return &discordgo.ApplicationCommandOption{Type: discordgo.ApplicationCommandOptionSubCommand, Name: name, Description: desc, Options: o}
}
return []*discordgo.ApplicationCommandOption{
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")),
}
}
// queueEntry returns the queued song at position n (1 is the first one after
// the song that is playing), as /queue numbers them.
func queueEntry(guildID string, n int) (*music.TrackEntry, int) {
_, rest := music.GetQueue(guildID)
if n < 1 || n > len(rest) {
return nil, len(rest)
}
e := rest[n-1]
return &e, len(rest)
}
func title(e *music.TrackEntry) string {
return strings.TrimSpace(e.Track.Info.Title)
}
// 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
}
var err error
var msg string
switch sub.Name {
case "remove":
n := int(args["position"].IntValue())
e, size := queueEntry(g, n)
if e == nil {
shared.RespondEphemeral(s, i, fmt.Sprintf("There is no song number %d in the queue (it has %d).", n, size))
return
}
err, msg = music.RemoveFromQueue(g, e.QueueID), fmt.Sprintf("Removed **%s**.", title(e))
case "move":
from, to := int(args["from"].IntValue()), int(args["to"].IntValue())
e, size := queueEntry(g, from)
if e == nil {
shared.RespondEphemeral(s, i, fmt.Sprintf("There is no song number %d in the queue (it has %d).", from, size))
return
}
if to > size {
to = size
}
err, msg = music.Reorder(g, e.QueueID, to), fmt.Sprintf("Moved **%s** to number %d.", title(e), to)
default:
shared.RespondEphemeral(s, i, "Unknown subcommand.")
return
}
if err != nil {
shared.RespondEphemeral(s, i, "That didn't work: "+err.Error())
return
}
shared.RespondEphemeral(s, i, msg)
}