diff --git a/src/historykeeper.cpp b/src/historykeeper.cpp index bb9122999..e39aed3bf 100644 --- a/src/historykeeper.cpp +++ b/src/historykeeper.cpp @@ -147,7 +147,7 @@ QList HistoryKeeper::getChatHistory(HistoryKeeper::C QSqlQuery dbAnswer; if (ct == ctSingle) { - dbAnswer = db->exec(QString("SELECT timestamp, user_id, message, sent_ok FROM history INNER JOIN aliases ON history.sender = aliases.id ") + + dbAnswer = db->exec(QString("SELECT history.id, timestamp, user_id, message, sent_ok FROM history INNER JOIN aliases ON history.sender = aliases.id ") + QString("AND timestamp BETWEEN %1 AND %2 AND chat_id = %3;") .arg(time64_from).arg(time64_to).arg(chat_id)); } else { @@ -156,13 +156,15 @@ QList HistoryKeeper::getChatHistory(HistoryKeeper::C while (dbAnswer.next()) { - QString sender = dbAnswer.value(1).toString(); - QString message = unWrapMessage(dbAnswer.value(2).toString()); - qint64 timeInt = dbAnswer.value(0).toLongLong(); - QDateTime time = QDateTime::fromMSecsSinceEpoch(timeInt); - bool isSent = dbAnswer.value(3).toBool(); + qint64 id = dbAnswer.value(0).toLongLong(); + qint64 timeInt = dbAnswer.value(1).toLongLong(); + QString sender = dbAnswer.value(2).toString(); + QString message = unWrapMessage(dbAnswer.value(3).toString()); + bool isSent = dbAnswer.value(4).toBool(); - res.push_back({sender,message,time,isSent}); + QDateTime time = QDateTime::fromMSecsSinceEpoch(timeInt); + + res.push_back({id, sender,message,time,isSent}); } return res; diff --git a/src/historykeeper.h b/src/historykeeper.h index 53e365829..55f0810e4 100644 --- a/src/historykeeper.h +++ b/src/historykeeper.h @@ -30,6 +30,7 @@ public: struct HistMessage { + qint64 id; QString sender; QString message; QDateTime timestamp; diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index d3c47a197..ab4d1860b 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -81,7 +81,7 @@ ChatForm::ChatForm(Friend* chatFriend) setAcceptDrops(true); if (Settings::getInstance().getEnableLogging()) - loadHistory(QDateTime::currentDateTime().addDays(-7)); + loadHistory(QDateTime::currentDateTime().addDays(-7), true); } ChatForm::~ChatForm() @@ -709,7 +709,7 @@ void ChatForm::onAvatarRemoved(int FriendId) avatar->setPixmap(QPixmap(":/img/contact_dark.png"), Qt::transparent); } -void ChatForm::loadHistory(QDateTime since) +void ChatForm::loadHistory(QDateTime since, bool processUndelivered) { QDateTime now = QDateTime::currentDateTime(); @@ -748,7 +748,19 @@ void ChatForm::loadHistory(QDateTime since) // Show each messages MessageActionPtr ca = genMessageActionAction(ToxID::fromString(it.sender), it.message, false, msgDateTime); if (it.isSent) + { ca->markAsSent(); + } else { + if (processUndelivered) + { + int rec; + if (ca->isAction()) + rec = Core::getInstance()->sendAction(f->getFriendID(), ca->getRawMessage()); + else + rec = Core::getInstance()->sendMessage(f->getFriendID(), ca->getRawMessage()); + registerReceipt(rec, it.id, ca); + } + } historyMessages.append(ca); } std::swap(storedPrevId, previousId); @@ -861,3 +873,20 @@ void ChatForm::clearReciepts() receipts.clear(); undeliveredMsgs.clear(); } + +void ChatForm::deliverOfflineMsgs() +{ + QMap msgs = undeliveredMsgs; + clearReciepts(); + + for (auto iter = msgs.begin(); iter != msgs.end(); iter++) + { + QString messageText = iter.value()->getRawMessage(); + int rec; + if (iter.value()->isAction()) + rec = Core::getInstance()->sendAction(f->getFriendID(), messageText); + else + rec = Core::getInstance()->sendMessage(f->getFriendID(), messageText); + registerReceipt(rec, iter.key(), iter.value()); + } +} diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index 315a922d4..b64793663 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -36,7 +36,7 @@ public: ChatForm(Friend* chatFriend); ~ChatForm(); void setStatusMessage(QString newMessage); - void registerReceipt(int receipt, int messageID, MessageActionPtr msg); + void dischargeReceipt(int receipt); void clearReciepts(); @@ -51,6 +51,7 @@ signals: void volMuteToggle(int callId); public slots: + void deliverOfflineMsgs(); void startFileSend(ToxFile file); void onFileRecvRequest(ToxFile file); void onAvInvite(int FriendId, int CallId, bool video); @@ -84,10 +85,11 @@ private slots: void updateTime(); protected: - void loadHistory(QDateTime since); + void loadHistory(QDateTime since, bool processUndelivered = false); // drag & drop void dragEnterEvent(QDragEnterEvent* ev); void dropEvent(QDropEvent* ev); + void registerReceipt(int receipt, int messageID, MessageActionPtr msg); private: Friend* f; @@ -105,7 +107,7 @@ private: void stopCounter(); QString secondsToDHMS(quint32 duration); QHash receipts; - QHash undeliveredMsgs; + QMap undeliveredMsgs; }; #endif // CHATFORM_H diff --git a/src/widget/tool/chatactions/actionaction.cpp b/src/widget/tool/chatactions/actionaction.cpp index a9f749537..1063f070b 100644 --- a/src/widget/tool/chatactions/actionaction.cpp +++ b/src/widget/tool/chatactions/actionaction.cpp @@ -20,6 +20,7 @@ ActionAction::ActionAction(const QString &author, QString message, const QString &date, const bool& me) : MessageAction(author, author+" "+message, date, me) { + rawMessage = message; } QString ActionAction::getName() @@ -31,3 +32,8 @@ QString ActionAction::getMessage() { return MessageAction::getMessage("action"); } + +QString ActionAction::getRawMessage() +{ + return rawMessage; +} diff --git a/src/widget/tool/chatactions/actionaction.h b/src/widget/tool/chatactions/actionaction.h index 6f5318aac..62b101ef0 100644 --- a/src/widget/tool/chatactions/actionaction.h +++ b/src/widget/tool/chatactions/actionaction.h @@ -24,13 +24,15 @@ class ActionAction : public MessageAction public: ActionAction(const QString &author, QString message, const QString& date, const bool&); virtual ~ActionAction(){;} + virtual QString getRawMessage(); + virtual bool isAction() {return true;} protected: virtual QString getMessage(); virtual QString getName(); private: - QString message; + QString message, rawMessage; }; #endif // MESSAGEACTION_H diff --git a/src/widget/tool/chatactions/messageaction.cpp b/src/widget/tool/chatactions/messageaction.cpp index cf1520389..42e46bc79 100644 --- a/src/widget/tool/chatactions/messageaction.cpp +++ b/src/widget/tool/chatactions/messageaction.cpp @@ -89,3 +89,8 @@ void MessageAction::markAsSent() { isProcessed = true; } + +QString MessageAction::getRawMessage() +{ + return message; +} diff --git a/src/widget/tool/chatactions/messageaction.h b/src/widget/tool/chatactions/messageaction.h index c1a3d59df..9c11bbda4 100644 --- a/src/widget/tool/chatactions/messageaction.h +++ b/src/widget/tool/chatactions/messageaction.h @@ -26,6 +26,8 @@ public: virtual ~MessageAction(){;} virtual void featureUpdate(); void markAsSent(); + virtual QString getRawMessage(); + virtual bool isAction() {return false;} protected: virtual QString getMessage(); diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index a7f4e9bdf..1b0325319 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -692,6 +692,11 @@ void Widget::onFriendStatusChanged(int friendId, Status status) f->getChatForm()->addSystemInfoMessage(tr("%1 is now %2", "e.g. \"Dubslow is now online\"").arg(f->getDisplayedName()).arg(fStatus), "white", QDateTime::currentDateTime()); } + + if (isActualChange && status != Status::Offline) + { // wait a little + QTimer::singleShot(250, f->getChatForm(), SLOT(deliverOfflineMsgs())); + } } void Widget::onFriendStatusMessageChanged(int friendId, const QString& message) @@ -1058,12 +1063,10 @@ void Widget::setStatusBusy() void Widget::onMessageSendResult(int friendId, const QString& message, int messageId) { Q_UNUSED(message) + Q_UNUSED(messageId) Friend* f = FriendList::findFriend(friendId); if (!f) return; - - if (!messageId) - f->getChatForm()->addSystemInfoMessage(tr("Message failed to send"), "red", QDateTime::currentDateTime()); } void Widget::onGroupSendResult(int groupId, const QString& message, int result)