TelegramTUI/src/tgtui.cpp

180 lines
4.5 KiB
C++

#include "tgtui.h"
#include <ctime>
#include <cstring>
#include <iostream>
#include <string>
#include <Log.h>
#include <curses.h>
#include <cdk/cdk.h>
#include "config.h"
namespace pl = std::placeholders;
static std::string FormatTime(time_t t) {
char timeBuf[20];
std::size_t len = std::strftime(timeBuf, 20, "%Y-%m-%d %H:%M:%S", std::localtime(&t));
return std::string(timeBuf, len);
}
TgTUI::TgTUI() : tgclient(std::bind(&TgTUI::initDoneCB, this)) {}
TgTUI::~TgTUI() {
stop();
}
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;
tuiThread = std::thread(&TgTUI::threadLoop, this);
}
void TgTUI::threadLoop() {
// init ncurses
WINDOW* cursesWin = ::initscr();
// ::start_color();
::cbreak(); // Disable line buffering
::keypad(stdscr, TRUE); // Enable special keys like arrow keys
::noecho(); // Don't print characters to the screen
CDKSCREEN* cdkScr = ::initCDKScreen(cursesWin);
// build scroll
chatsItemList.clear();
chatsItemList.reserve(chats.size());
for(const SlimChat& chat : chats) {
std::string name = chat.name;
if(name.empty()) {
name = std::to_string(chat.chatId);
}
char* item = new char[name.size() +3];
item[0] = item[1] = ' ';
std::memcpy(item+2, name.c_str(), name.size() +1);
chatsItemList.push_back(item);
}
CDKSCROLL* scroll = newCDKScroll(cdkScr, LEFT, TOP, RIGHT, 0, 40, "Chats:", chatsItemList.data(), chatsItemList.size(), FALSE, A_REVERSE, TRUE, FALSE);
while(shouldRun) {
activateCDKScroll(scroll, nullptr);
if (scroll->exitType == vESCAPE_HIT) {
shouldRun = false;
} else if (scroll->exitType == vNORMAL) {
// build / activate chat view
int itemIndex = getCDKScrollCurrentItem(scroll);
int64_t chatId = chats.at(itemIndex).chatId;
(void) chatId;
}
}
destroyCDKScroll(scroll);
chats.clear();
for(char* item : chatsItemList) {
delete[] item;
}
tgclient.stop();
// deinit ncurses
::nocbreak();
::echo();
::endwin();
}
void TgTUI::handleNewChat(objptr<td_api::chat> chat) {
chats.push_back({chat->id_, chat->title_});
}
void TgTUI::handleChatMessages(const std::vector<std::shared_ptr<Message>>& msgs) {
messages = msgs;
// TODO
}
/*
ViewMode ViewChat::paint() {
static const size_t FormatLen = 45;
getmaxyx(stdscr, maxRows, maxCols);
::printw("Chat: %s (%li)\n", chat->name.c_str(), chat->chatId);
Log::info << "messages: " << messages.size() << " maxRows: " << maxRows;
for(uint32_t row = 0; row < maxRows-1 && row < messages.size(); ++row) {
std::shared_ptr<Message> msg = messages.at(row);
const char direction = ( msg->isOutgoing ? '>' : '<' );
const std::string timeStr = FormatTime(msg->sendDate);
std::string msgText = msg->text;
// find and remove first \n
std::size_t nPos = msgText.find('\n');
if(nPos != std::string::npos) {
msgText.resize(nPos);
}
if(MessageType::TEXT != msg->type) {
msgText = '<' + convertMessageType(msg->type) + '>';
}
uint32_t colLimit = std::min<int>(msgText.size(), maxCols - (FormatLen + 3));
if(msgText.size() > colLimit) {
msgText.resize(colLimit);
msgText.append("...");
}
::mvprintw(maxRows - row -1, 0, "[%s] %c (% 17li) %s", timeStr.c_str(), direction, msg->sender, msgText.c_str());
}
return ViewMode::Same;
}
*/