diff --git a/modules/bot/front/CMakeLists.txt b/modules/bot/front/CMakeLists.txt index 206c47f..19ee60a 100644 --- a/modules/bot/front/CMakeLists.txt +++ b/modules/bot/front/CMakeLists.txt @@ -2,10 +2,11 @@ cmake_minimum_required(VERSION 3.10.2) project(AnimeBot) file(GLOB SOURCES "src/*.cpp") -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") set(Boost_USE_MULTITHREADED ON) +set(CMAKE_BUILD_TYPE Debug) find_package(Threads REQUIRED) find_package(OpenSSL REQUIRED) diff --git a/modules/bot/front/include/KeyboardFactory.hpp b/modules/bot/front/include/KeyboardFactory.hpp index 9e15982..0d3d5f0 100644 --- a/modules/bot/front/include/KeyboardFactory.hpp +++ b/modules/bot/front/include/KeyboardFactory.hpp @@ -1,7 +1,11 @@ #include +#include "structs.hpp" class KeyboardFactory { public: /// Create keyboard for main menu static TgBot::InlineKeyboardMarkup::Ptr createMainMenu(); + + /// Create keyboard for My_Titles + static TgBot::InlineKeyboardMarkup::Ptr createMyTitles(std::vector titles); }; diff --git a/modules/bot/front/include/constants.hpp b/modules/bot/front/include/constants.hpp index 212a88f..595a369 100644 --- a/modules/bot/front/include/constants.hpp +++ b/modules/bot/front/include/constants.hpp @@ -6,9 +6,26 @@ namespace BotConstants { namespace Button { const std::string FIND_ANIME = "Найти аниме"; const std::string MY_TITLES = "Мои тайтлы"; + const std::string PREV = "<<Назад"; + const std::string NEXT = "Дальше>>"; } namespace Callback { - const std::string FIND_ANIME = "action:find_anime"; - const std::string MY_TITLES = "navigation:my_titles"; + const std::string ACTION = "action:"; + const std::string FIND_ANIME = ACTION + "find_anime"; + const std::string ADD_REVIEW = ACTION + "add_review"; + const std::string ADD_STATUS = ACTION + "add_status"; + const std::string STATUS = "status:"; + const std::string WATCHING = STATUS + "watching"; + const std::string SEEN = STATUS + "seen"; + const std::string WANT = STATUS + "want"; + const std::string THROWN = STATUS + "thrown"; + const std::string NAVIGATION = "navigation:"; + const std::string MY_TITLES = NAVIGATION + "my_titles"; + const std::string LIST_PREV = NAVIGATION + "prev"; + const std::string LIST_NEXT = NAVIGATION + "next"; + const std::string CHOICE = "choice:"; + } + namespace Text { + const std::string MAIN_MENU = "Вас приветствует nyanimedb бот:)\nЧего будем делать?"; } } diff --git a/modules/bot/front/include/handlers.hpp b/modules/bot/front/include/handlers.hpp new file mode 100644 index 0000000..27aee3a --- /dev/null +++ b/modules/bot/front/include/handlers.hpp @@ -0,0 +1,24 @@ +#include <tgbot/tgbot.h> +#include <string> +#include <structs.hpp> + +/// @brief Структура возвращаемого значения класса BotHandlers для изменения текущего сообщения +struct HandlerResult { + std::string message; + TgBot::InlineKeyboardMarkup::Ptr keyboard; +}; + +class BotHandlers { +public: + void handleCallback(const TgBot::CallbackQuery::Ptr query); + +private: + TgBot::Api botApi; + + void handleNavigation(const TgBot::CallbackQuery::Ptr query); + + /// @brief Получить очередную страницу тайтлов из списка пользователя + /// @param userId Идентификатор пользователя + /// @return HandlerResult + static HandlerResult returnMyTitles(int64_t userId); +}; diff --git a/modules/bot/front/include/structs.hpp b/modules/bot/front/include/structs.hpp new file mode 100644 index 0000000..57f5e4a --- /dev/null +++ b/modules/bot/front/include/structs.hpp @@ -0,0 +1,8 @@ +#pragma once + +struct Title { + int64_t id; + std::string name; + std::string description; + int64_t num; +}; diff --git a/modules/bot/front/src/KeyboardFactory.cpp b/modules/bot/front/src/KeyboardFactory.cpp index 1bd2cab..bc1bdd0 100644 --- a/modules/bot/front/src/KeyboardFactory.cpp +++ b/modules/bot/front/src/KeyboardFactory.cpp @@ -13,3 +13,46 @@ TgBot::InlineKeyboardMarkup::Ptr KeyboardFactory::createMainMenu() { keyboard->inlineKeyboard = {{button1, button2}}; return keyboard; } + +TgBot::InlineKeyboardMarkup::Ptr KeyboardFactory::createMyTitles(std::vector<Title> titles) { + auto keyboard = std::make_shared<TgBot::InlineKeyboardMarkup>(); + std::vector<TgBot::InlineKeyboardButton::Ptr> row; + std::vector<std::vector<TgBot::InlineKeyboardButton::Ptr>> layout; + + int counter = 0; + for(Title& title : titles) { + if(counter >= 6) { + break; + } + auto button = std::make_shared<TgBot::InlineKeyboardButton>(); + button->text = std::to_string(title.num) + " " + title.name; + button->callbackData = "title:" + std::to_string(title.num); + row.push_back(button); + counter++; + if(counter % 2 == 0) { + layout.push_back(row); + row.clear(); + } + } + + // TODO: Додумать логику, когда пришло 6 записей в конце + if(counter % 2 == 1) { + auto button = std::make_shared<TgBot::InlineKeyboardButton>(); + button->text = BotConstants::Button::PREV; + button->callbackData = BotConstants::Callback::LIST_PREV + std::to_string(titles[0].num); + layout[counter / 2].push_back(button); + } + else { + auto button_prev = std::make_shared<TgBot::InlineKeyboardButton>(); + button_prev->text = BotConstants::Button::PREV; + button_prev->callbackData = BotConstants::Callback::LIST_PREV + std::to_string(titles[0].num); + auto button_next = std::make_shared<TgBot::InlineKeyboardButton>(); + button_next->text = BotConstants::Button::NEXT; + button_next->callbackData = BotConstants::Callback::LIST_NEXT + std::to_string(titles[5].num); + layout.push_back({button_prev, button_next}); + } + + keyboard->inlineKeyboard = layout; + + return keyboard; +} diff --git a/modules/bot/front/src/front.cpp b/modules/bot/front/src/front.cpp index d6a0b88..e6d3034 100644 --- a/modules/bot/front/src/front.cpp +++ b/modules/bot/front/src/front.cpp @@ -1,5 +1,7 @@ #include "front.hpp" #include "KeyboardFactory.hpp" +#include "constants.hpp" +#include "handlers.hpp" AnimeBot::AnimeBot(const std::string& token) : bot(token) { setupHandlers(); @@ -9,13 +11,34 @@ void AnimeBot::setupHandlers() { bot.getEvents().onCommand("start", [this](TgBot::Message::Ptr message) { sendMainMenu(message->chat->id); }); + + auto [text, kb] = BotHandlers::returnMyTitles(321); + + auto cp_api = bot.getApi(); + bot.getEvents().onCallbackQuery([text, kb, cp_api](TgBot::CallbackQuery::Ptr query) { + cp_api.editMessageText( + text, + query->message->chat->id, + query->message->messageId, + "", + "", + nullptr, + kb + ); + }); } void AnimeBot::sendMainMenu(int64_t chatId) { auto keyboard = KeyboardFactory::createMainMenu(); - bot.getApi().sendMessage(chatId, "Главное меню", nullptr, nullptr, keyboard); + bot.getApi().sendMessage(chatId, BotConstants::Text::MAIN_MENU, nullptr, nullptr, keyboard); } TgBot::Bot& AnimeBot::getBot() { return bot; } + +/* +void AnimeBot::showMyTitles() { + +} +*/ diff --git a/modules/bot/front/src/handlers.cpp b/modules/bot/front/src/handlers.cpp new file mode 100644 index 0000000..cbd90da --- /dev/null +++ b/modules/bot/front/src/handlers.cpp @@ -0,0 +1,28 @@ +#include "handlers.hpp" +#include "KeyboardFactory.hpp" +#include "structs.hpp" +#include "constants.hpp" + +void BotHandlers::handleCallback(const TgBot::CallbackQuery::Ptr query) { + std::string data = query -> data; + + if (data.starts_with(BotConstants::Callback::NAVIGATION)) { + handleNavigation(query); + } +} + +/// В угоду потокобезопасности создаем новый экземпляр TgBot::Api +HandlerResult BotHandlers::returnMyTitles(int64_t userId) { + // Здесь должен происходить запрос на сервер + std::vector<Title> titles = {{123, "Школа мертвяков", "", 1}, {321, "KissXsis", "", 2}}; + + struct HandlerResult result; + result.keyboard = KeyboardFactory::createMyTitles(titles); + result.message = "1. Школа мертвяков\n2. KissXsis\n"; + + return result; +} + +void BotHandlers::handleNavigation(const TgBot::CallbackQuery::Ptr query) { + return; +}