Use a dropdown and a Create ticket button on the ticket panel, in orange

The panel is now one category dropdown and a Create ticket button
instead of a button per category. Discord doesn't send the dropdown's
value with a button click, so each member's pick is remembered in
memory for 15 minutes (per guild and member, capped). Panels posted
before keep working until they're reposted. Every ticket embed is
orange, closed tickets included.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
FernandoJVideiraandClaude Opus 5.5 committed 2026-10-21 11:58:19 +01:00
1 parent e453a9ba94
commit e10e1f7a86
8 files changed
+178 -50

No files matched your search

+31 -3
View File
@@ -60,7 +60,7 @@ var Tickets = &discordgo.ApplicationCommand{
{
Type: discordgo.ApplicationCommandOptionSubCommand,
Name: "add",
Description: "Add a category (one button on the panel)",
Description: "Add a category (an option in the panel's dropdown)",
Options: []*discordgo.ApplicationCommandOption{
{Type: discordgo.ApplicationCommandOptionString, Name: "name", Description: "e.g. Support, Report, Appeal", Required: true, MaxLength: 40},
{Type: discordgo.ApplicationCommandOptionRole, Name: "staff-role", Description: "Who handles these tickets"},
@@ -424,7 +424,7 @@ func closeTicket(s *discordgo.Session, i *discordgo.InteractionCreate, reason st
edit(s, i, "Ticket closed.")
}
// HandleComponent handles the panel buttons and dropdown and the Claim and
// HandleComponent handles the panel dropdown and Create ticket button and the Claim and
// Close buttons in a ticket.
func HandleComponent(s *discordgo.Session, i *discordgo.InteractionCreate) {
if Repo == nil {
@@ -434,9 +434,12 @@ func HandleComponent(s *discordgo.Session, i *discordgo.InteractionCreate) {
data := i.MessageComponentData()
switch {
case strings.HasPrefix(data.CustomID, "tickets:open:"):
// Panels posted before the dropdown had one button per category.
showOpenForm(s, i, strings.TrimPrefix(data.CustomID, "tickets:open:"))
case data.CustomID == "tickets:select" && len(data.Values) > 0:
showOpenForm(s, i, data.Values[0])
rememberPick(s, i, data.Values[0])
case data.CustomID == "tickets:create":
createFromPick(s, i)
case data.CustomID == "tickets:claim":
claim(s, i)
case data.CustomID == "tickets:close":
@@ -450,6 +453,31 @@ func HandleComponent(s *discordgo.Session, i *discordgo.InteractionCreate) {
}
}
// rememberPick stores the dropdown choice for the Create ticket button and
// acknowledges it without changing the panel, so the choice stays visible.
func rememberPick(s *discordgo.Session, i *discordgo.InteractionCreate, rawCategory string) {
catID, err := strconv.ParseInt(rawCategory, 10, 64)
if err != nil || i.Member == nil || i.Member.User == nil {
return
}
userID, _ := strconv.ParseInt(i.Member.User.ID, 10, 64)
tickets.RememberPick(guildID(i), userID, catID)
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{Type: discordgo.InteractionResponseDeferredMessageUpdate})
}
func createFromPick(s *discordgo.Session, i *discordgo.InteractionCreate) {
if i.Member == nil || i.Member.User == nil {
return
}
userID, _ := strconv.ParseInt(i.Member.User.ID, 10, 64)
catID, ok := tickets.PickedCategory(guildID(i), userID)
if !ok {
reply(s, i, "Pick a category from the menu first, then press **Create ticket**.")
return
}
showOpenForm(s, i, strconv.FormatInt(catID, 10))
}
func showOpenForm(s *discordgo.Session, i *discordgo.InteractionCreate, rawCategory string) {
catID, err := strconv.ParseInt(rawCategory, 10, 64)
if err != nil || i.Member == nil || i.Member.User == nil {