#include "handlers.hpp" #include "KeyboardFactory.hpp" #include "structs.hpp" #include "constants.hpp" void BotHandlers::handleNavigation(TgBot::CallbackQuery::Ptr query, UserContext& ctx) { const auto& current = ctx.history.back(); // текущий экран const std::string& data = query->data; int64_t chatId = query->message->chat->id; int64_t messageId = query->message->messageId; // Пагинация (в списках) if ((data == BotConstants::Callback::LIST_PREV || data == BotConstants::Callback::LIST_NEXT) && (current.state == UserState::VIEWING_MY_TITLES || current.state == UserState::VIEWING_REVIEW_LIST || current.state == UserState::VIEWING_FOUND_TITLES)) { int64_t newPayload = current.payload; if (data == BotConstants::Callback::LIST_PREV && newPayload > 0) { reducePayload(newPayload, current.state); } else if (data == BotConstants::Callback::LIST_NEXT) { increasePayload(newPayload, current.state); } else { if (data == BotConstants::Callback::LIST_PREV) { std::cout << "Error: navigation:prev callback for 1st page" << std::endl; return; } // TODO: log std::cout << "Error: navigation:prev unknown error" << std::endl; } ctx.history.back().payload = newPayload; auto result = renderCurrent(query, ctx); if(result.message == "meow") return; // TODO: убрать editMessage(chatId, messageId, result); return; } // Обработка back по интерфейсу if (data == BotConstants::Callback::NAV_BACK) { if (!popState(ctx)) { sendError(chatId, messageId, BotConstants::Text::SAD_ERROR); return; } auto result = renderCurrent(query, ctx); if(result.message == "meow") return; // TODO: убрать editMessage(chatId, messageId, result); return; } // Переходы вперёд (pyush) auto newStepOpt = computeNextStep(query, current); if (!newStepOpt.has_value()) { sendError(chatId, messageId, BotConstants::Text::SAD_ERROR); return; } ctx.history.push_back(*newStepOpt); auto result = renderCurrent(query, ctx); if(result.message == "meow") return; // TODO: убрать editMessage(chatId, messageId, result); } HandlerResult BotHandlers::renderCurrent(TgBot::CallbackQuery::Ptr query, const UserContext& ctx) { const auto& step = ctx.history.back(); //int64_t userId = query->from->id; int64_t chatId = query->message->chat->id; int64_t messageId = query->message->messageId; switch (step.state) { case UserState::MAIN_MENU: return showMainMenu(); case UserState::VIEWING_MY_TITLES: server_.fetchUserTitlesAsync(std::to_string(2)) // ALARM: тестовое значение вместо userId .then([this, chatId, messageId](pplx::task> t) { try { auto titles = t.get(); std::string message = formatTitlesList(titles); auto keyboard = KeyboardFactory::createMyTitles(titles); editMessage(chatId, messageId, {message, keyboard}); } catch (const std::exception& e) { sendError(chatId, messageId, BotConstants::Text::SERVER_ERROR); // Логирование ошибки (например, в cerr) } }); return {"meow", nullptr}; /* case UserState::VIEWING_TITLE_PAGE: return returnTitlePage(step.payload); // payload = titleId case UserState::VIEWING_REVIEW: return returnReview(step.payload); // payload = reviewId case UserState::AWAITING_REVIEW: return HandlerResult{"Пришлите текст отзыва:", nullptr}; // ... */ default: return HandlerResult{BotConstants::Text::SAD_ERROR, nullptr}; } } std::optional BotHandlers::computeNextStep( const TgBot::CallbackQuery::Ptr& query, const NavigationStep& current ) { const std::string& data = query->data; switch (current.state) { case UserState::MAIN_MENU: if (data == BotConstants::Callback::MY_TITLES) { return NavigationStep{UserState::VIEWING_MY_TITLES, 0}; } break; /* case UserState::VIEWING_MY_TITLES: if (data.starts_with("title_")) { int64_t titleId = parseId(data); return NavigationStep{UserState::VIEWING_TITLE_PAGE, titleId}; } break; case UserState::VIEWING_TITLE_PAGE: if (data == BotConstants::Callback::ACTION_ADD_REVIEW) { return NavigationStep{UserState::AWAITING_REVIEW, current.payload}; } if (data.starts_with("review_")) { int64_t reviewId = parseId(data); return NavigationStep{UserState::VIEWING_REVIEW, reviewId}; } break; */ default: break; } return std::nullopt; } std::string BotHandlers::formatTitlesList(const std::vector& titles) { if (titles.empty()) { return "У вас пока нет тайтлов."; } std::string msg; for (size_t i = 0; i < titles.size(); ++i) { // num — 0-based, но в сообщении показываем 1-based msg += std::to_string(i + 1) + ". " + titles[i].name + "\n"; } return msg; }