1
0
forked from blue/squawk

delivery statuses now actually mean something for MUC messages

This commit is contained in:
Blue 2020-03-25 18:28:36 +03:00
parent 6d1b83d0f8
commit 91cc851bfc
8 changed files with 76 additions and 10 deletions

View File

@ -51,7 +51,8 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
avatarHash(), avatarHash(),
avatarType(), avatarType(),
ownVCardRequestInProgress(false), ownVCardRequestInProgress(false),
network(p_net) network(p_net),
pendingStateMessages()
{ {
config.setUser(p_login); config.setUser(p_login);
config.setDomain(p_server); config.setDomain(p_server);
@ -594,7 +595,7 @@ QString Core::Account::getFullJid() const
void Core::Account::sendMessage(const Shared::Message& data) void Core::Account::sendMessage(const Shared::Message& data)
{ {
if (state == Shared::connected) { if (state == Shared::connected) {
QXmppMessage msg(data.getFrom(), data.getTo(), data.getBody(), data.getThread()); QXmppMessage msg(getFullJid(), data.getTo(), data.getBody(), data.getThread());
msg.setId(data.getId()); msg.setId(data.getId());
msg.setType(static_cast<QXmppMessage::Type>(data.getType())); //it is safe here, my type is compatible msg.setType(static_cast<QXmppMessage::Type>(data.getType())); //it is safe here, my type is compatible
msg.setOutOfBandUrl(data.getOutOfBandUrl()); msg.setOutOfBandUrl(data.getOutOfBandUrl());
@ -611,9 +612,8 @@ void Core::Account::sendMessage(const Shared::Message& data)
} }
if (ri != 0) { if (ri != 0) {
if (!ri->isMuc()) {
ri->appendMessageToArchive(data); ri->appendMessageToArchive(data);
} pendingStateMessages.insert(std::make_pair(data.getId(), data.getPenPalJid()));
} }
client.sendPacket(msg); client.sendPacket(msg);
@ -731,12 +731,18 @@ bool Core::Account::handleGroupMessage(const QXmppMessage& msg, bool outgoing, b
} else { } else {
return false; return false;
} }
cnt->appendMessageToArchive(sMsg);
QDateTime fiveMinsAgo = QDateTime::currentDateTime().addSecs(-300); std::map<QString, QString>::const_iterator pItr = pendingStateMessages.find(id);
if (sMsg.getTime() > fiveMinsAgo) { //otherwise it's considered a delayed delivery, most probably MUC history receipt if (pItr != pendingStateMessages.end()) {
cnt->changeMessageState(id, Shared::Message::State::delivered);
emit changeMessage(jid, id, {{"state", static_cast<uint>(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); emit message(sMsg);
} }
}
if (!forwarded && !outgoing) { if (!forwarded && !outgoing) {
if (msg.isReceiptRequested() && id.size() > 0) { if (msg.isReceiptRequested() && id.size() > 0) {

View File

@ -113,6 +113,7 @@ signals:
void addPresence(const QString& jid, const QString& name, const QMap<QString, QVariant>& data); void addPresence(const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
void removePresence(const QString& jid, const QString& name); void removePresence(const QString& jid, const QString& name);
void message(const Shared::Message& data); void message(const Shared::Message& data);
void changeMessage(const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
void responseArchive(const QString& jid, const std::list<Shared::Message>& list); void responseArchive(const QString& jid, const std::list<Shared::Message>& list);
void error(const QString& text); void error(const QString& text);
void addRoomParticipant(const QString& jid, const QString& nickName, const QMap<QString, QVariant>& data); void addRoomParticipant(const QString& jid, const QString& nickName, const QMap<QString, QVariant>& data);
@ -153,6 +154,7 @@ private:
QString avatarType; QString avatarType;
bool ownVCardRequestInProgress; bool ownVCardRequestInProgress;
NetworkAccess* network; NetworkAccess* network;
std::map<QString, QString> pendingStateMessages;
private slots: private slots:
void onClientConnected(); void onClientConnected();

View File

@ -221,6 +221,46 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg)
} }
} }
void Core::RosterItem::changeMessageState(const QString& id, Shared::Message::State newState)
{
bool found = false;
for (Shared::Message& msg : appendCache) {
if (msg.getId() == id) {
msg.setState(newState);
found = true;
break;
}
}
if (!found) {
for (Shared::Message& msg : hisoryCache) {
if (msg.getId() == id) {
msg.setState(newState);
found = true;
break;
}
}
}
if (!found) {
try {
archive->setMessageState(id, newState);
found = true;
} catch (const Archive::NotFound& e) {
qDebug() << "An attempt to change state to the message" << id << "but it couldn't be found";
}
}
if (found) {
for (Shared::Message& msg : responseCache) {
if (msg.getId() == id) {
msg.setState(newState);
break;
}
}
}
}
void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firstId, const QString& lastId) void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firstId, const QString& lastId)
{ {
unsigned int added(0); unsigned int added(0);

View File

@ -72,6 +72,8 @@ public:
virtual Shared::VCard handleResponseVCard(const QXmppVCardIq& card, const QString& resource); virtual Shared::VCard handleResponseVCard(const QXmppVCardIq& card, const QString& resource);
virtual void handlePresence(const QXmppPresence& pres) = 0; virtual void handlePresence(const QXmppPresence& pres) = 0;
void changeMessageState(const QString& id, Shared::Message::State newState);
signals: signals:
void nameChanged(const QString& name); void nameChanged(const QString& name);
void subscriptionStateChanged(Shared::SubscriptionState state); void subscriptionStateChanged(Shared::SubscriptionState state);

View File

@ -125,6 +125,7 @@ void Core::Squawk::addAccount(const QString& login, const QString& server, const
connect(acc, &Account::addPresence, this, &Squawk::onAccountAddPresence); connect(acc, &Account::addPresence, this, &Squawk::onAccountAddPresence);
connect(acc, &Account::removePresence, this, &Squawk::onAccountRemovePresence); connect(acc, &Account::removePresence, this, &Squawk::onAccountRemovePresence);
connect(acc, &Account::message, this, &Squawk::onAccountMessage); connect(acc, &Account::message, this, &Squawk::onAccountMessage);
connect(acc, &Account::changeMessage, this, &Squawk::onAccountChangeMessage);
connect(acc, &Account::responseArchive, this, &Squawk::onAccountResponseArchive); connect(acc, &Account::responseArchive, this, &Squawk::onAccountResponseArchive);
connect(acc, &Account::addRoom, this, &Squawk::onAccountAddRoom); connect(acc, &Account::addRoom, this, &Squawk::onAccountAddRoom);
@ -488,6 +489,14 @@ void Core::Squawk::onAccountRemoveRoomPresence(const QString& jid, const QString
emit removeRoomParticipant(acc->getName(), jid, nick); emit removeRoomParticipant(acc->getName(), jid, nick);
} }
void Core::Squawk::onAccountChangeMessage(const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
{
Account* acc = static_cast<Account*>(sender());
emit changeMessage(acc->getName(), jid, id, data);
}
void Core::Squawk::removeRoomRequest(const QString& account, const QString& jid) void Core::Squawk::removeRoomRequest(const QString& account, const QString& jid)
{ {
AccountsMap::const_iterator itr = amap.find(account); AccountsMap::const_iterator itr = amap.find(account);
@ -567,3 +576,4 @@ void Core::Squawk::uploadVCard(const QString& account, const Shared::VCard& card
} }
itr->second->uploadVCard(card); itr->second->uploadVCard(card);
} }

View File

@ -69,6 +69,7 @@ signals:
void uploadFileError(const QString& messageId, const QString& error); void uploadFileError(const QString& messageId, const QString& error);
void uploadFileProgress(const QString& messageId, qreal value); void uploadFileProgress(const QString& messageId, qreal value);
void responseVCard(const QString& jid, const Shared::VCard& card); void responseVCard(const QString& jid, const Shared::VCard& card);
void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
public slots: public slots:
void start(); void start();
@ -131,6 +132,7 @@ private slots:
void onAccountAddRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data); void onAccountAddRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data);
void onAccountChangeRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data); void onAccountChangeRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data);
void onAccountRemoveRoomPresence(const QString& jid, const QString& nick); void onAccountRemoveRoomPresence(const QString& jid, const QString& nick);
void onAccountChangeMessage(const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
}; };
} }

View File

@ -127,6 +127,7 @@ int main(int argc, char *argv[])
QObject::connect(squawk, &Core::Squawk::removePresence, &w, &Squawk::removePresence); QObject::connect(squawk, &Core::Squawk::removePresence, &w, &Squawk::removePresence);
QObject::connect(squawk, &Core::Squawk::stateChanged, &w, &Squawk::stateChanged); QObject::connect(squawk, &Core::Squawk::stateChanged, &w, &Squawk::stateChanged);
QObject::connect(squawk, &Core::Squawk::accountMessage, &w, &Squawk::accountMessage); QObject::connect(squawk, &Core::Squawk::accountMessage, &w, &Squawk::accountMessage);
QObject::connect(squawk, &Core::Squawk::changeMessage, &w, &Squawk::changeMessage);
QObject::connect(squawk, &Core::Squawk::responseArchive, &w, &Squawk::responseArchive); QObject::connect(squawk, &Core::Squawk::responseArchive, &w, &Squawk::responseArchive);
QObject::connect(squawk, &Core::Squawk::addRoom, &w, &Squawk::addRoom); QObject::connect(squawk, &Core::Squawk::addRoom, &w, &Squawk::addRoom);
QObject::connect(squawk, &Core::Squawk::changeRoom, &w, &Squawk::changeRoom); QObject::connect(squawk, &Core::Squawk::changeRoom, &w, &Squawk::changeRoom);

View File

@ -47,13 +47,16 @@ Room::~Room()
void Room::handleSendMessage(const QString& text) void Room::handleSendMessage(const QString& text)
{ {
Shared::Message msg(Shared::Message::groupChat); Shared::Message msg(Shared::Message::groupChat);
msg.setFrom(account->getFullJid()); msg.setFromJid(room->getJid());
msg.setFromResource(room->getNick());
msg.setToJid(palJid); msg.setToJid(palJid);
//msg.setToResource(activePalResource); //msg.setToResource(activePalResource);
msg.setBody(text); msg.setBody(text);
msg.setOutgoing(true); msg.setOutgoing(true);
msg.generateRandomId(); msg.generateRandomId();
msg.setCurrentTime(); msg.setCurrentTime();
msg.setState(Shared::Message::State::pending);
addMessage(msg);
emit sendMessage(msg); emit sendMessage(msg);
} }