From 5f12e3838b2d9c838f50926a42a01b8a257506a3 Mon Sep 17 00:00:00 2001 From: db123 Date: Wed, 24 Jun 2026 20:59:49 +0330 Subject: [PATCH] feat: add break threshold picker UI to settings with preset values Replaces the text-only instructions with a grid of common break thresholds (0/5/10/15/30 min, 1/2/4/8h) matching the accent picker pattern. --- internal/bot/handlers.go | 4 +++ internal/bot/settings.go | 63 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/internal/bot/handlers.go b/internal/bot/handlers.go index 4deef06..b4f0308 100644 --- a/internal/bot/handlers.go +++ b/internal/bot/handlers.go @@ -260,6 +260,10 @@ func (h *Handler) HandleCallback(ctx context.Context, cb *models.CallbackQuery) h.handleExportCallback(ctx, chatID, msgID, cb.ID, cb.Data) return } + if len(cb.Data) > 15 && cb.Data[:15] == "breakthreshold_" { + h.selectBreakThreshold(ctx, chatID, msgID, cb.ID, cb.Data[15:]) + return + } h.handleHistoryCallback(ctx, chatID, msgID, cb.ID, cb.Data) } } diff --git a/internal/bot/settings.go b/internal/bot/settings.go index 9400768..c192cf8 100644 --- a/internal/bot/settings.go +++ b/internal/bot/settings.go @@ -272,16 +272,67 @@ func (h *Handler) reportTimeCallback(ctx context.Context, chatID int64, msgID in h.editText(ctx, chatID, msgID, text, &kb) } -// breakThresholdCallback shows the current break threshold and how to change it. +// breakThresholdCallback shows the break threshold picker. func (h *Handler) breakThresholdCallback(ctx context.Context, chatID int64, msgID int, callbackID string) { h.answerCb(ctx, callbackID) bt := h.getTodayBreakThreshold(chatID) - text := fmt.Sprintf("Current break threshold: %dm\n\nUse /setbreak to change it (0-480).\nGaps shorter than the threshold are absorbed into work time.", bt/60) - kb := models.InlineKeyboardMarkup{ - InlineKeyboard: [][]models.InlineKeyboardButton{ - {{Text: "Back to Settings", CallbackData: "back_settings"}}, - }, + text, kb := h.buildBreakThresholdKeyboard(bt) + h.editText(ctx, chatID, msgID, text, &kb) +} + +// buildBreakThresholdKeyboard returns the break threshold picker. +func (h *Handler) buildBreakThresholdKeyboard(current int64) (string, models.InlineKeyboardMarkup) { + values := []int{0, 5, 10, 15, 30, 60, 120, 240, 480} + labels := map[int]string{ + 0: "0 (off)", + 5: "5 min", + 10: "10 min", + 15: "15 min", + 30: "30 min", + 60: "1h", + 120: "2h", + 240: "4h", + 480: "8h", } + rows := [][]models.InlineKeyboardButton{} + for _, v := range values { + label := labels[v] + if int(current/60) == v { + label = "> " + label + } + rows = append(rows, []models.InlineKeyboardButton{ + {Text: label, CallbackData: fmt.Sprintf("breakthreshold_%d", v)}, + }) + } + rows = append(rows, []models.InlineKeyboardButton{ + {Text: "Back to Settings", CallbackData: "back_settings"}, + }) + return "Select break threshold:", models.InlineKeyboardMarkup{InlineKeyboard: rows} +} + +// selectBreakThreshold saves the chosen break threshold and returns to settings. +func (h *Handler) selectBreakThreshold(ctx context.Context, chatID int64, msgID int, callbackID, valStr string) { + h.answerCb(ctx, callbackID) + mins, err := strconv.Atoi(valStr) + if err != nil || mins < 0 || mins > 480 { + return + } + user, err := h.getOrCreateUser(chatID) + if err != nil { + return + } + now := time.Now() + date := now.Format("2006-01-02") + day, err := h.DB.GetOrCreateDay(user.ID, date) + if err != nil { + return + } + day.MinBreakThreshold = int64(mins) * 60 + if err := h.DB.UpdateDay(day); err != nil { + return + } + bt := h.getTodayBreakThreshold(chatID) + text, kb := h.buildSettingsKeyboard(user, bt) h.editText(ctx, chatID, msgID, text, &kb) }