Message error handling as state, errorText to store, fake ID for message without

This commit is contained in:
Blue 2020-03-26 18:08:44 +03:00
parent 91cc851bfc
commit 57d6e3adab
6 changed files with 109 additions and 58 deletions

View File

@ -554,8 +554,26 @@ void Core::Account::onMessageReceived(const QXmppMessage& msg)
case QXmppMessage::GroupChat: case QXmppMessage::GroupChat:
handled = handleGroupMessage(msg); handled = handleGroupMessage(msg);
break; break;
case QXmppMessage::Error: case QXmppMessage::Error: {
QString id = msg.id();
std::map<QString, QString>::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<uint>(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"; qDebug() << "received a message with type \"Error\", not sure what to do with it now, skipping";
}
}
break; break;
case QXmppMessage::Headline: case QXmppMessage::Headline:
qDebug() << "received a message with type \"Headline\", not sure what to do with it now, skipping"; 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<QString, QString>::const_iterator pItr = pendingStateMessages.find(id); std::map<QString, QString>::const_iterator pItr = pendingStateMessages.find(id);
if (pItr != pendingStateMessages.end()) { if (pItr != pendingStateMessages.end()) {
cnt->changeMessageState(id, Shared::Message::State::delivered); cnt->changeMessageState(id, Shared::Message::State::delivered);
pendingStateMessages.erase(pItr);
emit changeMessage(jid, id, {{"state", static_cast<uint>(Shared::Message::State::delivered)}}); emit changeMessage(jid, id, {{"state", static_cast<uint>(Shared::Message::State::delivered)}});
} else { } else {
cnt->appendMessageToArchive(sMsg); cnt->appendMessageToArchive(sMsg);
QDateTime minAgo = QDateTime::currentDateTime().addSecs(-60); QDateTime minAgo = QDateTime::currentDateTime().addSecs(-60);
if (sMsg.getTime() > minAgo) { //otherwise it's considered a delayed delivery, most probably MUC history receipt if (sMsg.getTime() > minAgo) { //otherwise it's considered a delayed delivery, most probably MUC history receipt
emit message(sMsg); 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 void Core::Account::initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing, bool forwarded, bool guessing) const
{ {
const QDateTime& time(source.stamp()); 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.setFrom(source.from());
target.setTo(source.to()); target.setTo(source.to());
target.setBody(source.body()); 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)) { if (msg.id().size() > 0 && (msg.body().size() > 0 || msg.outOfBandUrl().size() > 0)) {
std::map<QString, QString>::const_iterator itr = achiveQueries.find(queryId); std::map<QString, QString>::const_iterator itr = achiveQueries.find(queryId);
QString jid = itr->second; QString jid = itr->second;
RosterItem* item = 0; RosterItem* item = getRosterItem(jid);
std::map<QString, Contact*>::const_iterator citr = contacts.find(jid);
if (citr != contacts.end()) {
item = citr->second;
} else {
std::map<QString, Conference*>::const_iterator coitr = conferences.find(jid);
if (coitr != conferences.end()) {
item = coitr->second;
}
}
Shared::Message sMsg(Shared::Message::chat); Shared::Message sMsg(Shared::Message::chat);
initializeMessage(sMsg, msg, false, true, true); initializeMessage(sMsg, msg, false, true, true);
@ -808,21 +824,27 @@ void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMess
//handleChatMessage(msg, false, true, true); //handleChatMessage(msg, false, true, true);
} }
Core::RosterItem * Core::Account::getRosterItem(const QString& jid)
{
RosterItem* item = 0;
std::map<QString, Contact*>::const_iterator citr = contacts.find(jid);
if (citr != contacts.end()) {
item = citr->second;
} else {
std::map<QString, Conference*>::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) void Core::Account::requestArchive(const QString& jid, int count, const QString& before)
{ {
qDebug() << "An archive request for " << jid << ", before " << before; qDebug() << "An archive request for " << jid << ", before " << before;
RosterItem* contact = 0; RosterItem* contact = getRosterItem(jid);
std::map<QString, Contact*>::const_iterator itr = contacts.find(jid);
bool gr = false;
if (itr != contacts.end()) {
contact = itr->second;
} else {
std::map<QString, Conference*>::const_iterator citr = conferences.find(jid);
if (citr != conferences.end()) {
contact = citr->second;
gr = true;
}
}
if (contact == 0) { if (contact == 0) {
qDebug() << "An attempt to request archive for" << jid << "in account" << name << ", but the contact with such id wasn't found, skipping"; 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, "", ""); QXmppMessage msg(getFullJid(), jid, "", "");
QString last = Shared::generateUUID(); QString last = Shared::generateUUID();
msg.setId(last); msg.setId(last);
if (gr) { if (contact->isMuc()) {
msg.setType(QXmppMessage::GroupChat); msg.setType(QXmppMessage::GroupChat);
} else { } else {
msg.setType(QXmppMessage::Chat); msg.setType(QXmppMessage::Chat);
@ -883,18 +905,9 @@ void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResu
{ {
std::map<QString, QString>::const_iterator itr = achiveQueries.find(queryId); std::map<QString, QString>::const_iterator itr = achiveQueries.find(queryId);
QString jid = itr->second; QString jid = itr->second;
RosterItem* ri = 0;
achiveQueries.erase(itr); achiveQueries.erase(itr);
std::map<QString, Contact*>::const_iterator citr = contacts.find(jid);
if (citr != contacts.end()) { RosterItem* ri = getRosterItem(jid);
ri = citr->second;
} else {
std::map<QString, Conference*>::const_iterator coitr = conferences.find(jid);
if (coitr != conferences.end()) {
ri = coitr->second;
}
}
if (ri != 0) { if (ri != 0) {
qDebug() << "Flushing messages for" << jid; qDebug() << "Flushing messages for" << jid;
@ -1392,23 +1405,15 @@ void Core::Account::onVCardReceived(const QXmppVCardIq& card)
resource = comps.back(); resource = comps.back();
} }
pendingVCardRequests.erase(id); pendingVCardRequests.erase(id);
RosterItem* item = 0; RosterItem* item = getRosterItem(jid);
std::map<QString, Contact*>::const_iterator contItr = contacts.find(jid); if (item == 0) {
if (contItr == contacts.end()) {
std::map<QString, Conference*>::const_iterator confItr = conferences.find(jid);
if (confItr == conferences.end()) {
if (jid == getLogin() + "@" + getServer()) { if (jid == getLogin() + "@" + getServer()) {
onOwnVCardReceived(card); onOwnVCardReceived(card);
} else { } else {
qDebug() << "received vCard" << jid << "doesn't belong to any of known contacts or conferences, skipping"; qDebug() << "received vCard" << jid << "doesn't belong to any of known contacts or conferences, skipping";
} }
return; return;
} else {
item = confItr->second;
}
} else {
item = contItr->second;
} }
Shared::VCard vCard = item->handleResponseVCard(card, resource); Shared::VCard vCard = item->handleResponseVCard(card, resource);

View File

@ -223,6 +223,7 @@ private:
void storeConferences(); void storeConferences();
void clearConferences(); void clearConferences();
void sendMessageWithLocalUploadedFile(Shared::Message msg, const QString& url); void sendMessageWithLocalUploadedFile(Shared::Message msg, const QString& url);
RosterItem* getRosterItem(const QString& jid);
}; };
void initializeVCard(Shared::VCard& vCard, const QXmppVCardIq& card); void initializeVCard(Shared::VCard& vCard, const QXmppVCardIq& card);

View File

@ -147,6 +147,11 @@ QString Shared::Message::getToResource() const
return rTo; return rTo;
} }
QString Shared::Message::getErrorText() const
{
return errorText;
}
QString Shared::Message::getPenPalJid() const QString Shared::Message::getPenPalJid() const
{ {
if (outgoing) { if (outgoing) {
@ -195,6 +200,13 @@ void Shared::Message::setToResource(const QString& to)
rTo = to; rTo = to;
} }
void Shared::Message::setErrorText(const QString& err)
{
if (state == State::error) {
errorText = err;
}
}
bool Shared::Message::getOutgoing() const bool Shared::Message::getOutgoing() const
{ {
return outgoing; return outgoing;
@ -243,6 +255,10 @@ void Shared::Message::setType(Shared::Message::Type t)
void Shared::Message::setState(Shared::Message::State p_state) void Shared::Message::setState(Shared::Message::State p_state)
{ {
state = p_state; state = p_state;
if (state != State::error) {
errorText = "";
}
} }
void Shared::Message::setEdited(bool p_edited) void Shared::Message::setEdited(bool p_edited)
@ -266,6 +282,9 @@ void Shared::Message::serialize(QDataStream& data) const
data << oob; data << oob;
data << (quint8)state; data << (quint8)state;
data << edited; data << edited;
if (state == State::error) {
data << errorText;
}
} }
void Shared::Message::deserialize(QDataStream& data) void Shared::Message::deserialize(QDataStream& data)
@ -288,6 +307,9 @@ void Shared::Message::deserialize(QDataStream& data)
data >> s; data >> s;
state = static_cast<State>(s); state = static_cast<State>(s);
data >> edited; data >> edited;
if (state == State::error) {
data >> errorText;
}
} }
bool Shared::Message::change(const QMap<QString, QVariant>& data) bool Shared::Message::change(const QMap<QString, QVariant>& data)
@ -297,6 +319,13 @@ bool Shared::Message::change(const QMap<QString, QVariant>& data)
setState(static_cast<State>(itr.value().toUInt())); setState(static_cast<State>(itr.value().toUInt()));
} }
if (state == State::error) {
itr = data.find("errorText");
if (itr != data.end()) {
setErrorText(itr.value().toString());
}
}
bool idChanged = false; bool idChanged = false;
itr = data.find("id"); itr = data.find("id");
if (itr != data.end()) { if (itr != data.end()) {

View File

@ -190,6 +190,7 @@ public:
void setOutOfBandUrl(const QString& url); void setOutOfBandUrl(const QString& url);
void setState(State p_state); void setState(State p_state);
void setEdited(bool p_edited); void setEdited(bool p_edited);
void setErrorText(const QString& err);
bool change(const QMap<QString, QVariant>& data); bool change(const QMap<QString, QVariant>& data);
QString getFrom() const; QString getFrom() const;
@ -210,6 +211,7 @@ public:
QString getOutOfBandUrl() const; QString getOutOfBandUrl() const;
State getState() const; State getState() const;
bool getEdited() const; bool getEdited() const;
QString getErrorText() const;
QString getPenPalJid() const; QString getPenPalJid() const;
QString getPenPalResource() const; QString getPenPalResource() const;
@ -233,6 +235,7 @@ private:
QString oob; QString oob;
State state; State state;
bool edited; bool edited;
QString errorText;
}; };
class VCard { class VCard {

View File

@ -108,9 +108,7 @@ Message::Message(const Shared::Message& source, bool p_outgoing, const QString&
sender->setAlignment(Qt::AlignRight); sender->setAlignment(Qt::AlignRight);
date->setAlignment(Qt::AlignRight); date->setAlignment(Qt::AlignRight);
statusIcon = new QLabel(); statusIcon = new QLabel();
QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast<uint8_t>(source.getState())])); setState();
statusIcon->setToolTip(QCoreApplication::translate("Global", Shared::messageStateNames[static_cast<uint8_t>(source.getState())].toLatin1()));
statusIcon->setPixmap(q.pixmap(12, 12));
statusLay->addWidget(statusIcon); statusLay->addWidget(statusIcon);
statusLay->addWidget(date); statusLay->addWidget(date);
layout->addStretch(); layout->addStretch();
@ -333,11 +331,25 @@ bool Message::change(const QMap<QString, QVariant>& data)
} }
} }
if (hasStatusIcon) { if (hasStatusIcon) {
QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast<uint8_t>(msg.getState())])); setState();
statusIcon->setToolTip(QCoreApplication::translate("Global", Shared::messageStateNames[static_cast<uint8_t>(msg.getState())].toLatin1()));
statusIcon->setPixmap(q.pixmap(12, 12));
} }
return idChanged; return idChanged;
} }
void Message::setState()
{
Shared::Message::State state = msg.getState();
QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast<uint8_t>(state)]));
QString tt = QCoreApplication::translate("Global", Shared::messageStateNames[static_cast<uint8_t>(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));
}

View File

@ -93,6 +93,7 @@ private:
void hideButton(); void hideButton();
void hideProgress(); void hideProgress();
void hideFile(); void hideFile();
void setState();
}; };
#endif // MESSAGE_H #endif // MESSAGE_H