diff --git a/core/account.cpp b/core/account.cpp index c9e08eb..0f654fa 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -19,7 +19,6 @@ #include "account.h" #include #include -#include using namespace Core; @@ -43,8 +42,8 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& rcpm(new QXmppMessageReceiptManager()), contacts(), conferences(), - maxReconnectTimes(0), - reconnectTimes(0), + reconnectScheduled(false), + reconnectTimer(new QTimer), queuedContacts(), outOfRosterContacts(), pendingMessages(), @@ -62,8 +61,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& config.setAutoAcceptSubscriptions(true); //config.setAutoReconnectionEnabled(false); - QObject::connect(&client, &QXmppClient::connected, this, &Account::onClientConnected); - QObject::connect(&client, &QXmppClient::disconnected, this, &Account::onClientDisconnected); + QObject::connect(&client, &QXmppClient::stateChanged, this, &Account::onClientStateChange); QObject::connect(&client, &QXmppClient::presenceReceived, this, &Account::onPresenceReceived); QObject::connect(&client, &QXmppClient::messageReceived, mh, &MessageHandler::onMessageReceived); QObject::connect(&client, &QXmppClient::error, this, &Account::onClientError); @@ -152,10 +150,26 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& } else { presence.setVCardUpdateType(QXmppPresence::VCardUpdateNotReady); } + + reconnectTimer->setSingleShot(true); + QObject::connect(reconnectTimer, &QTimer::timeout, this, &Account::connect); + +// QXmppLogger* logger = new QXmppLogger(this); +// logger->setLoggingType(QXmppLogger::SignalLogging); +// client.setLogger(logger); +// +// QObject::connect(logger, &QXmppLogger::message, this, [](QXmppLogger::MessageType type, const QString& text){ +// qDebug() << text; +// }); } Account::~Account() { + if (reconnectScheduled) { + reconnectScheduled = false; + reconnectTimer->stop(); + } + QObject::disconnect(network, &NetworkAccess::uploadFileComplete, mh, &MessageHandler::onFileUploaded); QObject::disconnect(network, &NetworkAccess::uploadFileError, mh, &MessageHandler::onFileUploadError); @@ -167,6 +181,7 @@ Account::~Account() delete itr->second; } + delete reconnectTimer; delete rcpm; delete dm; delete um; @@ -184,10 +199,8 @@ Shared::ConnectionState Core::Account::getState() const void Core::Account::connect() { if (state == Shared::ConnectionState::disconnected) { - reconnectTimes = maxReconnectTimes; - state = Shared::ConnectionState::connecting; + qDebug() << presence.availableStatusType(); client.connectToServer(config, presence); - emit connectionStateChanged(state); } else { qDebug("An attempt to connect an account which is already connected, skipping"); } @@ -195,54 +208,63 @@ void Core::Account::connect() void Core::Account::disconnect() { - reconnectTimes = 0; + if (reconnectScheduled) { + reconnectScheduled = false; + reconnectTimer->stop(); + } if (state != Shared::ConnectionState::disconnected) { clearConferences(); client.disconnectFromServer(); - state = Shared::ConnectionState::disconnected; - emit connectionStateChanged(state); } } -void Core::Account::onClientConnected() +void Core::Account::onClientStateChange(QXmppClient::State st) { - if (state == Shared::ConnectionState::connecting) { - reconnectTimes = maxReconnectTimes; - state = Shared::ConnectionState::connected; - dm->requestItems(getServer()); - dm->requestInfo(getServer()); - emit connectionStateChanged(state); - } else { - qDebug() << "Something weird had happened - xmpp client reported about successful connection but account wasn't in" << state << "state"; - } -} - -void Core::Account::onClientDisconnected() -{ - cancelHistoryRequests(); - pendingVCardRequests.clear(); - clearConferences(); - if (state != Shared::ConnectionState::disconnected) { - if (reconnectTimes > 0) { - qDebug() << "Account" << name << "is reconnecting for" << reconnectTimes << "more times"; - --reconnectTimes; - state = Shared::ConnectionState::connecting; - client.connectToServer(config, presence); - emit connectionStateChanged(state); - } else { - qDebug() << "Account" << name << "has been disconnected"; - state = Shared::ConnectionState::disconnected; - emit connectionStateChanged(state); + switch (st) { + case QXmppClient::ConnectedState: { + if (state != Shared::ConnectionState::connected) { + if (client.isActive()) { + Shared::ConnectionState os = state; + state = Shared::ConnectionState::connected; + if (os == Shared::ConnectionState::connecting) { + dm->requestItems(getServer()); + dm->requestInfo(getServer()); + } + emit connectionStateChanged(state); + } + } else { + qDebug() << "Something weird happened - xmpp client of account" << name + << "reported about successful connection but account was in" << state << "state"; + } } - } else { - //qDebug("Something weird had happened - xmpp client reported about being disconnection but account was already in disconnected state"); + break; + case QXmppClient::ConnectingState: { + if (state != Shared::ConnectionState::connecting) { + state = Shared::ConnectionState::connecting; + emit connectionStateChanged(state); + } + } + break; + case QXmppClient::DisconnectedState: { + cancelHistoryRequests(); + pendingVCardRequests.clear(); + if (state != Shared::ConnectionState::disconnected) { + state = Shared::ConnectionState::disconnected; + emit connectionStateChanged(state); + } else { + qDebug() << "Something weird happened - xmpp client of account" << name + << "reported about disconnection but account was in" << state << "state"; + } + } + break; } } void Core::Account::reconnect() { - if (state == Shared::ConnectionState::connected) { - ++reconnectTimes; + if (state == Shared::ConnectionState::connected && !reconnectScheduled) { + reconnectScheduled = true; + reconnectTimer->start(500); client.disconnectFromServer(); } else { qDebug() << "An attempt to reconnect account" << getName() << "which was not connected"; @@ -286,14 +308,6 @@ void Core::Account::onRosterReceived() } } -void Core::Account::setReconnectTimes(unsigned int times) -{ - maxReconnectTimes = times; - if (state == Shared::ConnectionState::connected) { - reconnectTimes = times; - } -} - void Core::Account::onRosterItemAdded(const QString& bareJid) { addedAccount(bareJid); @@ -589,14 +603,6 @@ void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMess QString jid = itr->second; RosterItem* item = getRosterItem(jid); - qDebug() << "archive for" << jid; - qDebug() << "id:" << msg.id(); - qDebug() << "oid:" << msg.originId(); - qDebug() << "sid:" << msg.stanzaId(); - qDebug() << "rid:" << msg.replaceId(); - qDebug() << "============================"; - - Shared::Message sMsg(static_cast(msg.type())); mh->initializeMessage(sMsg, msg, false, true, true); sMsg.setState(Shared::Message::State::sent); @@ -645,49 +651,35 @@ void Core::Account::requestArchive(const QString& jid, int count, const QString& emit responseArchive(contact->jid, std::list()); } - if (contact->getArchiveState() == RosterItem::empty && before.size() == 0) { - QXmppMessage msg(getFullJid(), jid, "", ""); - QString last = Shared::generateUUID(); - msg.setId(last); - if (contact->isMuc()) { - msg.setType(QXmppMessage::GroupChat); - } else { - msg.setType(QXmppMessage::Chat); - } - msg.setState(QXmppMessage::Active); - client.sendPacket(msg); - QTimer* timer = new QTimer; - QObject::connect(timer, &QTimer::timeout, [timer, contact, count, last](){ - contact->requestFromEmpty(count, last); - timer->deleteLater(); - }); - - timer->setSingleShot(true); - timer->start(1000); - } else { - contact->requestHistory(count, before); - } + contact->requestHistory(count, before); } void Core::Account::onContactNeedHistory(const QString& before, const QString& after, const QDateTime& at) { RosterItem* contact = static_cast(sender()); - QString to = ""; + + QString to = contact->jid; QXmppResultSetQuery query; - query.setMax(100); - if (before.size() > 0) { - query.setBefore(before); - } QDateTime start; - if (after.size() > 0) { //there is some strange behavior of ejabberd server returning empty result set - if (at.isValid()) { //there can be some useful information about it here https://github.com/processone/ejabberd/issues/2924 - start = at; - } else { - query.setAfter(after); + query.setMax(100); + + if (contact->getArchiveState() == RosterItem::empty) { + query.setBefore(before); + qDebug() << "Requesting remote history from empty for" << contact->jid; + } else { + if (before.size() > 0) { + query.setBefore(before); } + if (after.size() > 0) { //there is some strange behavior of ejabberd server returning empty result set + if (at.isValid()) { //there can be some useful information about it here https://github.com/processone/ejabberd/issues/2924 + start = at; + } else { + query.setAfter(after); + } + } + qDebug() << "Remote query for" << contact->jid << "from" << after << ", to" << before; } - qDebug() << "Remote query from" << after << ", to" << before; QString q = am->retrieveArchivedMessages(to, "", contact->jid, start, QDateTime(), query); achiveQueries.insert(std::make_pair(q, contact->jid)); @@ -704,7 +696,7 @@ void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResu RosterItem* ri = getRosterItem(jid); if (ri != 0) { - qDebug() << "Flushing messages for" << jid; + qDebug() << "Flushing messages for" << jid << ", complete:" << complete; ri->flushMessagesToArchive(complete, resultSetReply.first(), resultSetReply.last()); } } diff --git a/core/account.h b/core/account.h index b0d5ee0..d31d066 100644 --- a/core/account.h +++ b/core/account.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -66,10 +67,6 @@ public: QObject* parent = 0); ~Account(); - void connect(); - void disconnect(); - void reconnect(); - Shared::ConnectionState getState() const; QString getName() const; QString getLogin() const; @@ -91,7 +88,6 @@ public: void sendMessage(const Shared::Message& data); void sendMessage(const Shared::Message& data, const QString& path); void requestArchive(const QString& jid, int count, const QString& before); - void setReconnectTimes(unsigned int times); void subscribeToContact(const QString& jid, const QString& reason); void unsubscribeFromContact(const QString& jid, const QString& reason); void removeContactRequest(const QString& jid); @@ -107,6 +103,9 @@ public: void uploadVCard(const Shared::VCard& card); public slots: + void connect(); + void disconnect(); + void reconnect(); void requestVCard(const QString& jid); signals: @@ -154,8 +153,8 @@ private: QXmppMessageReceiptManager* rcpm; std::map contacts; std::map conferences; - unsigned int maxReconnectTimes; - unsigned int reconnectTimes; + bool reconnectScheduled; + QTimer* reconnectTimer; std::map queuedContacts; std::set outOfRosterContacts; @@ -172,8 +171,7 @@ private: MessageHandler* mh; private slots: - void onClientConnected(); - void onClientDisconnected(); + void onClientStateChange(QXmppClient::State state); void onClientError(QXmppClient::Error err); void onRosterReceived(); @@ -219,8 +217,6 @@ private: void handleNewContact(Contact* contact); void handleNewRosterItem(RosterItem* contact); void handleNewConference(Conference* contact); - bool handleChatMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false); - bool handleGroupMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false); void addNewRoom(const QString& jid, const QString& nick, const QString& roomName, bool autoJoin); void addToGroup(const QString& jid, const QString& group); void removeFromGroup(const QString& jid, const QString& group); diff --git a/core/archive.cpp b/core/archive.cpp index 179f33e..628723d 100644 --- a/core/archive.cpp +++ b/core/archive.cpp @@ -67,6 +67,7 @@ void Core::Archive::open(const QString& account) mdb_dbi_open(txn, "order", MDB_CREATE | MDB_INTEGERKEY, &order); mdb_dbi_open(txn, "stats", MDB_CREATE, &stats); mdb_dbi_open(txn, "avatars", MDB_CREATE, &avatars); + mdb_dbi_open(txn, "sid", MDB_CREATE, &sid); mdb_txn_commit(txn); mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn); @@ -99,6 +100,7 @@ void Core::Archive::open(const QString& account) void Core::Archive::close() { if (opened) { + mdb_dbi_close(environment, sid); mdb_dbi_close(environment, avatars); mdb_dbi_close(environment, stats); mdb_dbi_close(environment, order); @@ -139,12 +141,36 @@ bool Core::Archive::addElement(const Shared::Message& message) mdb_txn_abort(txn); return false; } else { - rc = mdb_txn_commit(txn); - if (rc) { - qDebug() << "A transaction error: " << mdb_strerror(rc); - return false; + if (message.getStanzaId().size() > 0) { + const std::string& szid = message.getStanzaId().toStdString(); + + lmdbKey.mv_size = szid.size(); + lmdbKey.mv_data = (char*)szid.c_str(); + lmdbData.mv_size = id.size(); + lmdbData.mv_data = (uint8_t*)id.data(); + rc = mdb_put(txn, sid, &lmdbKey, &lmdbData, MDB_NOOVERWRITE); + + if (rc) { + qDebug() << "An element stanzaId to id pair couldn't be inserted into the archive" << mdb_strerror(rc); + mdb_txn_abort(txn); + return false; + } else { + rc = mdb_txn_commit(txn); + if (rc) { + qDebug() << "A transaction error: " << mdb_strerror(rc); + return false; + } + return true; + } + + } else { + rc = mdb_txn_commit(txn); + if (rc) { + qDebug() << "A transaction error: " << mdb_strerror(rc); + return false; + } + return true; } - return true; } } else { qDebug() << "An element couldn't been added to the archive, skipping" << mdb_strerror(rc); @@ -164,10 +190,12 @@ void Core::Archive::clear() mdb_drop(txn, main, 0); mdb_drop(txn, order, 0); mdb_drop(txn, stats, 0); + mdb_drop(txn, avatars, 0); + mdb_drop(txn, sid, 0); mdb_txn_commit(txn); } -Shared::Message Core::Archive::getElement(const QString& id) +Shared::Message Core::Archive::getElement(const QString& id) const { if (!opened) { throw Closed("getElement", jid.toStdString()); @@ -186,7 +214,7 @@ Shared::Message Core::Archive::getElement(const QString& id) } } -Shared::Message Core::Archive::getMessage(const std::string& id, MDB_txn* txn) +Shared::Message Core::Archive::getMessage(const std::string& id, MDB_txn* txn) const { MDB_val lmdbKey, lmdbData; lmdbKey.mv_size = id.size(); @@ -220,6 +248,7 @@ void Core::Archive::changeMessage(const QString& id, const QMap 0; QDateTime oTime = msg.getTime(); bool idChange = msg.change(data); @@ -250,6 +279,19 @@ void Core::Archive::changeMessage(const QString& id, const QMap 0 && (idChange || !hadStanzaId)) { + const std::string& szid = msg.getStanzaId().toStdString(); + + lmdbData.mv_size = szid.size(); + lmdbData.mv_data = (char*)szid.c_str(); + rc = mdb_put(txn, sid, &lmdbData, &lmdbKey, 0); + + if (rc != 0) { + throw Unknown(jid.toStdString(), mdb_strerror(rc)); + } + }; + lmdbData.mv_size = ba.size(); lmdbData.mv_data = (uint8_t*)ba.data(); rc = mdb_put(txn, main, &lmdbKey, &lmdbData, 0); @@ -395,7 +437,20 @@ unsigned int Core::Archive::addElements(const std::list& messag if (rc) { qDebug() << "An element couldn't be inserted into the index, aborting the transaction" << mdb_strerror(rc); } else { - //qDebug() << "element added with id" << message.getId() << "stamp" << message.getTime(); + if (message.getStanzaId().size() > 0) { + const std::string& szid = message.getStanzaId().toStdString(); + + lmdbKey.mv_size = szid.size(); + lmdbKey.mv_data = (char*)szid.c_str(); + lmdbData.mv_size = id.size(); + lmdbData.mv_data = (uint8_t*)id.data(); + rc = mdb_put(txn, sid, &lmdbKey, &lmdbData, MDB_NOOVERWRITE); + + if (rc) { + qDebug() << "During bulk add an element stanzaId to id pair couldn't be inserted into the archive, continuing without stanzaId" << mdb_strerror(rc); + } + + } success++; } } else { @@ -536,6 +591,46 @@ void Core::Archive::setFromTheBeginning(bool is) } } +QString Core::Archive::idByStanzaId(const QString& stanzaId) const +{ + if (!opened) { + throw Closed("idByStanzaId", jid.toStdString()); + } + QString id; + std::string ssid = stanzaId.toStdString(); + + MDB_txn *txn; + MDB_val lmdbKey, lmdbData; + lmdbKey.mv_size = ssid.size(); + lmdbKey.mv_data = (char*)ssid.c_str(); + mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn); + int rc = mdb_get(txn, sid, &lmdbKey, &lmdbData); + if (rc == 0) { + id = QString::fromStdString(std::string((char*)lmdbData.mv_data, lmdbData.mv_size)); + } + mdb_txn_abort(txn); + + return id; +} + +QString Core::Archive::stanzaIdById(const QString& id) const +{ + if (!opened) { + throw Closed("stanzaIdById", jid.toStdString()); + } + + try { + Shared::Message msg = getElement(id); + return msg.getStanzaId(); + } catch (const NotFound& e) { + return QString(); + } catch (const Empty& e) { + return QString(); + } catch (...) { + throw; + } +} + void Core::Archive::printOrder() { qDebug() << "Printing order"; diff --git a/core/archive.h b/core/archive.h index ef6ca23..b71a8be 100644 --- a/core/archive.h +++ b/core/archive.h @@ -45,7 +45,7 @@ public: bool addElement(const Shared::Message& message); unsigned int addElements(const std::list& messages); - Shared::Message getElement(const QString& id); + Shared::Message getElement(const QString& id) const; void changeMessage(const QString& id, const QMap& data); Shared::Message oldest(); QString oldestId(); @@ -60,6 +60,8 @@ public: AvatarInfo getAvatarInfo(const QString& resource = "") const; bool readAvatarInfo(AvatarInfo& target, const QString& resource = "") const; void readAllResourcesAvatars(std::map& data) const; + QString idByStanzaId(const QString& stanzaId) const; + QString stanzaIdById(const QString& id) const; public: const QString jid; @@ -169,10 +171,11 @@ private: bool opened; bool fromTheBeginning; MDB_env* environment; - MDB_dbi main; - MDB_dbi order; + MDB_dbi main; //id to message + MDB_dbi order; //time to id MDB_dbi stats; - MDB_dbi avatars; + MDB_dbi avatars; + MDB_dbi sid; //stanzaId to id bool getStatBoolValue(const std::string& id, MDB_txn* txn); std::string getStatStringValue(const std::string& id, MDB_txn* txn); @@ -183,7 +186,7 @@ private: void printOrder(); void printKeys(); bool dropAvatar(const std::string& resource); - Shared::Message getMessage(const std::string& id, MDB_txn* txn); + Shared::Message getMessage(const std::string& id, MDB_txn* txn) const; Shared::Message getStoredMessage(MDB_txn *txn, MDB_cursor* cursor, MDB_cursor_op op, MDB_val* key, MDB_val* value, int& rc); Shared::Message edge(bool end); }; diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index aa02e78..ae06694 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -162,7 +162,7 @@ bool Core::MessageHandler::handleGroupMessage(const QXmppMessage& msg, bool outg } return true; - } + } return false; } @@ -176,16 +176,13 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp if (id.size() == 0) { id = source.id(); } - if (id.size() == 0) { - id = source.stanzaId(); - } + target.setStanzaId(source.stanzaId()); #else id = source.id(); #endif - if (id.size() == 0) { - target.generateRandomId(); - } else { - target.setId(id); + target.setId(id); + if (target.getId().size() == 0) { + target.generateRandomId(); //TODO out of desperation, I need at least a random ID } target.setFrom(source.from()); target.setTo(source.to()); @@ -217,13 +214,10 @@ void Core::MessageHandler::logMessage(const QXmppMessage& msg, const QString& re qDebug() << "- state: " << msg.state(); qDebug() << "- stamp: " << msg.stamp(); qDebug() << "- id: " << msg.id(); +#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 3, 0) + qDebug() << "- stanzaId: " << msg.stanzaId(); +#endif qDebug() << "- outOfBandUrl: " << msg.outOfBandUrl(); - qDebug() << "- isAttentionRequested: " << msg.isAttentionRequested(); - qDebug() << "- isReceiptRequested: " << msg.isReceiptRequested(); - qDebug() << "- receiptId: " << msg.receiptId(); - qDebug() << "- subject: " << msg.subject(); - qDebug() << "- thread: " << msg.thread(); - qDebug() << "- isMarkable: " << msg.isMarkable(); qDebug() << "=============================="; } diff --git a/core/rosteritem.cpp b/core/rosteritem.cpp index 8260eec..9163994 100644 --- a/core/rosteritem.cpp +++ b/core/rosteritem.cpp @@ -157,7 +157,7 @@ void Core::RosterItem::performRequest(int count, const QString& before) requestedCount = -1; } Shared::Message msg = archive->newest(); - emit needHistory("", msg.getId(), msg.getTime()); + emit needHistory("", getId(msg), msg.getTime()); } break; case end: @@ -176,27 +176,37 @@ void Core::RosterItem::performRequest(int count, const QString& before) } catch (const Archive::NotFound& e) { requestCache.emplace_back(requestedCount, before); requestedCount = -1; - emit needHistory(archive->oldestId(), ""); + emit needHistory(getId(archive->oldest()), ""); } catch (const Archive::Empty& e) { requestCache.emplace_back(requestedCount, before); requestedCount = -1; - emit needHistory(archive->oldestId(), ""); + emit needHistory(getId(archive->oldest()), ""); } if (found) { int rSize = responseCache.size(); if (rSize < count) { if (rSize != 0) { - emit needHistory(responseCache.front().getId(), ""); + emit needHistory(getId(responseCache.front()), ""); } else { - emit needHistory(before, ""); + QString bf; + if (muc) { + bf = archive->stanzaIdById(before); + if (bf.size() < 0) { + qDebug() << "Didn't find stanzaId for id requesting history for" << jid << ", falling back to requesting by id"; + bf = before; + } + } else { + bf = before; + } + emit needHistory(bf, ""); } } else { nextRequest(); } } } else { - emit needHistory(archive->oldestId(), ""); + emit needHistory(getId(archive->oldest()), ""); } break; case complete: @@ -213,10 +223,20 @@ void Core::RosterItem::performRequest(int count, const QString& before) } } +QString Core::RosterItem::getId(const Shared::Message& msg) +{ + QString id; + if (muc) { + id = msg.getStanzaId(); + } else { + id = msg.getId(); + } + return id; +} + void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg) { - const QString& id = msg.getId(); - if (id.size() > 0) { + if (msg.getId().size() > 0) { if (msg.storable()) { switch (archiveState) { case empty: @@ -224,13 +244,13 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg) archiveState = end; } if (!syncronizing) { - requestHistory(-1, id); + requestHistory(-1, getId(msg)); } break; case beginning: appendCache.push_back(msg); if (!syncronizing) { - requestHistory(-1, id); + requestHistory(-1, getId(msg)); } break; case end: @@ -239,7 +259,7 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg) case chunk: appendCache.push_back(msg); if (!syncronizing) { - requestHistory(-1, id); + requestHistory(-1, getId(msg)); } break; case complete: @@ -247,7 +267,7 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg) break; } } else if (!syncronizing && archiveState == empty) { - requestHistory(-1, id); + requestHistory(-1, getId(msg)); } } } @@ -377,26 +397,6 @@ void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firs } } -void Core::RosterItem::requestFromEmpty(int count, const QString& before) -{ - if (syncronizing) { - qDebug("perform from empty didn't work, another request queued"); - } else { - if (archiveState != empty) { - qDebug("perform from empty didn't work, the state is not empty"); - requestHistory(count, before); - } else { - syncronizing = true; - requestedCount = count; - requestedBefore = ""; - hisoryCache.clear(); - responseCache.clear(); - - emit needHistory(before, ""); - } - } -} - QString Core::RosterItem::getServer() const { QStringList lst = jid.split("@"); diff --git a/core/rosteritem.h b/core/rosteritem.h index cecd2e4..f38e189 100644 --- a/core/rosteritem.h +++ b/core/rosteritem.h @@ -67,7 +67,6 @@ public: void appendMessageToArchive(const Shared::Message& msg); void flushMessagesToArchive(bool finished, const QString& firstId, const QString& lastId); void requestHistory(int count, const QString& before); - void requestFromEmpty(int count, const QString& before); QString avatarPath(const QString& resource = "") const; QString folderPath() const; bool readAvatarInfo(Archive::AvatarInfo& target, const QString& resource = "") const; @@ -112,6 +111,7 @@ protected: private: void nextRequest(); void performRequest(int count, const QString& before); + QString getId(const Shared::Message& msg); }; } diff --git a/core/squawk.cpp b/core/squawk.cpp index 8a486c0..9bb2f14 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -133,11 +133,9 @@ void Core::Squawk::addAccount( ) { QSettings settings; - unsigned int reconnects = settings.value("reconnects", 2).toUInt(); Account* acc = new Account(login, server, password, name, &network); acc->setResource(resource); - acc->setReconnectTimes(reconnects); acc->setPasswordType(passwordType); accounts.push_back(acc); amap.insert(std::make_pair(name, acc)); @@ -664,6 +662,7 @@ void Core::Squawk::responsePassword(const QString& account, const QString& passw return; } itr->second->setPassword(password); + emit changeAccount(account, {{"password", password}}); accountReady(); } @@ -750,5 +749,6 @@ void Core::Squawk::onWalletResponsePassword(const QString& login, const QString& return; } itr->second->setPassword(password); + emit changeAccount(login, {{"password", password}}); accountReady(); } diff --git a/shared/message.cpp b/shared/message.cpp index 7df0f28..fad10dc 100644 --- a/shared/message.cpp +++ b/shared/message.cpp @@ -32,7 +32,12 @@ Shared::Message::Message(Shared::Message::Type p_type): outgoing(false), forwarded(false), state(State::delivered), - edited(false) {} + edited(false), + errorText(), + originalMessage(), + lastModified(), + stanzaId() + {} Shared::Message::Message(): jFrom(), @@ -50,7 +55,9 @@ Shared::Message::Message(): edited(false), errorText(), originalMessage(), - lastModified() {} + lastModified(), + stanzaId() + {} QString Shared::Message::getBody() const { @@ -77,7 +84,11 @@ QString Shared::Message::getTo() const QString Shared::Message::getId() const { - return id; + if (id.size() > 0) { + return id; + } else { + return stanzaId; + } } QDateTime Shared::Message::getTime() const @@ -299,6 +310,7 @@ void Shared::Message::serialize(QDataStream& data) const data << originalMessage; data << lastModified; } + data << stanzaId; } void Shared::Message::deserialize(QDataStream& data) @@ -328,6 +340,7 @@ void Shared::Message::deserialize(QDataStream& data) data >> originalMessage; data >> lastModified; } + data >> stanzaId; } bool Shared::Message::change(const QMap& data) @@ -353,6 +366,18 @@ bool Shared::Message::change(const QMap& data) idChanged = true; } } + + itr = data.find("stanzaId"); + if (itr != data.end()) { + QString newId = itr.value().toString(); + if (stanzaId != newId) { + setStanzaId(newId); + if (id.size() == 0) { + idChanged = true; + } + } + } + itr = data.find("body"); if (itr != data.end()) { QMap::const_iterator dItr = data.find("stamp"); @@ -397,3 +422,13 @@ bool Shared::Message::storable() const { return id.size() > 0 && (body.size() > 0 || oob.size()) > 0; } + +void Shared::Message::setStanzaId(const QString& sid) +{ + stanzaId = sid; +} + +QString Shared::Message::getStanzaId() const +{ + return stanzaId; +} diff --git a/shared/message.h b/shared/message.h index 4a0d661..d84053f 100644 --- a/shared/message.h +++ b/shared/message.h @@ -71,6 +71,7 @@ public: void setEdited(bool p_edited); void setErrorText(const QString& err); bool change(const QMap& data); + void setStanzaId(const QString& sid); QString getFrom() const; QString getFromJid() const; @@ -98,6 +99,7 @@ public: bool serverStored() const; QDateTime getLastModified() const; QString getOriginalBody() const; + QString getStanzaId() const; void serialize(QDataStream& data) const; void deserialize(QDataStream& data); @@ -120,6 +122,7 @@ private: QString errorText; QString originalMessage; QDateTime lastModified; + QString stanzaId; }; }