nyanimedb/modules/bot/front/include/handlers.hpp
2025-12-06 01:59:28 +03:00

127 lines
6.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <tgbot/tgbot.h>
#include <string>
#include <structs.hpp>
#include <unordered_map>
#include "BotToServer.hpp"
/// @brief Структура возвращаемого значения класса BotHandlers для изменения текущего сообщения
struct HandlerResult {
std::string message;
TgBot::InlineKeyboardMarkup::Ptr keyboard;
};
enum class UserState {
MAIN_MENU, // Главное меню
VIEWING_MY_TITLES, // Список моих тайтлов
AWAITING_TITLE_NAME, // Жду название тайтла для поиска
VIEWING_FOUND_TITLES, // Смотрю найденные тайтлы
VIEWING_TITLE_PAGE, // Смотрю страничку тайтла
AWAITING_REVIEW, // Жду ревью на тайтл
VIEWING_REVIEW_LIST, // Смотрю список ревью на тайтл
VIEWING_REVIEW, // Смотрю (конкретное) ревью на тайтл
VIEWING_DESCRIPTION, // Смотрю описание тайтла
ERROR, // Ошибка состояния
};
struct NavigationStep {
UserState state;
int64_t payload; // ID тайтла, ревью и т.д.
};
struct UserContext {
int64_t userId;
std::vector<NavigationStep> history; // Текущее состояние пользователя + история предыдущих состояний
};
class BotHandlers {
public:
BotHandlers(TgBot::Api api) : botApi(api) {;}
/// @brief Обработка callback'ов из кнопок интерфейса
/// @param query запрос callback
void handleCallback(TgBot::CallbackQuery::Ptr query);
/// @brief Обработка сообщений боту
/// @details
/// Функция для обработки сообщений, которые юзер отправляет
/// боту. Необходима для обработки ревью и названий искомого
/// аниме. Внутри себя проверяет текущий state пользователя
/// в боте.
/// @param message обрабатываемое сообщение
void handleMessage(TgBot::Message::Ptr message);
/// @brief Создает контекст начального меню для пользователя
/// @param chatId id чата пользователя
void createInitContext(int64_t chatId);
private:
TgBot::Api botApi;
std::unordered_map<int64_t, UserContext> userContexts;
BotToServer server_;
void handleNavigation(TgBot::CallbackQuery::Ptr query, UserContext& ctx);
void handleError(TgBot::CallbackQuery::Ptr query, UserContext& ctx);
void processCallbackImpl(TgBot::CallbackQuery::Ptr query);
/// @brief Получить очередную страницу тайтлов из списка пользователя
/// @param userId Идентификатор пользователя
/// @param payload Полезная нагрузка
/// @return HandlerResult
/// static HandlerResult returnMyTitles(int64_t userId, int64_t payload);
/// @brief Вход в новое состояние
/// @param ctx текущий контекст
/// @param newState новое состояние, добавляемое в стек
/// @param payload полезная нагрузка этого состояния
void pushState(UserContext& ctx, UserState newState, int64_t payload);
/// @brief Возврат в предыдущее состояние
/// @param ctx Текущий контекст
/// @return true в случае успеха
bool popState(UserContext& ctx);
/// @brief Уменьшает значение нагрузки с учетом текущего состояния
/// @param payload Изменяемое значение нагрузки
/// @param curState Текущее состояние
void reducePayload(int64_t& payload, const UserState curState);
/// @brief Увеличивает значение нагрузки с учетом текущего состояния
/// @param payload Изменяемое значение нагрузки
/// @param curState Текущее состояние
void increasePayload(int64_t& payload, const UserState curState);
/// @brief Редактирует текущее сообщение в диалоге с пользователем
/// @details Меняет текст сообщения и клавиатуру на те, что передаются
/// в аргументе response. Информацию об id чата и изменяемого сообщения
/// забирает из query, который возвращается с callback'ом после нажатия
/// кнопки в интерфейсе
/// @param query Callback запрос
/// @param response Параметры ответа: клавиатура и текст
void editMessage(int64_t chatId, int64_t messageId, HandlerResult response);
/// @brief Отрисовка текущего экрана (соотв. контексту)
/// @param ctx - текущий контекст
void renderCurrent(TgBot::CallbackQuery::Ptr query, const UserContext& ctx);
/// @brief Логика переходов между контекстами (навигация на следующий шаг)
/// @param query - запрос
/// @param current - текущий шаг навигации
/// @return следующий NavigationStep при успехе (std::nullopt в случае ошибки)
std::optional<NavigationStep> computeNextStep(const TgBot::CallbackQuery::Ptr& query,
const NavigationStep& current);
/// @brief Получить состояние страницы главного меню
/// @return HandlerResult с параметрами главного меню
HandlerResult showMainMenu();
/// @brief Посылает интерфейс обработки ошибки на callback запрос
/// @param query запрос
void sendError(int64_t chatId, int64_t messageId, const std::string& errText);
// Форматирование для отображения в сообщении
std::string formatTitlesList(const std::vector<BotStructs::Title>& titles);
};