diff --git a/inc/tgclient.h b/inc/tgclient.h index 91f58c1..853bf34 100644 --- a/inc/tgclient.h +++ b/inc/tgclient.h @@ -55,6 +55,9 @@ public: void registerChatFiltersCallback(ChatFiltersCallback cfclb); //exposed apicalls + void openChat(int64_t chatid); + void closeChat(int64_t chatid); + void deleteMessage(int64_t chatid, int64_t messageid, bool forall = true); void screenShottaken(int64_t chatid); diff --git a/inc/tgtui.h b/inc/tgtui.h index e1336e2..7a9f672 100644 --- a/inc/tgtui.h +++ b/inc/tgtui.h @@ -6,6 +6,8 @@ #include "tgclient.h" class View; +class ViewChat; +class ViewChatList; class TgTUI { public: @@ -19,16 +21,25 @@ public: const std::vector& getChats(); private: + enum class ViewMode { + ChatList = 0, + Chat = 1, + }; + void initDoneCB(); void threadLoop(); void handleNewChat(objptr chat); + void switchToView(ViewMode vm); + TGClient tgclient; + ViewMode currentViewMode; View* currentView = nullptr; - std::vector views; + ViewChatList* viewChatList = nullptr; + ViewChat* viewChat = nullptr; std::vector chats; bool shouldRun = false; diff --git a/inc/view.h b/inc/view.h index 5ca9b23..9a490c7 100644 --- a/inc/view.h +++ b/inc/view.h @@ -12,8 +12,13 @@ public: virtual void paint() = 0; - virtual bool keyIn(int key); + // return -2 -> exit + // return -1 -> keep current ViewMode + // return 0 <= -> switch to other ViewMode + virtual int keyIn(int key); protected: TgTUI& tgtui; + + int maxRows, maxCols; }; diff --git a/inc/viewchat.h b/inc/viewchat.h new file mode 100644 index 0000000..7a1ea29 --- /dev/null +++ b/inc/viewchat.h @@ -0,0 +1,21 @@ +#pragma once + +#include "slimchat.h" +#include "view.h" + +class ViewChat : public View { +public: + ViewChat(TgTUI& tgtui); + virtual ~ViewChat(); + + void setChat(const SlimChat* chat); + int64_t getChat() const; + + virtual void paint() override; + + virtual int keyIn(int key) override; + +private: + const SlimChat* chat = nullptr; + +}; diff --git a/inc/viewchatlist.h b/inc/viewchatlist.h index 5f284e8..cf93260 100644 --- a/inc/viewchatlist.h +++ b/inc/viewchatlist.h @@ -15,7 +15,7 @@ public: virtual void paint() override; - virtual bool keyIn(int key) override; + virtual int keyIn(int key) override; int64_t getSelectedChatId(); @@ -23,6 +23,4 @@ private: std::vector chats; int32_t currentChatOffset = 0; int32_t selectedChatRow = 0; - - int maxRows, maxCols; }; \ No newline at end of file diff --git a/src/tgclient.cpp b/src/tgclient.cpp index fb98b10..d0a096f 100644 --- a/src/tgclient.cpp +++ b/src/tgclient.cpp @@ -158,6 +158,14 @@ static auto createMessageInputText(const std::string& in) { return createMessageInputTextEntities(in, entities); } +void TGClient::openChat(int64_t chatid) { + send_staticquery(td::make_tl_object(chatid), HANDLER_NULL); +} + +void TGClient::closeChat(int64_t chatid) { + send_staticquery(td::make_tl_object(chatid), HANDLER_NULL); +} + void TGClient::deleteMessage(int64_t chatid, int64_t messageid, bool forall) { send_staticquery(td::make_tl_object(chatid, td_api::array(1, messageid), forall), HANDLER_NULL); } diff --git a/src/tgtui.cpp b/src/tgtui.cpp index 3eb51bb..bbadac8 100644 --- a/src/tgtui.cpp +++ b/src/tgtui.cpp @@ -6,19 +6,19 @@ #include "config.h" #include "view.h" +#include "viewchat.h" #include "viewchatlist.h" namespace pl = std::placeholders; TgTUI::TgTUI() : tgclient(std::bind(&TgTUI::initDoneCB, this)) { - views.push_back(new ViewChatList(*this)); + viewChatList = new ViewChatList(*this); + viewChat = new ViewChat(*this); } TgTUI::~TgTUI() { - for(View* v : views) { - delete v; - } - views.clear(); + delete viewChatList; + delete viewChat; } void TgTUI::run() { @@ -70,7 +70,8 @@ const std::vector& TgTUI::getChats() { void TgTUI::initDoneCB() { shouldRun = true; - currentView = views.at(0); + currentView = viewChatList; + currentViewMode = ViewMode::ChatList; tuiThread = std::thread(&TgTUI::threadLoop, this); } @@ -84,8 +85,7 @@ void TgTUI::threadLoop() { currentView->open(); - bool keep = true; - while(shouldRun && keep) { + while(shouldRun) { ::clear(); currentView->paint(); @@ -93,18 +93,56 @@ void TgTUI::threadLoop() { ::refresh(); int ch = getch(); - - keep = currentView->keyIn(ch); + int newMode = currentView->keyIn(ch); + if(newMode == -2) { + // exit + shouldRun = false; + } else if(newMode == -1) { + continue; + } else { + switchToView((ViewMode) newMode); + } } currentView->close(); + tgclient.stop(); + // deinit ncurses ::nocbreak(); ::echo(); ::endwin(); + } void TgTUI::handleNewChat(objptr chat) { chats.push_back({chat->id_, chat->title_}); } + +void TgTUI::switchToView(ViewMode to) { + + // close old mode + if(currentViewMode == ViewMode::Chat) { + tgclient.closeChat(viewChat->getChat()); + } + + // prepare new mode + if(to == ViewMode::Chat) { + int64_t chatid = viewChatList->getSelectedChatId(); + auto it = std::find_if(chats.begin(), chats.end(), [chatid](const SlimChat& sc){ + return sc.chatId == chatid; + }); + + if(it != chats.end()) { + viewChat->setChat(&*it); + tgclient.openChat(chatid); + } + } + + switch(to) { + case ViewMode::ChatList: currentView = viewChatList; break; + case ViewMode::Chat: currentView = viewChat; break; + } + + currentViewMode = to; +} diff --git a/src/view.cpp b/src/view.cpp index f211309..18293f9 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -8,6 +8,6 @@ void View::open() {} void View::close() {} -bool View::keyIn(int) { - return true; +int View::keyIn(int) { + return -1; } diff --git a/src/viewchat.cpp b/src/viewchat.cpp new file mode 100644 index 0000000..f17581c --- /dev/null +++ b/src/viewchat.cpp @@ -0,0 +1,29 @@ +#include "viewchat.h" + +#include + +ViewChat::ViewChat(TgTUI& tgtui) : View(tgtui) {} + +ViewChat::~ViewChat() {} + +void ViewChat::setChat(const SlimChat* chat) { + this->chat = chat; +} + +int64_t ViewChat::getChat() const { + return this->chat->chatId; +} + +void ViewChat::paint() { + ::printw("Chat: %s (%li)\n", chat->name.c_str(), chat->chatId); +} + +int ViewChat::keyIn(int key) { + switch (key) { + case KEY_LEFT: + case 'q': + return 0; + } + + return -1; +} diff --git a/src/viewchatlist.cpp b/src/viewchatlist.cpp index be41353..ece3d22 100644 --- a/src/viewchatlist.cpp +++ b/src/viewchatlist.cpp @@ -36,7 +36,7 @@ void ViewChatList::paint() { } } -bool ViewChatList::keyIn(int key) { +int ViewChatList::keyIn(int key) { switch (key) { case KEY_UP: if (selectedChatRow > 0) { @@ -50,10 +50,13 @@ bool ViewChatList::keyIn(int key) { break; case KEY_RIGHT: case KEY_ENTER: - return false; + return 1; + case KEY_LEFT: + case 'q': + return -2; } - return true; + return -1; } int64_t ViewChatList::getSelectedChatId() {