TelegramTUI/src/tgtui.cpp

150 lines
3.3 KiB
C++

#include "tgtui.h"
#include <iostream>
#include <Log.h>
#include <curses.h>
#include "config.h"
#include "view.h"
#include "viewchat.h"
#include "viewchatlist.h"
namespace pl = std::placeholders;
TgTUI::TgTUI() : tgclient(std::bind(&TgTUI::initDoneCB, this)) {
viewChatList = new ViewChatList(*this);
viewChat = new ViewChat(*this);
}
TgTUI::~TgTUI() {
stop();
delete viewChatList;
delete viewChat;
}
void TgTUI::run() {
//apply config
tgclient.setAuthData( [](){
std::cout << "Auth Code: " << std::flush;
std::string code;
std::cin >> code; // TODO: take input different
return code;
});
//register callbacks
/*
tgclient.registerDraftHandler(std::bind(&UserBot::handleDraft, this, pl::_1, pl::_2));
tgclient.registerActionHandler(std::bind(&UserBot::handleAction, this, pl::_1, pl::_2, pl::_3));
tgclient.registerDeleteHandler(std::bind(&UserBot::handleDelete, this, pl::_1, pl::_2));
tgclient.registerStatusUpdateHandler(std::bind(&UserBot::handleStatus, this, pl::_1));
tgclient.registerEditMessageHandler(std::bind(&UserBot::handleEditMessage, this, pl::_1));
tgclient.registerNewMessageHandler(std::bind(&UserBot::handleMessage, this, pl::_1));
tgclient.registerUserUpdateHandler(std::bind(&Store::logUser, store, pl::_1));
tgclient.registerIndexDoneHandle(std::bind(&UserBot::handleIndexDone, this, pl::_1));
tgclient.registerFileUpdateCallback(std::bind(&UserBot::handleFileUpdate, this, pl::_1));
tgclient.registerChatFiltersCallback(std::bind(&UserBot::handleChatFilters, this, pl::_1));
*/
tgclient.registerNewChatCallback(std::bind(&TgTUI::handleNewChat, this, pl::_1));
//run client
tgclient.loop();
}
void TgTUI::stop() {
shouldRun = false;
tgclient.stop();
if(tuiThread.joinable()) {
tuiThread.join();
}
}
const std::vector<SlimChat>& TgTUI::getChats() {
return chats;
}
void TgTUI::initDoneCB() {
shouldRun = true;
currentView = viewChatList;
currentViewMode = ViewMode::ChatList;
tuiThread = std::thread(&TgTUI::threadLoop, this);
}
void TgTUI::threadLoop() {
// init ncurses
::initscr();
// ::start_color();
::cbreak(); // Disable line buffering
::keypad(stdscr, TRUE); // Enable special keys like arrow keys
::noecho(); // Don't print characters to the screen
currentView->open();
while(shouldRun) {
::clear();
currentView->paint();
::refresh();
int ch = getch();
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<td_api::chat> 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;
}