diff --git a/inc/tgtui.h b/inc/tgtui.h index b2839fb..f45d190 100644 --- a/inc/tgtui.h +++ b/inc/tgtui.h @@ -6,6 +6,7 @@ #include "tgclient.h" #include "message.h" +#include class TgTUI { public: @@ -32,6 +33,9 @@ private: std::vector chatsItemList; std::vector> messages; + CDKSCROLL* chatsScroll = nullptr; + CDKSCROLL* chatScroll = nullptr; + bool shouldRun = false; std::thread tuiThread; }; diff --git a/src/tgtui.cpp b/src/tgtui.cpp index 8fa2247..f3ccab6 100644 --- a/src/tgtui.cpp +++ b/src/tgtui.cpp @@ -20,6 +20,30 @@ static std::string FormatTime(time_t t) { return std::string(timeBuf, len); } +template +static std::vector convertToList(const std::vector& v, std::function f, bool reverse = false) { + std::vector out; + out.resize(v.size(), nullptr); + for(size_t i = 0; i < v.size(); ++i) { + const T& t = v.at(i); + const std::string value = f(t); + + char* item = new char[value.size()+1]; + std::memcpy(item, value.c_str(), value.size() +1); + + size_t index = (reverse ? (v.size() - i) -1 : i); + out.at(index) = item; + } + return out; +} + +static void clearVec(std::vector v) { + for(char* c : v) { + delete[] c; + } + v.clear(); +} + TgTUI::TgTUI() : tgclient(std::bind(&TgTUI::initDoneCB, this)) {} TgTUI::~TgTUI() { @@ -86,41 +110,46 @@ void TgTUI::threadLoop() { 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); - } + { + chatsItemList.reserve(chats.size()); - 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); + std::vector chatsItemList = convertToList(chats, [](const SlimChat& chat){ + std::string name = chat.name; + if(name.empty()) { + name = std::to_string(chat.chatId); + } + + name.insert(0, " "); + return name; + }); + + chatsScroll = newCDKScroll(cdkScr, LEFT, TOP, RIGHT, 0, 40, "Chats:", chatsItemList.data(), chatsItemList.size(), FALSE, A_REVERSE, TRUE, FALSE); + chatScroll = newCDKScroll(cdkScr, 41, TOP, RIGHT, 0, -41, "Chat:", nullptr, 0, FALSE, A_REVERSE, TRUE, FALSE); + clearVec(chatsItemList); } - CDKSCROLL* scroll = newCDKScroll(cdkScr, LEFT, TOP, RIGHT, 0, 40, "Chats:", chatsItemList.data(), chatsItemList.size(), FALSE, A_REVERSE, TRUE, FALSE); - while(shouldRun) { - activateCDKScroll(scroll, nullptr); + activateCDKScroll(chatsScroll, nullptr); - if (scroll->exitType == vESCAPE_HIT) { + if (chatsScroll->exitType == vESCAPE_HIT) { shouldRun = false; - } else if (scroll->exitType == vNORMAL) { + } else if (chatsScroll->exitType == vNORMAL) { // build / activate chat view - int itemIndex = getCDKScrollCurrentItem(scroll); - int64_t chatId = chats.at(itemIndex).chatId; - (void) chatId; + int itemIndex = getCDKScrollCurrentItem(chatsScroll); + const SlimChat& chat = chats.at(itemIndex); + tgclient.openChat(chat.chatId); + tgclient.getLastMessages(chat.chatId, std::bind(&TgTUI::handleChatMessages, this, pl::_1)); + + activateCDKScroll(chatScroll, nullptr); + + tgclient.closeChat(chat.chatId); } } - destroyCDKScroll(scroll); + destroyCDKScroll(chatsScroll); + destroyCDKScroll(chatScroll); chats.clear(); - for(char* item : chatsItemList) { - delete[] item; - } tgclient.stop(); @@ -136,24 +165,12 @@ void TgTUI::handleNewChat(objptr chat) { void TgTUI::handleChatMessages(const std::vector>& msgs) { messages = msgs; - // TODO -} + Log::debug << "new messages: " << msgs.size(); -/* -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 msg = messages.at(row); + std::vector listEntrys = convertToList>(msgs, [](const std::shared_ptr& msg) { const char direction = ( msg->isOutgoing ? '>' : '<' ); - const std::string timeStr = FormatTime(msg->sendDate); + const std::string timeStr = "[" + FormatTime(msg->sendDate) + "] "; std::string msgText = msg->text; // find and remove first \n @@ -163,18 +180,12 @@ ViewMode ViewChat::paint() { } if(MessageType::TEXT != msg->type) { - msgText = '<' + convertMessageType(msg->type) + '>'; + msgText = '<' + convertMessageType(msg->type) + "> " + msgText; } - uint32_t colLimit = std::min(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; + return timeStr + direction + " (" + std::to_string(msg->sender) + ") " + msgText; + }, true); + setCDKScrollItems(chatScroll, listEntrys.data(), listEntrys.size(), FALSE); + setCDKScrollPosition(chatScroll, listEntrys.size()-1); + clearVec(listEntrys); } -*/ \ No newline at end of file