#include "yc.h" #include "client.h" #include "direction.h" #include #include #include #include #include #include #include #include void Yc::connectAccounts(const QList &pairs) { for (const auto &p : pairs) { QXmppConfiguration cfg; cfg.setStreamSecurityMode(QXmppConfiguration::TLSRequired); cfg.setJid(p.first); cfg.setPassword(p.second); cfg.setAutoReconnectionEnabled(true); const auto client = new Client(p.first); addAccount(client); client->connectToServer(cfg); } } void Yc::startChat(const QString from, const QString to) { bool found = false; #if 0 for (int i = 0; i < ui.conversations_list->count(); i++) { const auto it = static_cast(ui.conversations_list->item(i)); if (it->from == from && it->to == to) { found = true; break; } } if (!found) new Conversation(from, to, ui.conversations_list); for (const auto c : clients) if (c->jidBare() == from) { selected = c; break; } ui.sw->setCurrentIndex(Tab::Chat); ui.jid->setText(to); ui.messages->scrollToBottom(); #endif } void Yc::addInMessage(const QXmppMessage &msg) { #if 0 new Message(msg.body(), msg.stamp().toLocalTime(), Direction::In, ui.messages); #endif } void Yc::addOutMessage(const QString &msg, const QDateTime &dt) { #if 0 new Message(msg, dt.toLocalTime(), Direction::Out, ui.messages); #endif } void Yc::addAccount(Client *const c) { c->configuration().setAutoReconnectionEnabled(true); clients.append(c); c->connect(c, &Client::messageReceived, this, [this] (QXmppMessage msg) { if (msg.body().isEmpty()) return; else if (msg.stamp().isNull()) msg.setStamp(QDateTime::currentDateTimeUtc()); storeMessage(msg, Direction::In); if (selected) addInMessage(msg); }); const auto roster = c->findExtension(); if (roster) roster->connect(roster, &QXmppRosterManager::rosterReceived, c, [this, c, roster] { c->database().addToRoster(roster->getRosterBareJids()); }); else throw std::runtime_error("Expected non-null QXmppRosterManager"); } void Yc::storeMessage(const QString &from, const QString &to, const QString &msg, const QDateTime &dt, const Direction dir) const { QString jid, contact; switch (dir) { case Direction::In: jid = QXmppUtils::jidToBareJid(to); contact = QXmppUtils::jidToBareJid(from); break; case Direction::Out: jid = from; contact = to; break; } for (const auto c : clients) { if (c->jidBare() == jid) { const auto &db = c->database(); JidDb::Message m; m.body = msg; m.dt = dt; m.direction = dir; m.contact = contact; db.store(m); } } } void Yc::storeMessage(const QXmppMessage &msg, const Direction dir) const { storeMessage(msg.from(), msg.to(), msg.body(), msg.stamp(), dir); } void Yc::retrieveConversations() { for (const auto c : clients) { const auto &db = c->database(); for (const auto &conv : db.conversations()) { #if 0 new Conversation(db.jid, conv.to, ui.conversations_list, conv.last_msg, conv.dt); #else emit newConversation(db.jid, conv.to, conv.last_msg); #endif } } } void Yc::init() { creds.load().then(this, [=] (Credentials::PairListResult &&result) { if (std::holds_alternative(result)) { const auto &pairs = std::get(result); connectAccounts(pairs); retrieveConversations(); } else if (std::holds_alternative(result)) { const auto &error = std::get(result); std::cerr << qPrintable(error.description) << std::endl; } }); } Yc::~Yc() { for (const auto c : clients) delete c; } Yc::Yc(QObject *parent) : QObject(parent) { }