diff --git a/core/account.cpp b/core/account.cpp index 5ce29ee..6784674 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -923,3 +923,6 @@ void Core::Account::onContactHistoryResponse(const std::list& l void Core::Account::requestChangeMessage(const QString& jid, const QString& messageId, const QMap& data){ mh->requestChangeMessage(jid, messageId, data);} + +void Core::Account::resendMessage(const QString& jid, const QString& id) { + mh->resendMessage(jid, id);} diff --git a/core/account.h b/core/account.h index a0db9f9..5ba834c 100644 --- a/core/account.h +++ b/core/account.h @@ -103,6 +103,7 @@ public: void removeRoomRequest(const QString& jid); void addRoomRequest(const QString& jid, const QString& nick, const QString& password, bool autoJoin); void uploadVCard(const Shared::VCard& card); + void resendMessage(const QString& jid, const QString& id); public slots: void connect(); diff --git a/core/archive.cpp b/core/archive.cpp index 96a8c0d..2582ff9 100644 --- a/core/archive.cpp +++ b/core/archive.cpp @@ -308,8 +308,9 @@ void Core::Archive::changeMessage(const QString& id, const QMap 0 && (idChange || !hadStanzaId)) { - const std::string& szid = msg.getStanzaId().toStdString(); + QString qsid = msg.getStanzaId(); + if (qsid.size() > 0 && (idChange || !hadStanzaId)) { + std::string szid = qsid.toStdString(); lmdbData.mv_size = szid.size(); lmdbData.mv_data = (char*)szid.c_str(); diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index 54aff53..33b3458 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -73,8 +73,7 @@ void Core::MessageHandler::onMessageReceived(const QXmppMessage& msg) bool Core::MessageHandler::handleChatMessage(const QXmppMessage& msg, bool outgoing, bool forwarded, bool guessing) { - const QString& body(msg.body()); - if (body.size() != 0) { + if (msg.body().size() != 0 || msg.outOfBandUrl().size() > 0) { Shared::Message sMsg(Shared::Message::chat); initializeMessage(sMsg, msg, outgoing, forwarded, guessing); QString jid = sMsg.getPenPalJid(); @@ -234,17 +233,17 @@ void Core::MessageHandler::onReceiptReceived(const QString& jid, const QString& if (ri != 0) { ri->changeMessage(id, cData); } - pendingStateMessages.erase(itr); emit acc->changeMessage(itr->second, id, cData); + pendingStateMessages.erase(itr); } } -void Core::MessageHandler::sendMessage(const Shared::Message& data) +void Core::MessageHandler::sendMessage(const Shared::Message& data, bool newMessage) { if (data.getOutOfBandUrl().size() == 0 && data.getAttachPath().size() > 0) { - prepareUpload(data); + prepareUpload(data, newMessage); } else { - performSending(data); + performSending(data, newMessage); } } @@ -256,6 +255,7 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) RosterItem* ri = acc->rh->getRosterItem(jid); bool sent = false; QMap changes; + QDateTime sendTime = QDateTime::currentDateTimeUtc(); if (acc->state == Shared::ConnectionState::connected) { QXmppMessage msg(acc->getFullJid(), data.getTo(), data.getBody(), data.getThread()); @@ -266,8 +266,10 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) msg.setType(static_cast(data.getType())); //it is safe here, my type is compatible msg.setOutOfBandUrl(oob); msg.setReceiptRequested(true); + msg.setStamp(sendTime); sent = acc->client.sendPacket(msg); + //sent = false; if (sent) { data.setState(Shared::Message::State::sent); @@ -289,9 +291,10 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) if (oob.size() > 0) { changes.insert("outOfBandUrl", oob); } - if (!newMessage) { - changes.insert("stamp", data.getTime()); + if (newMessage) { + data.setTime(sendTime); } + changes.insert("stamp", sendTime); if (ri != 0) { if (newMessage) { @@ -309,7 +312,7 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) emit acc->changeMessage(jid, id, changes); } -void Core::MessageHandler::prepareUpload(const Shared::Message& data) +void Core::MessageHandler::prepareUpload(const Shared::Message& data, bool newMessage) { if (acc->state == Shared::ConnectionState::connected) { QString jid = data.getPenPalJid(); @@ -322,16 +325,23 @@ void Core::MessageHandler::prepareUpload(const Shared::Message& data) QString path = data.getAttachPath(); QString url = acc->network->getFileRemoteUrl(path); if (url.size() != 0) { - sendMessageWithLocalUploadedFile(data, url); + sendMessageWithLocalUploadedFile(data, url, newMessage); } else { - if (acc->network->checkAndAddToUploading(acc->getName(), jid, id, path)) { + pendingStateMessages.insert(std::make_pair(id, jid)); + if (newMessage) { ri->appendMessageToArchive(data); - pendingStateMessages.insert(std::make_pair(id, jid)); } else { + QMap changes({ + {"state", (uint)Shared::Message::State::pending} + }); + ri->changeMessage(id, changes); + emit acc->changeMessage(jid, id, changes); + } + //this checks if the file is already uploading, and if so it subscribes to it's success, so, i need to do stuff only if the network knows nothing of this file + if (!acc->network->checkAndAddToUploading(acc->getName(), jid, id, path)) { if (acc->um->serviceFound()) { QFileInfo file(path); if (file.exists() && file.isReadable()) { - ri->appendMessageToArchive(data); pendingStateMessages.insert(std::make_pair(id, jid)); uploadingSlotsQueue.emplace_back(path, id); if (uploadingSlotsQueue.size() == 1) { @@ -353,7 +363,6 @@ void Core::MessageHandler::prepareUpload(const Shared::Message& data) } } - void Core::MessageHandler::onUploadSlotReceived(const QXmppHttpUploadSlotIq& slot) { if (uploadingSlotsQueue.size() == 0) { @@ -481,3 +490,22 @@ void Core::MessageHandler::requestChangeMessage(const QString& jid, const QStrin } } } + +void Core::MessageHandler::resendMessage(const QString& jid, const QString& id) +{ + RosterItem* cnt = acc->rh->getRosterItem(jid); + if (cnt != 0) { + try { + Shared::Message msg = cnt->getMessage(id); + if (msg.getState() == Shared::Message::State::error) { + sendMessage(msg, false); + } else { + qDebug() << "An attempt to resend a message to" << jid << "by account" << acc->getName() << ", but this message seems to have been normally sent, this method was made to retry sending failed to be sent messages, skipping"; + } + } catch (const Archive::NotFound& err) { + qDebug() << "An attempt to resend a message to" << jid << "by account" << acc->getName() << ", but this message wasn't found in history, skipping"; + } + } else { + qDebug() << "An attempt to resend a message to" << jid << "by account" << acc->getName() << ", but this jid isn't present in account roster, skipping"; + } +} diff --git a/core/handlers/messagehandler.h b/core/handlers/messagehandler.h index 9138245..4eb9265 100644 --- a/core/handlers/messagehandler.h +++ b/core/handlers/messagehandler.h @@ -45,8 +45,9 @@ public: MessageHandler(Account* account); public: - void sendMessage(const Shared::Message& data); + void sendMessage(const Shared::Message& data, bool newMessage = true); void initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing = false, bool forwarded = false, bool guessing = false) const; + void resendMessage(const QString& jid, const QString& id); public slots: void onMessageReceived(const QXmppMessage& message); @@ -66,7 +67,7 @@ private: void logMessage(const QXmppMessage& msg, const QString& reason = "Message wasn't handled: "); void sendMessageWithLocalUploadedFile(Shared::Message msg, const QString& url, bool newMessage = true); void performSending(Shared::Message data, bool newMessage = true); - void prepareUpload(const Shared::Message& data); + void prepareUpload(const Shared::Message& data, bool newMessage = true); void handleUploadError(const QString& jid, const QString& messageId, const QString& errorText); private: diff --git a/core/main.cpp b/core/main.cpp index 0090424..0be020e 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -100,6 +100,7 @@ int main(int argc, char *argv[]) QObject::connect(&w, &Squawk::disconnectAccount, squawk, &Core::Squawk::disconnectAccount); QObject::connect(&w, &Squawk::changeState, squawk, &Core::Squawk::changeState); QObject::connect(&w, &Squawk::sendMessage, squawk,&Core::Squawk::sendMessage); + QObject::connect(&w, &Squawk::resendMessage, squawk,&Core::Squawk::resendMessage); QObject::connect(&w, &Squawk::requestArchive, squawk, &Core::Squawk::requestArchive); QObject::connect(&w, &Squawk::subscribeContact, squawk, &Core::Squawk::subscribeContact); QObject::connect(&w, &Squawk::unsubscribeContact, squawk, &Core::Squawk::unsubscribeContact); diff --git a/core/squawk.cpp b/core/squawk.cpp index 411d4ab..6b8af49 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -328,13 +328,24 @@ void Core::Squawk::sendMessage(const QString& account, const Shared::Message& da { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { - qDebug("An attempt to send a message with non existing account, skipping"); + qDebug() << "An attempt to send a message with non existing account" << account << ", skipping"; return; } itr->second->sendMessage(data); } +void Core::Squawk::resendMessage(const QString& account, const QString& jid, const QString& id) +{ + AccountsMap::const_iterator itr = amap.find(account); + if (itr == amap.end()) { + qDebug() << "An attempt to resend a message with non existing account" << account << ", skipping"; + return; + } + + itr->second->resendMessage(jid, id); +} + void Core::Squawk::requestArchive(const QString& account, const QString& jid, int count, const QString& before) { AccountsMap::const_iterator itr = amap.find(account); diff --git a/core/squawk.h b/core/squawk.h index 25fdbda..338eb40 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -101,6 +101,7 @@ public slots: void changeState(Shared::Availability state); void sendMessage(const QString& account, const Shared::Message& data); + void resendMessage(const QString& account, const QString& jid, const QString& id); void requestArchive(const QString& account, const QString& jid, int count, const QString& before); void subscribeContact(const QString& account, const QString& jid, const QString& reason); diff --git a/ui/squawk.cpp b/ui/squawk.cpp index fb79592..6a0a676 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -466,6 +466,15 @@ void Squawk::onConversationMessage(const Shared::Message& msg) emit sendMessage(acc, msg); } +void Squawk::onConversationResend(const QString& id) +{ + Conversation* conv = static_cast(sender()); + QString acc = conv->getAccount(); + QString jid = conv->getJid(); + + emit resendMessage(acc, jid, id); +} + void Squawk::onRequestArchive(const QString& account, const QString& jid, const QString& before) { emit requestArchive(account, jid, 20, before); //TODO amount as a settings value @@ -914,6 +923,7 @@ void Squawk::subscribeConversation(Conversation* conv) { connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed); connect(conv, &Conversation::sendMessage, this, &Squawk::onConversationMessage); + connect(conv, &Conversation::resendMessage, this, &Squawk::onConversationResend); connect(conv, &Conversation::notifyableMessage, this, &Squawk::notify); } diff --git a/ui/squawk.h b/ui/squawk.h index 15d3f82..28389fa 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -63,6 +63,7 @@ signals: void disconnectAccount(const QString&); void changeState(Shared::Availability state); void sendMessage(const QString& account, const Shared::Message& data); + void resendMessage(const QString& account, const QString& jid, const QString& id); void requestArchive(const QString& account, const QString& jid, int count, const QString& before); void subscribeContact(const QString& account, const QString& jid, const QString& reason); void unsubscribeContact(const QString& account, const QString& jid, const QString& reason); @@ -148,6 +149,7 @@ private slots: void onComboboxActivated(int index); void onRosterItemDoubleClicked(const QModelIndex& item); void onConversationMessage(const Shared::Message& msg); + void onConversationResend(const QString& id); void onRequestArchive(const QString& account, const QString& jid, const QString& before); void onRosterContextMenu(const QPoint& point); void onItemCollepsed(const QModelIndex& index); diff --git a/ui/widgets/conversation.cpp b/ui/widgets/conversation.cpp index 45ce2c5..d003551 100644 --- a/ui/widgets/conversation.cpp +++ b/ui/widgets/conversation.cpp @@ -414,6 +414,16 @@ void Conversation::onFeedContext(const QPoint& pos) contextMenu->clear(); bool showMenu = false; + if (item->getState() == Shared::Message::State::error) { + showMenu = true; + QString id = item->getId(); + QAction* resend = contextMenu->addAction(Shared::icon("view-refresh"), tr("Try sending again")); + connect(resend, &QAction::triggered, [this, id]() { + element->feed->registerUpload(id); + emit resendMessage(id); + }); + } + QString path = item->getAttachPath(); if (path.size() > 0) { showMenu = true; diff --git a/ui/widgets/conversation.h b/ui/widgets/conversation.h index 3f048fb..b0eb745 100644 --- a/ui/widgets/conversation.h +++ b/ui/widgets/conversation.h @@ -80,6 +80,7 @@ public: signals: void sendMessage(const Shared::Message& message); + void resendMessage(const QString& id); void requestArchive(const QString& before); void shown(); void requestLocalFile(const QString& messageId, const QString& url);