package ui import ( "fmt" "github.com/NicoNex/echotron/v3" ) // PaginationConfig конфигурация для построения навигационного ряда пагинации type PaginationConfig struct { CurrentPage int TotalPages int // Для API пагинации (из page.Pages) TotalItems int // Для локальной пагинации (len(array)) ItemsPerPage int // Для расчета TotalPages из TotalItems PrevCallback string // По умолчанию "prev" NextCallback string // По умолчанию "next" MiddleButtons []echotron.InlineKeyboardButton // Опциональные кнопки в центре (например, "+ Добавить") } // BuildNavigationRow создает навигационный ряд с динамической шириной. // Показывает ряд только если страниц > 1. // Возвращает nil если пагинация не нужна. func BuildNavigationRow(config PaginationConfig) []echotron.InlineKeyboardButton { // Вычисляем TotalPages из TotalItems если не задан totalPages := config.TotalPages if totalPages == 0 && config.TotalItems > 0 && config.ItemsPerPage > 0 { totalPages = CalculatePages(config.TotalItems, config.ItemsPerPage) } // Устанавливаем значения по умолчанию для callbacks prevCallback := config.PrevCallback if prevCallback == "" { prevCallback = "prev" } nextCallback := config.NextCallback if nextCallback == "" { nextCallback = "next" } var row []echotron.InlineKeyboardButton // Левая стрелка (только если есть предыдущая страница) if totalPages > 1 && config.CurrentPage > 0 { row = append(row, echotron.InlineKeyboardButton{ Text: "←", CallbackData: prevCallback, }) } // Средние кнопки (если есть) if len(config.MiddleButtons) > 0 { row = append(row, config.MiddleButtons...) } // Правая стрелка (только если есть следующая страница) if totalPages > 1 && config.CurrentPage+1 < totalPages { row = append(row, echotron.InlineKeyboardButton{ Text: "→", CallbackData: nextCallback, }) } if len(row) == 0 { return nil } return row } // CalculatePages вычисляет количество страниц из общего количества элементов func CalculatePages(totalItems, itemsPerPage int) int { if itemsPerPage <= 0 { return 0 } return (totalItems + itemsPerPage - 1) / itemsPerPage } // GetPageBounds возвращает start/end индексы для текущей страницы. // Автоматически сбрасывает на первую страницу если currentPage выходит за границы. func GetPageBounds(currentPage, itemsPerPage, totalItems int) (start, end int) { start = currentPage * itemsPerPage if start >= totalItems { start = 0 } end = start + itemsPerPage if end > totalItems { end = totalItems } return start, end } // FormatPageInfo форматирует текст индикатора страницы для заголовка func FormatPageInfo(currentPage, totalPages int) string { if totalPages <= 1 { return "" } return fmt.Sprintf(" (стр. %d/%d)", currentPage+1, totalPages) }