corrected messages now are supposed to display correctly

This commit is contained in:
Blue 2020-03-28 17:05:49 +03:00
parent fe1ae8567a
commit ff2c9831cf
9 changed files with 202 additions and 63 deletions

View file

@ -716,7 +716,6 @@ bool Core::Account::handleChatMessage(const QXmppMessage& msg, bool outgoing, bo
{
const QString& body(msg.body());
if (body.size() != 0) {
const QString& id(msg.id());
Shared::Message sMsg(Shared::Message::chat);
initializeMessage(sMsg, msg, outgoing, forwarded, guessing);
QString jid = sMsg.getPenPalJid();
@ -741,9 +740,18 @@ bool Core::Account::handleChatMessage(const QXmppMessage& msg, bool outgoing, bo
} else {
sMsg.setState(Shared::Message::State::delivered);
}
cnt->appendMessageToArchive(sMsg);
emit message(sMsg);
QString oId = msg.replaceId();
if (oId.size() > 0) {
QMap<QString, QVariant> cData = {
{"body", sMsg.getBody()},
{"stamp", sMsg.getTime()}
};
cnt->correctMessageInArchive(oId, sMsg);
emit changeMessage(jid, oId, cData);
} else {
cnt->appendMessageToArchive(sMsg);
emit message(sMsg);
}
return true;
}
@ -773,12 +781,22 @@ bool Core::Account::handleGroupMessage(const QXmppMessage& msg, bool outgoing, b
pendingStateMessages.erase(pItr);
emit changeMessage(jid, id, cData);
} else {
cnt->appendMessageToArchive(sMsg);
QDateTime minAgo = QDateTime::currentDateTime().addSecs(-60);
if (sMsg.getTime() > minAgo) { //otherwise it's considered a delayed delivery, most probably MUC history receipt
emit message(sMsg);
QString oId = msg.replaceId();
if (oId.size() > 0) {
QMap<QString, QVariant> cData = {
{"body", sMsg.getBody()},
{"stamp", sMsg.getTime()}
};
cnt->correctMessageInArchive(oId, sMsg);
emit changeMessage(jid, oId, cData);
} else {
//qDebug() << "Delayed delivery: ";
cnt->appendMessageToArchive(sMsg);
QDateTime minAgo = QDateTime::currentDateTime().addSecs(-60);
if (sMsg.getTime() > minAgo) { //otherwise it's considered a delayed delivery, most probably MUC history receipt
emit message(sMsg);
} else {
//qDebug() << "Delayed delivery: ";
}
}
}
@ -824,10 +842,16 @@ void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMess
QString jid = itr->second;
RosterItem* item = getRosterItem(jid);
Shared::Message sMsg(Shared::Message::chat);
Shared::Message sMsg(static_cast<Shared::Message::Type>(msg.type()));
initializeMessage(sMsg, msg, false, true, true);
sMsg.setState(Shared::Message::State::sent);
item->addMessageToArchive(sMsg);
QString oId = msg.replaceId();
if (oId.size() > 0) {
item->correctMessageInArchive(oId, sMsg);
} else {
item->addMessageToArchive(sMsg);
}
}
//handleChatMessage(msg, false, true, true);

View file

@ -267,8 +267,7 @@ void Core::Archive::changeMessage(const QString& id, const QMap<QString, QVarian
Shared::Message Core::Archive::newest()
{
QString id = newestId();
return getElement(id);
return edge(true);
}
QString Core::Archive::newestId()
@ -276,25 +275,8 @@ QString Core::Archive::newestId()
if (!opened) {
throw Closed("newestId", jid.toStdString());
}
MDB_txn *txn;
int rc;
rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
MDB_cursor* cursor;
rc = mdb_cursor_open(txn, order, &cursor);
MDB_val lmdbKey, lmdbData;
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_LAST);
if (rc) {
qDebug() << "Error geting newestId " << mdb_strerror(rc);
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
throw Empty(jid.toStdString());
} else {
std::string sId((char*)lmdbData.mv_data, lmdbData.mv_size);
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
return sId.c_str();
}
Shared::Message msg = newest();
return msg.getId();
}
QString Core::Archive::oldestId()
@ -302,30 +284,79 @@ QString Core::Archive::oldestId()
if (!opened) {
throw Closed("oldestId", jid.toStdString());
}
Shared::Message msg = oldest();
return msg.getId();
}
Shared::Message Core::Archive::oldest()
{
return edge(false);
}
Shared::Message Core::Archive::edge(bool end)
{
QString name;
MDB_cursor_op begin;
MDB_cursor_op iteration;
if (end) {
name = "newest";
begin = MDB_LAST;
iteration = MDB_PREV;
} else {
name = "oldest";
begin = MDB_FIRST;
iteration = MDB_NEXT;
}
if (!opened) {
throw Closed(name.toStdString(), jid.toStdString());
}
MDB_txn *txn;
MDB_cursor* cursor;
MDB_val lmdbKey, lmdbData;
int rc;
rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
MDB_cursor* cursor;
rc = mdb_cursor_open(txn, order, &cursor);
MDB_val lmdbKey, lmdbData;
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, begin);
Shared::Message msg = getStoredMessage(txn, cursor, iteration, &lmdbKey, &lmdbData, rc);
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_FIRST);
if (rc) {
qDebug() << "Error geting oldestId " << mdb_strerror(rc);
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
qDebug() << "Error geting" << name << "message" << mdb_strerror(rc);
throw Empty(jid.toStdString());
} else {
std::string sId((char*)lmdbData.mv_data, lmdbData.mv_size);
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
return sId.c_str();
return msg;
}
}
Shared::Message Core::Archive::oldest()
Shared::Message Core::Archive::getStoredMessage(MDB_txn *txn, MDB_cursor* cursor, MDB_cursor_op op, MDB_val* key, MDB_val* value, int& rc)
{
return getElement(oldestId());
Shared::Message msg;
std::string sId;
while (true) {
if (rc) {
break;
}
sId = std::string((char*)value->mv_data, value->mv_size);
try {
msg = getMessage(sId, txn);
if (msg.serverStored()) {
break;
} else {
rc = mdb_cursor_get(cursor, key, value, op);
}
} catch (...) {
break;
}
}
return msg;
}
unsigned int Core::Archive::addElements(const std::list<Shared::Message>& messages)

View file

@ -183,6 +183,8 @@ private:
void printKeys();
bool dropAvatar(const std::string& resource);
Shared::Message getMessage(const std::string& id, MDB_txn* txn);
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);
};
}

View file

@ -35,6 +35,7 @@ Core::RosterItem::RosterItem(const QString& pJid, const QString& pAccount, QObje
appendCache(),
responseCache(),
requestCache(),
toCorrect(),
muc(false)
{
archive->open(account);
@ -75,6 +76,36 @@ void Core::RosterItem::addMessageToArchive(const Shared::Message& msg)
{
if (msg.storable()) {
hisoryCache.push_back(msg);
std::map<QString, Shared::Message>::iterator itr = toCorrect.find(msg.getId());
if (itr != toCorrect.end()) {
hisoryCache.back().change({
{"body", itr->second.getBody()},
{"stamp", itr->second.getTime()}
});
toCorrect.erase(itr);
}
}
}
void Core::RosterItem::correctMessageInArchive(const QString& originalId, const Shared::Message& msg)
{
if (msg.storable()) {
QDateTime thisTime = msg.getTime();
std::map<QString, Shared::Message>::iterator itr = toCorrect.find(originalId);
if (itr != toCorrect.end()) {
if (itr->second.getTime() < thisTime) {
itr->second = msg;
}
return;
}
bool found = changeMessage(originalId, {
{"body", msg.getBody()},
{"stamp", thisTime}
});
if (!found) {
toCorrect.insert(std::make_pair(originalId, msg));
}
}
}
@ -221,7 +252,7 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg)
}
}
void Core::RosterItem::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
bool Core::RosterItem::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
{
bool found = false;
for (Shared::Message& msg : appendCache) {
@ -259,6 +290,8 @@ void Core::RosterItem::changeMessage(const QString& id, const QMap<QString, QVar
}
}
}
return found;
}
void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firstId, const QString& lastId)

View file

@ -61,6 +61,7 @@ public:
bool isMuc() const;
void addMessageToArchive(const Shared::Message& msg);
void correctMessageInArchive(const QString& originalId, const Shared::Message& msg);
void appendMessageToArchive(const Shared::Message& msg);
void flushMessagesToArchive(bool finished, const QString& firstId, const QString& lastId);
void requestHistory(int count, const QString& before);
@ -72,7 +73,7 @@ public:
virtual Shared::VCard handleResponseVCard(const QXmppVCardIq& card, const QString& resource);
virtual void handlePresence(const QXmppPresence& pres) = 0;
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
bool changeMessage(const QString& id, const QMap<QString, QVariant>& data);
signals:
void nameChanged(const QString& name);
@ -98,6 +99,7 @@ protected:
std::list<Shared::Message> appendCache;
std::list<Shared::Message> responseCache;
std::list<std::pair<int, QString>> requestCache;
std::map<QString, Shared::Message> toCorrect;
bool muc;
private: