From 189a932d52dce9712e269eac5f8530b0b68710b4 Mon Sep 17 00:00:00 2001 From: Vovko Date: Sat, 21 Mar 2026 14:03:30 -0500 Subject: [PATCH] more consistent command --- cmd/discord/commands/public/theme.go | 129 +++++++++++++------------ static/localization/en/discord.yaml | 8 +- static/localization/pl/discord.yaml | 6 +- static/localization/pt-BR/discord.yaml | 6 +- 4 files changed, 82 insertions(+), 67 deletions(-) diff --git a/cmd/discord/commands/public/theme.go b/cmd/discord/commands/public/theme.go index f2947de7..b030ce6b 100644 --- a/cmd/discord/commands/public/theme.go +++ b/cmd/discord/commands/public/theme.go @@ -31,57 +31,90 @@ func init() { Ephemeral(). Params(builder.SetNameKey("command_theme_name"), builder.SetDescKey("command_theme_description")). Options( - builder.NewOption("select", discordgo.ApplicationCommandOptionString). + builder.NewOption("select", discordgo.ApplicationCommandOptionSubCommand). Params(builder.SetNameKey("command_theme_option_select_name"), builder.SetDescKey("command_theme_option_select_description")). - Choices(buildThemeChoices()...), - builder.NewOption("clear", discordgo.ApplicationCommandOptionBoolean). + Options( + builder.NewOption("theme", discordgo.ApplicationCommandOptionString). + Choices(buildThemeChoices()...), + ), + builder.NewOption("clear", discordgo.ApplicationCommandOptionSubCommand). Params(builder.SetNameKey("command_theme_option_clear_name"), builder.SetDescKey("command_theme_option_clear_description")), ). Handler(func(ctx common.Context) error { - if clear, ok := common.GetOption[bool](ctx.Options(), "clear"); ok && clear { - existing, err := ctx.Core().Database().GetUserContentFromRef(ctx.Ctx(), ctx.User().ID, models.UserContentTypeThemePreference) - if err != nil && !database.IsNotFound(err) { - return ctx.Err(err, common.ApplicationError) + subcommand, subOptions, _ := ctx.Options().Subcommand() + switch subcommand { + default: + return ctx.Reply().Send("command_theme_current_fmt") + + case "select": + selected, hasSelection := common.GetOption[string](subOptions, "theme") + if !hasSelection { + currentTheme, hasTheme := ctx.User().Content(models.UserContentTypeThemePreference) + var currentID string + if hasTheme { + currentID = string(currentTheme.Value) + } else { + currentID = "default" + } + + ids := themes.AvailableThemes() + sort.Strings(ids) + + var lines []string + for _, id := range ids { + name := ctx.Localize(fmt.Sprintf("command_theme_select_option_theme_choice_%s_name", id)) + if name == "" { + name = id + } + if id == currentID { + lines = append(lines, "⬢ "+name) + } else { + lines = append(lines, "⬡ "+name) + } + } + + return ctx.Reply().Format("command_theme_current_fmt", strings.Join(lines, "\n")).Send() } - if !database.IsNotFound(err) { - err = ctx.Core().Database().DeleteUserContent(ctx.Ctx(), existing.ID) - if err != nil { + + if selected == "default" { + existing, err := ctx.Core().Database().GetUserContentFromRef(ctx.Ctx(), ctx.User().ID, models.UserContentTypeThemePreference) + if err != nil && !database.IsNotFound(err) { return ctx.Err(err, common.ApplicationError) } + if !database.IsNotFound(err) { + err = ctx.Core().Database().DeleteUserContent(ctx.Ctx(), existing.ID) + if err != nil { + return ctx.Err(err, common.ApplicationError) + } + } + return ctx.Reply().Send("command_theme_reset_success") } - return ctx.Reply().Send("command_theme_reset_success") - } - selected, hasSelection := common.GetOption[string](ctx.Options(), "select") - if !hasSelection { - currentTheme, hasTheme := ctx.User().Content(models.UserContentTypeThemePreference) - var currentID string - if hasTheme { - currentID = string(currentTheme.Value) - } else { - currentID = "default" + if _, ok := themes.GetTheme(selected); !ok { + return ctx.Reply().IsError(common.UserError).Send("command_theme_not_found") } - ids := themes.AvailableThemes() - sort.Strings(ids) - - var lines []string - for _, id := range ids { - name := ctx.Localize(fmt.Sprintf("command_theme_option_select_choice_%s_name", id)) - if name == "" { - name = id - } - if id == currentID { - lines = append(lines, "⬢ "+name) - } else { - lines = append(lines, "⬡ "+name) + existing, err := ctx.Core().Database().GetUserContentFromRef(ctx.Ctx(), ctx.User().ID, models.UserContentTypeThemePreference) + if err != nil && !database.IsNotFound(err) { + return ctx.Err(err, common.ApplicationError) + } + if database.IsNotFound(err) { + existing = models.UserContent{ + UserID: ctx.User().ID, + ReferenceID: ctx.User().ID, } } - return ctx.Reply().Format("command_theme_current_fmt", strings.Join(lines, "\n")).Send() - } + existing.Type = models.UserContentTypeThemePreference + existing.Value = []byte(selected) + _, err = ctx.Core().Database().UpsertUserContent(ctx.Ctx(), existing) + if err != nil { + return ctx.Err(err, common.ApplicationError) + } + + return ctx.Reply().Format("command_theme_set_success_fmt", selected).Send() - if selected == "default" { + case "clear": existing, err := ctx.Core().Database().GetUserContentFromRef(ctx.Ctx(), ctx.User().ID, models.UserContentTypeThemePreference) if err != nil && !database.IsNotFound(err) { return ctx.Err(err, common.ApplicationError) @@ -94,30 +127,6 @@ func init() { } return ctx.Reply().Send("command_theme_reset_success") } - - if _, ok := themes.GetTheme(selected); !ok { - return ctx.Reply().IsError(common.UserError).Send("command_theme_not_found") - } - - existing, err := ctx.Core().Database().GetUserContentFromRef(ctx.Ctx(), ctx.User().ID, models.UserContentTypeThemePreference) - if err != nil && !database.IsNotFound(err) { - return ctx.Err(err, common.ApplicationError) - } - if database.IsNotFound(err) { - existing = models.UserContent{ - UserID: ctx.User().ID, - ReferenceID: ctx.User().ID, - } - } - - existing.Type = models.UserContentTypeThemePreference - existing.Value = []byte(selected) - _, err = ctx.Core().Database().UpsertUserContent(ctx.Ctx(), existing) - if err != nil { - return ctx.Err(err, common.ApplicationError) - } - - return ctx.Reply().Format("command_theme_set_success_fmt", selected).Send() }), ) } diff --git a/static/localization/en/discord.yaml b/static/localization/en/discord.yaml index f7133d5c..0ec75041 100644 --- a/static/localization/en/discord.yaml +++ b/static/localization/en/discord.yaml @@ -242,9 +242,11 @@ wargaming_error_private_account: "This account is marked private by Wargaming an command_theme_name: "theme" command_theme_description: "Change the visual theme of your stats images" command_theme_option_select_name: "select" -command_theme_option_select_description: "Pick a theme to apply to your stats" -command_theme_option_select_choice_default_name: "Default" -command_theme_option_select_choice_spring2026_name: "Sakura Flutter" +command_theme_option_select_description: "Select a theme for your stats images" +command_theme_select_option_theme_name: "theme" +command_theme_select_option_theme_description: "Pick a theme to apply to your stats" +command_theme_select_option_theme_choice_default_name: "Default" +command_theme_select_option_theme_choice_spring2026_name: "Sakura Flutter" command_theme_option_clear_name: "clear" command_theme_option_clear_description: "Remove your current theme and go back to default" command_theme_set_success_fmt: "Your theme has been updated to **%s**! It will be applied to your next stats image." diff --git a/static/localization/pl/discord.yaml b/static/localization/pl/discord.yaml index 8866cc00..8cf2bdea 100644 --- a/static/localization/pl/discord.yaml +++ b/static/localization/pl/discord.yaml @@ -243,8 +243,10 @@ command_theme_name: "motyw" command_theme_description: "Zmień motyw wizualny swoich obrazów statystyk" command_theme_option_select_name: "wybierz" command_theme_option_select_description: "Wybierz motyw do zastosowania w statystykach" -command_theme_option_select_choice_default_name: "Domyślny" -command_theme_option_select_choice_spring2026_name: "Sakura Flutter" +command_theme_select_option_theme_name: "motyw" +command_theme_select_option_theme_description: "Wybierz motyw do zastosowania w statystykach" +command_theme_select_option_theme_choice_default_name: "Domyślny" +command_theme_select_option_theme_choice_spring2026_name: "Sakura Flutter" command_theme_option_clear_name: "wyczyść" command_theme_option_clear_description: "Usuń aktualny motyw i wróć do domyślnego" command_theme_set_success_fmt: "Twój motyw został zmieniony na **%s**! Zostanie zastosowany do następnego obrazu statystyk." diff --git a/static/localization/pt-BR/discord.yaml b/static/localization/pt-BR/discord.yaml index 41c65e18..7e76447f 100644 --- a/static/localization/pt-BR/discord.yaml +++ b/static/localization/pt-BR/discord.yaml @@ -243,8 +243,10 @@ command_theme_name: "tema" command_theme_description: "Altere o tema visual das suas imagens de estatísticas" command_theme_option_select_name: "selecionar" command_theme_option_select_description: "Escolha um tema para aplicar às suas estatísticas" -command_theme_option_select_choice_default_name: "Padrão" -command_theme_option_select_choice_spring2026_name: "Sakura Flutter" +command_theme_select_option_theme_name: "tema" +command_theme_select_option_theme_description: "Escolha um tema para aplicar às suas estatísticas" +command_theme_select_option_theme_choice_default_name: "Padrão" +command_theme_select_option_theme_choice_spring2026_name: "Sakura Flutter" command_theme_option_clear_name: "limpar" command_theme_option_clear_description: "Remova seu tema atual e volte ao padrão" command_theme_set_success_fmt: "Seu tema foi atualizado para **%s**! Ele será aplicado na sua próxima imagem de estatísticas."