diff --git a/core/account.cpp b/core/account.cpp index a7f4801..b615c83 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -51,7 +51,8 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& avatarHash(), avatarType(), ownVCardRequestInProgress(false), - network(p_net) + network(p_net), + pendingStateMessages() { config.setUser(p_login); config.setDomain(p_server); @@ -594,7 +595,7 @@ QString Core::Account::getFullJid() const void Core::Account::sendMessage(const Shared::Message& data) { 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.setType(static_cast(data.getType())); //it is safe here, my type is compatible msg.setOutOfBandUrl(data.getOutOfBandUrl()); @@ -611,9 +612,8 @@ void Core::Account::sendMessage(const Shared::Message& data) } if (ri != 0) { - if (!ri->isMuc()) { - ri->appendMessageToArchive(data); - } + ri->appendMessageToArchive(data); + pendingStateMessages.insert(std::make_pair(data.getId(), data.getPenPalJid())); } client.sendPacket(msg); @@ -731,11 +731,17 @@ bool Core::Account::handleGroupMessage(const QXmppMessage& msg, bool outgoing, b } else { return false; } - cnt->appendMessageToArchive(sMsg); - QDateTime fiveMinsAgo = QDateTime::currentDateTime().addSecs(-300); - if (sMsg.getTime() > fiveMinsAgo) { //otherwise it's considered a delayed delivery, most probably MUC history receipt - emit message(sMsg); + std::map::const_iterator pItr = pendingStateMessages.find(id); + if (pItr != pendingStateMessages.end()) { + cnt->changeMessageState(id, Shared::Message::State::delivered); + 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); + } } if (!forwarded && !outgoing) { diff --git a/core/account.h b/core/account.h index 8978800..dcf32d3 100644 --- a/core/account.h +++ b/core/account.h @@ -113,6 +113,7 @@ signals: void addPresence(const QString& jid, const QString& name, const QMap& data); void removePresence(const QString& jid, const QString& name); void message(const Shared::Message& data); + void changeMessage(const QString& jid, const QString& id, const QMap& data); void responseArchive(const QString& jid, const std::list& list); void error(const QString& text); void addRoomParticipant(const QString& jid, const QString& nickName, const QMap& data); @@ -153,6 +154,7 @@ private: QString avatarType; bool ownVCardRequestInProgress; NetworkAccess* network; + std::map pendingStateMessages; private slots: void onClientConnected(); diff --git a/core/rosteritem.cpp b/core/rosteritem.cpp index b9801d9..712e4a5 100644 --- a/core/rosteritem.cpp +++ b/core/rosteritem.cpp @@ -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) { unsigned int added(0); diff --git a/core/rosteritem.h b/core/rosteritem.h index ec8a622..f18d42f 100644 --- a/core/rosteritem.h +++ b/core/rosteritem.h @@ -72,6 +72,8 @@ public: virtual Shared::VCard handleResponseVCard(const QXmppVCardIq& card, const QString& resource); virtual void handlePresence(const QXmppPresence& pres) = 0; + void changeMessageState(const QString& id, Shared::Message::State newState); + signals: void nameChanged(const QString& name); void subscriptionStateChanged(Shared::SubscriptionState state); diff --git a/core/squawk.cpp b/core/squawk.cpp index 3ccb224..75cceec 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -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::removePresence, this, &Squawk::onAccountRemovePresence); connect(acc, &Account::message, this, &Squawk::onAccountMessage); + connect(acc, &Account::changeMessage, this, &Squawk::onAccountChangeMessage); connect(acc, &Account::responseArchive, this, &Squawk::onAccountResponseArchive); 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); } + + +void Core::Squawk::onAccountChangeMessage(const QString& jid, const QString& id, const QMap& data) +{ + Account* acc = static_cast(sender()); + emit changeMessage(acc->getName(), jid, id, data); +} + void Core::Squawk::removeRoomRequest(const QString& account, const QString& jid) { 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); } + diff --git a/core/squawk.h b/core/squawk.h index e2a6b74..76f5170 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -69,6 +69,7 @@ signals: void uploadFileError(const QString& messageId, const QString& error); void uploadFileProgress(const QString& messageId, qreal value); void responseVCard(const QString& jid, const Shared::VCard& card); + void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap& data); public slots: void start(); @@ -131,6 +132,7 @@ private slots: void onAccountAddRoomPresence(const QString& jid, const QString& nick, const QMap& data); void onAccountChangeRoomPresence(const QString& jid, const QString& nick, const QMap& data); void onAccountRemoveRoomPresence(const QString& jid, const QString& nick); + void onAccountChangeMessage(const QString& jid, const QString& id, const QMap& data); }; } diff --git a/main.cpp b/main.cpp index a38852b..f3a410c 100644 --- a/main.cpp +++ b/main.cpp @@ -127,6 +127,7 @@ int main(int argc, char *argv[]) QObject::connect(squawk, &Core::Squawk::removePresence, &w, &Squawk::removePresence); QObject::connect(squawk, &Core::Squawk::stateChanged, &w, &Squawk::stateChanged); 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::addRoom, &w, &Squawk::addRoom); QObject::connect(squawk, &Core::Squawk::changeRoom, &w, &Squawk::changeRoom); diff --git a/ui/widgets/room.cpp b/ui/widgets/room.cpp index f495432..6d5340f 100644 --- a/ui/widgets/room.cpp +++ b/ui/widgets/room.cpp @@ -47,13 +47,16 @@ Room::~Room() void Room::handleSendMessage(const QString& text) { Shared::Message msg(Shared::Message::groupChat); - msg.setFrom(account->getFullJid()); + msg.setFromJid(room->getJid()); + msg.setFromResource(room->getNick()); msg.setToJid(palJid); //msg.setToResource(activePalResource); msg.setBody(text); msg.setOutgoing(true); msg.generateRandomId(); msg.setCurrentTime(); + msg.setState(Shared::Message::State::pending); + addMessage(msg); emit sendMessage(msg); }