Files
cyclingbot/bot/handlers_personal.go
Blake Ridgway ba1770b493 first commit
2026-04-11 14:06:59 -05:00

119 lines
4.2 KiB
Go

package bot
import (
"context"
"fmt"
"strings"
"time"
"github.com/bwmarrin/discordgo"
)
func (b *Bot) handleMyStats(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
userID := i.Member.User.ID
username := displayName(i.Member, i.Member.User)
unit, _ := b.db.GetUserPreference(ctx, userID, i.GuildID)
since := b.challengeStart(ctx, i.GuildID)
challenge, _ := b.db.GetUserStats(ctx, i.GuildID, userID, since)
yearly, _ := b.db.GetUserYearlyStats(ctx, i.GuildID, userID, time.Now().Year())
allTime, _ := b.db.GetUserStats(ctx, i.GuildID, userID, time.Time{})
pb, _ := b.db.GetUserPB(ctx, i.GuildID, userID)
streak, _ := b.db.GetUserStreak(ctx, userID)
kudos, _ := b.db.GetKudosReceived(ctx, i.GuildID, userID)
if allTime.LogCount == 0 {
respondEphemeral(s, i, "You haven't logged any distances yet. Post your rides in the fitness challenge channel!")
return
}
name, _, _ := b.db.GetSetting(ctx, i.GuildID, "challenge_name")
if name == "" {
name = "Challenge"
}
var sb strings.Builder
sb.WriteString(fmt.Sprintf("## 🚴 %s's Stats\n\n", username))
sb.WriteString(fmt.Sprintf("**%s:** %s (%d ride%s)\n", name,
formatDist(challenge.TotalKM, unit), challenge.LogCount, plural(challenge.LogCount)))
sb.WriteString(fmt.Sprintf("**%d:** %s (%d ride%s)\n", time.Now().Year(),
formatDist(yearly.TotalKM, unit), yearly.LogCount, plural(yearly.LogCount)))
sb.WriteString(fmt.Sprintf("**All time:** %s (%d ride%s)\n\n",
formatDist(allTime.TotalKM, unit), allTime.LogCount, plural(allTime.LogCount)))
sb.WriteString(fmt.Sprintf("**Personal best:** %s\n", formatDist(pb, unit)))
sb.WriteString(fmt.Sprintf("**Average ride:** %s\n", formatDist(allTime.TotalKM/float64(allTime.LogCount), unit)))
if streak > 0 {
sb.WriteString(fmt.Sprintf("**Current streak:** %d day%s 🔥\n", streak, plural(streak)))
}
if kudos > 0 {
sb.WriteString(fmt.Sprintf("**Kudos received:** %d 👏\n", kudos))
}
respondEphemeral(s, i, sb.String())
}
func (b *Bot) handleHistory(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
userID := i.Member.User.ID
unit, _ := b.db.GetUserPreference(ctx, userID, i.GuildID)
count := int(optInt(i.ApplicationCommandData().Options, "count", 5))
if count > 20 {
count = 20
}
logs, err := b.db.GetUserHistory(ctx, i.GuildID, userID, count)
if err != nil || len(logs) == 0 {
respondEphemeral(s, i, "No rides logged yet.")
return
}
var sb strings.Builder
sb.WriteString(fmt.Sprintf("## 🚴 Your Last %d Ride%s\n\n", len(logs), plural(len(logs))))
for _, l := range logs {
sb.WriteString(fmt.Sprintf("**%s** — %s\n", l.LoggedAt.Format("02 Jan 2006"), formatDist(l.KM, unit)))
}
respondEphemeral(s, i, sb.String())
}
func (b *Bot) handlePB(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
userID := i.Member.User.ID
unit, _ := b.db.GetUserPreference(ctx, userID, i.GuildID)
pb, err := b.db.GetUserPB(ctx, i.GuildID, userID)
if err != nil || pb == 0 {
respondEphemeral(s, i, "No rides logged yet.")
return
}
respondEphemeral(s, i, fmt.Sprintf("🏆 Your personal best single ride is **%s**!", formatDist(pb, unit)))
}
func (b *Bot) handleStreak(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
target := optUser(i.ApplicationCommandData().Options, "user", s)
var userID, username string
if target != nil {
userID = target.ID
username = target.Username
} else {
userID = i.Member.User.ID
username = displayName(i.Member, i.Member.User)
}
streak, err := b.db.GetUserStreak(ctx, userID)
if err != nil {
respondEphemeral(s, i, "Error fetching streak.")
return
}
if streak == 0 {
respondEphemeral(s, i, fmt.Sprintf("**%s** has no active streak. Get riding! 🚴", username))
return
}
respondEphemeral(s, i, fmt.Sprintf("🔥 **%s** is on a **%d day** streak!", username, streak))
}
func (b *Bot) handleSetUnit(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
unit := i.ApplicationCommandData().Options[0].StringValue()
if err := b.db.SetUserPreference(ctx, i.Member.User.ID, i.GuildID, unit); err != nil {
respondEphemeral(s, i, "Error saving preference.")
return
}
respondEphemeral(s, i, fmt.Sprintf("✅ Your stats will now show in **%s**.", unit))
}