Files
FernandoJVideiraandClaude Opus 5.5 e10e1f7a86 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]>
2026-10-21 11:58:19 +01:00

60 lines
1.4 KiB
Go

package tickets
import (
"sync"
"time"
)
// Discord doesn't send a dropdown's value along with a button click, so the
// panel's category pick is remembered here between the two interactions:
// per guild and member, for a short while, in memory. A bot restart forgets
// it, which only means picking the category again.
const (
pickTTL = 15 * time.Minute
maxPicks = 10000 // a ceiling, so a flood of picks can't grow this forever
)
type pickKey struct{ guild, user int64 }
type pick struct {
category int64
at time.Time
}
var (
picksMu sync.Mutex
picks = map[pickKey]pick{}
now = time.Now
)
// RememberPick records the category a member chose in the panel dropdown.
func RememberPick(guildID, userID, categoryID int64) {
picksMu.Lock()
defer picksMu.Unlock()
t := now()
k := pickKey{guildID, userID}
if _, ok := picks[k]; !ok && len(picks) >= maxPicks {
for k, p := range picks {
if t.Sub(p.at) > pickTTL {
delete(picks, k)
}
}
if len(picks) >= maxPicks {
return
}
}
picks[k] = pick{categoryID, t}
}
// PickedCategory returns the category a member chose, if they did recently.
func PickedCategory(guildID, userID int64) (int64, bool) {
picksMu.Lock()
defer picksMu.Unlock()
p, ok := picks[pickKey{guildID, userID}]
if !ok || now().Sub(p.at) > pickTTL {
delete(picks, pickKey{guildID, userID})
return 0, false
}
return p.category, true
}