From 57d6e3adab4713498da754cb0ca7e459e58b6f9b Mon Sep 17 00:00:00 2001 From: blue Date: Thu, 26 Mar 2020 18:08:44 +0300 Subject: [PATCH] Message error handling as state, errorText to store, fake ID for message without --- core/account.cpp | 109 ++++++++++++++++++++++--------------------- core/account.h | 1 + global.cpp | 29 ++++++++++++ global.h | 3 ++ ui/utils/message.cpp | 24 +++++++--- ui/utils/message.h | 1 + 6 files changed, 109 insertions(+), 58 deletions(-) diff --git a/core/account.cpp b/core/account.cpp index b615c83..1dc0d55 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -554,8 +554,26 @@ void Core::Account::onMessageReceived(const QXmppMessage& msg) case QXmppMessage::GroupChat: handled = handleGroupMessage(msg); break; - case QXmppMessage::Error: - qDebug() << "received a message with type \"Error\", not sure what to do with it now, skipping"; + case QXmppMessage::Error: { + QString id = msg.id(); + std::map::const_iterator itr = pendingStateMessages.find(id); + if (itr != pendingStateMessages.end()) { + QString jid = itr->second; + RosterItem* cnt = getRosterItem(jid); + if (cnt != 0) { + cnt->changeMessageState(id, Shared::Message::State::error); + } + ; + emit changeMessage(jid, id, { + {"state", static_cast(Shared::Message::State::error)}, + {"errorText", msg.error().text()} + }); + pendingStateMessages.erase(itr); + handled = true; + } else { + qDebug() << "received a message with type \"Error\", not sure what to do with it now, skipping"; + } + } break; case QXmppMessage::Headline: qDebug() << "received a message with type \"Headline\", not sure what to do with it now, skipping"; @@ -735,12 +753,15 @@ bool Core::Account::handleGroupMessage(const QXmppMessage& msg, bool outgoing, b std::map::const_iterator pItr = pendingStateMessages.find(id); if (pItr != pendingStateMessages.end()) { cnt->changeMessageState(id, Shared::Message::State::delivered); + pendingStateMessages.erase(pItr); emit changeMessage(jid, id, {{"state", static_cast(Shared::Message::State::delivered)}}); } 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); + } else { + //qDebug() << "Delayed delivery: "; } } @@ -761,7 +782,12 @@ bool Core::Account::handleGroupMessage(const QXmppMessage& msg, bool outgoing, b void Core::Account::initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing, bool forwarded, bool guessing) const { const QDateTime& time(source.stamp()); - target.setId(source.id()); + QString id = source.id(); + if (id.size() == 0) { + target.generateRandomId(); + } else { + target.setId(id); + } target.setFrom(source.from()); target.setTo(source.to()); target.setBody(source.body()); @@ -787,17 +813,7 @@ void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMess if (msg.id().size() > 0 && (msg.body().size() > 0 || msg.outOfBandUrl().size() > 0)) { std::map::const_iterator itr = achiveQueries.find(queryId); QString jid = itr->second; - RosterItem* item = 0; - std::map::const_iterator citr = contacts.find(jid); - - if (citr != contacts.end()) { - item = citr->second; - } else { - std::map::const_iterator coitr = conferences.find(jid); - if (coitr != conferences.end()) { - item = coitr->second; - } - } + RosterItem* item = getRosterItem(jid); Shared::Message sMsg(Shared::Message::chat); initializeMessage(sMsg, msg, false, true, true); @@ -808,21 +824,27 @@ void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMess //handleChatMessage(msg, false, true, true); } +Core::RosterItem * Core::Account::getRosterItem(const QString& jid) +{ + RosterItem* item = 0; + std::map::const_iterator citr = contacts.find(jid); + if (citr != contacts.end()) { + item = citr->second; + } else { + std::map::const_iterator coitr = conferences.find(jid); + if (coitr != conferences.end()) { + item = coitr->second; + } + } + + return item; +} + + void Core::Account::requestArchive(const QString& jid, int count, const QString& before) { qDebug() << "An archive request for " << jid << ", before " << before; - RosterItem* contact = 0; - std::map::const_iterator itr = contacts.find(jid); - bool gr = false; - if (itr != contacts.end()) { - contact = itr->second; - } else { - std::map::const_iterator citr = conferences.find(jid); - if (citr != conferences.end()) { - contact = citr->second; - gr = true; - } - } + RosterItem* contact = getRosterItem(jid); if (contact == 0) { qDebug() << "An attempt to request archive for" << jid << "in account" << name << ", but the contact with such id wasn't found, skipping"; @@ -834,7 +856,7 @@ void Core::Account::requestArchive(const QString& jid, int count, const QString& QXmppMessage msg(getFullJid(), jid, "", ""); QString last = Shared::generateUUID(); msg.setId(last); - if (gr) { + if (contact->isMuc()) { msg.setType(QXmppMessage::GroupChat); } else { msg.setType(QXmppMessage::Chat); @@ -883,18 +905,9 @@ void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResu { std::map::const_iterator itr = achiveQueries.find(queryId); QString jid = itr->second; - RosterItem* ri = 0; - achiveQueries.erase(itr); - std::map::const_iterator citr = contacts.find(jid); - if (citr != contacts.end()) { - ri = citr->second; - } else { - std::map::const_iterator coitr = conferences.find(jid); - if (coitr != conferences.end()) { - ri = coitr->second; - } - } + + RosterItem* ri = getRosterItem(jid); if (ri != 0) { qDebug() << "Flushing messages for" << jid; @@ -1392,23 +1405,15 @@ void Core::Account::onVCardReceived(const QXmppVCardIq& card) resource = comps.back(); } pendingVCardRequests.erase(id); - RosterItem* item = 0; + RosterItem* item = getRosterItem(jid); - std::map::const_iterator contItr = contacts.find(jid); - if (contItr == contacts.end()) { - std::map::const_iterator confItr = conferences.find(jid); - if (confItr == conferences.end()) { - if (jid == getLogin() + "@" + getServer()) { - onOwnVCardReceived(card); - } else { - qDebug() << "received vCard" << jid << "doesn't belong to any of known contacts or conferences, skipping"; - } - return; + if (item == 0) { + if (jid == getLogin() + "@" + getServer()) { + onOwnVCardReceived(card); } else { - item = confItr->second; + qDebug() << "received vCard" << jid << "doesn't belong to any of known contacts or conferences, skipping"; } - } else { - item = contItr->second; + return; } Shared::VCard vCard = item->handleResponseVCard(card, resource); diff --git a/core/account.h b/core/account.h index dcf32d3..69e17a7 100644 --- a/core/account.h +++ b/core/account.h @@ -223,6 +223,7 @@ private: void storeConferences(); void clearConferences(); void sendMessageWithLocalUploadedFile(Shared::Message msg, const QString& url); + RosterItem* getRosterItem(const QString& jid); }; void initializeVCard(Shared::VCard& vCard, const QXmppVCardIq& card); diff --git a/global.cpp b/global.cpp index 6ff87c5..4cdfa8d 100644 --- a/global.cpp +++ b/global.cpp @@ -147,6 +147,11 @@ QString Shared::Message::getToResource() const return rTo; } +QString Shared::Message::getErrorText() const +{ + return errorText; +} + QString Shared::Message::getPenPalJid() const { if (outgoing) { @@ -195,6 +200,13 @@ void Shared::Message::setToResource(const QString& to) rTo = to; } +void Shared::Message::setErrorText(const QString& err) +{ + if (state == State::error) { + errorText = err; + } +} + bool Shared::Message::getOutgoing() const { return outgoing; @@ -243,6 +255,10 @@ void Shared::Message::setType(Shared::Message::Type t) void Shared::Message::setState(Shared::Message::State p_state) { state = p_state; + + if (state != State::error) { + errorText = ""; + } } void Shared::Message::setEdited(bool p_edited) @@ -266,6 +282,9 @@ void Shared::Message::serialize(QDataStream& data) const data << oob; data << (quint8)state; data << edited; + if (state == State::error) { + data << errorText; + } } void Shared::Message::deserialize(QDataStream& data) @@ -288,6 +307,9 @@ void Shared::Message::deserialize(QDataStream& data) data >> s; state = static_cast(s); data >> edited; + if (state == State::error) { + data >> errorText; + } } bool Shared::Message::change(const QMap& data) @@ -297,6 +319,13 @@ bool Shared::Message::change(const QMap& data) setState(static_cast(itr.value().toUInt())); } + if (state == State::error) { + itr = data.find("errorText"); + if (itr != data.end()) { + setErrorText(itr.value().toString()); + } + } + bool idChanged = false; itr = data.find("id"); if (itr != data.end()) { diff --git a/global.h b/global.h index 29b7969..e0a0796 100644 --- a/global.h +++ b/global.h @@ -190,6 +190,7 @@ public: void setOutOfBandUrl(const QString& url); void setState(State p_state); void setEdited(bool p_edited); + void setErrorText(const QString& err); bool change(const QMap& data); QString getFrom() const; @@ -210,6 +211,7 @@ public: QString getOutOfBandUrl() const; State getState() const; bool getEdited() const; + QString getErrorText() const; QString getPenPalJid() const; QString getPenPalResource() const; @@ -233,6 +235,7 @@ private: QString oob; State state; bool edited; + QString errorText; }; class VCard { diff --git a/ui/utils/message.cpp b/ui/utils/message.cpp index f3f162b..26fbd99 100644 --- a/ui/utils/message.cpp +++ b/ui/utils/message.cpp @@ -108,9 +108,7 @@ Message::Message(const Shared::Message& source, bool p_outgoing, const QString& sender->setAlignment(Qt::AlignRight); date->setAlignment(Qt::AlignRight); statusIcon = new QLabel(); - QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast(source.getState())])); - statusIcon->setToolTip(QCoreApplication::translate("Global", Shared::messageStateNames[static_cast(source.getState())].toLatin1())); - statusIcon->setPixmap(q.pixmap(12, 12)); + setState(); statusLay->addWidget(statusIcon); statusLay->addWidget(date); layout->addStretch(); @@ -333,11 +331,25 @@ bool Message::change(const QMap& data) } } if (hasStatusIcon) { - QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast(msg.getState())])); - statusIcon->setToolTip(QCoreApplication::translate("Global", Shared::messageStateNames[static_cast(msg.getState())].toLatin1())); - statusIcon->setPixmap(q.pixmap(12, 12)); + setState(); } return idChanged; } + +void Message::setState() +{ + Shared::Message::State state = msg.getState(); + QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast(state)])); + QString tt = QCoreApplication::translate("Global", Shared::messageStateNames[static_cast(state)].toLatin1()); + if (state == Shared::Message::State::error) { + QString errText = msg.getErrorText(); + if (errText.size() > 0) { + tt += ": " + errText; + } + } + statusIcon->setToolTip(tt); + statusIcon->setPixmap(q.pixmap(12, 12)); +} + diff --git a/ui/utils/message.h b/ui/utils/message.h index b041b87..baac728 100644 --- a/ui/utils/message.h +++ b/ui/utils/message.h @@ -93,6 +93,7 @@ private: void hideButton(); void hideProgress(); void hideFile(); + void setState(); }; #endif // MESSAGE_H