fix: currency validation, league mobile layout, settings 2-col, burnout ratio, add setusername

- Require both symbol+code in /setcurrency; add preset picker ($ USD,
  T Toman, IRR Rial, EUR, GBP) in settings inline menu
- League: compact 2-line per entry for mobile; sort buttons in 2x2 grid
- Settings: 2-column layout with grouped buttons (timezone+calendar,
  report+report time, break+accent, rpg+league, currency+rate)
- Burnout: cap break ratio at 100% to prevent nonsense values
- Add /setusername command (uses existing SanitizeDisplayName)
- Update /help with new/changed commands
This commit is contained in:
2026-06-25 01:46:07 +03:30
parent 344c615666
commit 605c41ab88
5 changed files with 136 additions and 66 deletions

View File

@@ -179,29 +179,39 @@ func (h *Handler) settingsCallback(ctx context.Context, chatID int64, msgID int,
// buildSettingsKeyboard returns the settings menu text and inline keyboard.
func (h *Handler) buildSettingsKeyboard(user *db.User, st *db.UserSettings, breakThreshold int64) (string, models.InlineKeyboardMarkup) {
reportStatus := "disabled"
reportStatus := "off"
if st.ReportEnabled {
reportStatus = "enabled"
reportStatus = "on"
}
rpgStatus := "disabled"
rpgStatus := "off"
if st.RPGEnabled {
rpgStatus = "enabled"
rpgStatus = "on"
}
leagueStatus := "disabled"
leagueStatus := "off"
if st.LeagueOptIn {
leagueStatus = "on"
}
rows := [][]models.InlineKeyboardButton{
{{Text: fmt.Sprintf("Timezone: %s", user.Timezone), CallbackData: "timezone"}},
{{Text: fmt.Sprintf("Accent: %s", st.ExportAccent), CallbackData: "accent"}},
{{Text: fmt.Sprintf("Calendar: %s", user.Calendar), CallbackData: "caltype"}},
{{Text: fmt.Sprintf("Report: %s", reportStatus), CallbackData: "reporttoggle"}},
{{Text: fmt.Sprintf("Report time: %s", st.ReportTime), CallbackData: "reporttime"}},
{{Text: fmt.Sprintf("Break threshold: %dm", breakThreshold/60), CallbackData: "breakthreshold"}},
{{Text: fmt.Sprintf("RPG: %s", rpgStatus), CallbackData: "rpgtoggle"}},
{{Text: fmt.Sprintf("League: %s", leagueStatus), CallbackData: "leaguetoggle"}},
{{Text: fmt.Sprintf("Currency: %s", st.Currency), CallbackData: "currency"}},
{{Text: fmt.Sprintf("Rate: %.2f", st.HourlyRate), CallbackData: "setrate"}},
{
{Text: fmt.Sprintf("Timezone: %s", user.Timezone), CallbackData: "timezone"},
{Text: fmt.Sprintf("Calendar: %s", user.Calendar), CallbackData: "caltype"},
},
{
{Text: fmt.Sprintf("Report: %s", reportStatus), CallbackData: "reporttoggle"},
{Text: fmt.Sprintf("Report time: %s", st.ReportTime), CallbackData: "reporttime"},
},
{
{Text: fmt.Sprintf("Break: %dm", breakThreshold/60), CallbackData: "breakthreshold"},
{Text: fmt.Sprintf("Accent: %s", st.ExportAccent), CallbackData: "accent"},
},
{
{Text: fmt.Sprintf("RPG: %s", rpgStatus), CallbackData: "rpgtoggle"},
{Text: fmt.Sprintf("League: %s", leagueStatus), CallbackData: "leaguetoggle"},
},
{
{Text: fmt.Sprintf("Currency: %s", st.Currency), CallbackData: "currency"},
{Text: fmt.Sprintf("Rate: %.2f", st.HourlyRate), CallbackData: "setrate"},
},
{{Text: "Back to Menu", CallbackData: "back_menu"}},
}
return "Settings:", models.InlineKeyboardMarkup{InlineKeyboard: rows}