summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Voicu <vladvoic@gmail.com>2011-04-29 18:13:05 (GMT)
committerKevin Smith <git@kismith.co.uk>2011-04-30 08:35:40 (GMT)
commit09f61b624e99f69a9221ba46c15efa61892f475f (patch)
tree636be7dd1399a4cf97fda4343d6f849d9eac2e34 /Swift/Controllers
parentd4781a09b22013da45adf8e9e8b6484fd672a3ec (diff)
downloadswift-09f61b624e99f69a9221ba46c15efa61892f475f.zip
swift-09f61b624e99f69a9221ba46c15efa61892f475f.tar.bz2
Correct message feature using XEP-Correct
Uses Kev's not-yet-published protocol for correcting the last sent message. Release-Notes: You can now correct your previously sent message in a chat by pressing 'up' in the input field. License: This patch is BSD-licensed, see http://www.opensource.org/licenses/bsd-license.php
Diffstat (limited to 'Swift/Controllers')
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp34
-rw-r--r--Swift/Controllers/Chat/ChatController.h1
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp16
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.h7
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h5
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h3
6 files changed, 53 insertions, 13 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index 911f3e2..9767f8d 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -102,8 +102,23 @@ void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> me
setToJID(from);
}
}
- chatStateNotifier_->receivedMessageFromContact(message->getPayload<ChatState>());
+ boost::shared_ptr<Replace> replace = message->getPayload<Replace>();
+ if (replace) {
+ // Determine the timestamp
+ boost::posix_time::ptime timeStamp = boost::posix_time::microsec_clock::universal_time();
+ boost::optional<boost::posix_time::ptime> messageTimeStamp = getMessageTimestamp(message);
+ if (messageTimeStamp) {
+ timeStamp = *messageTimeStamp;
+ }
+ std::string body = message->getBody();
+ chatWindow_->replaceMessage(body, lastMessageUIID_, timeStamp);
+ replacedMessage_ = true;
+ }
+ else {
+ replacedMessage_ = false;
+ }
chatStateTracker_->handleMessageReceived(message);
+ chatStateNotifier_->receivedMessageFromContact(message->getPayload<ChatState>());
}
void ChatController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
@@ -116,10 +131,19 @@ void ChatController::preSendMessageRequest(boost::shared_ptr<Message> message) {
}
void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<Stanza> sentStanza) {
- std::string id = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
- if (stanzaChannel_->getStreamManagementEnabled() && !id.empty()) {
- chatWindow_->setAckState(id, ChatWindow::Pending);
- unackedStanzas_[sentStanza] = id;
+ if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty()) {
+ chatWindow_->setAckState(myLastMessageUIID_, ChatWindow::Pending);
+ unackedStanzas_[sentStanza] = myLastMessageUIID_;
+ }
+ boost::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>();
+ if (replace) {
+ chatWindow_->replaceMessage(body, myLastMessageUIID_, boost::posix_time::microsec_clock::universal_time());
+ } else {
+ myLastMessageUIID_ = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
+ if (stanzaChannel_->getStreamManagementEnabled()) {
+ chatWindow_->setAckState(myLastMessageUIID_, ChatWindow::Pending);
+ unackedStanzas_[sentStanza] = myLastMessageUIID_;
+ }
}
lastWasPresence_ = false;
chatStateNotifier_->userSentMessage();
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index dd4bf90..4fafb44 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -40,6 +40,7 @@ namespace Swift {
NickResolver* nickResolver_;
ChatStateNotifier* chatStateNotifier_;
ChatStateTracker* chatStateTracker_;
+ std::string myLastMessageUIID_;
bool isInMUC_;
bool lastWasPresence_;
std::string lastStatusChangeString_;
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index 566d075..14e17cd 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -30,9 +30,10 @@ namespace Swift {
ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency), eventController_(eventController), timerFactory_(timerFactory) {
chatWindow_ = chatWindowFactory_->createChatWindow(toJID, eventStream);
chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));
- chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1));
+ chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1, _2));
setOnline(stanzaChannel->isAvailable() && iqRouter->isAvailable());
createDayChangeTimer();
+ replacedMessage_ = false;
}
ChatControllerBase::~ChatControllerBase() {
@@ -88,7 +89,7 @@ void ChatControllerBase::handleAllMessagesRead() {
chatWindow_->setUnreadMessageCount(0);
}
-void ChatControllerBase::handleSendMessageRequest(const std::string &body) {
+void ChatControllerBase::handleSendMessageRequest(const std::string &body, bool isCorrectionMessage) {
if (!stanzaChannel_->isAvailable() || body.empty()) {
return;
}
@@ -104,6 +105,10 @@ void ChatControllerBase::handleSendMessageRequest(const std::string &body) {
boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
message->addPayload(boost::shared_ptr<Delay>(new Delay(now, selfJID_)));
}
+ if (isCorrectionMessage) {
+ message->addPayload(boost::shared_ptr<Replace> (new Replace(lastSentMessageStanzaID_)));
+ }
+ message->setID(lastSentMessageStanzaID_ = idGenerator_.generateID());
stanzaChannel_->sendMessage(message);
postSendMessage(message->getBody(), boost::dynamic_pointer_cast<Stanza>(message));
onActivity(message->getBody());
@@ -164,7 +169,7 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
JID from = message->getFrom();
std::vector<boost::shared_ptr<Delay> > delayPayloads = message->getPayloads<Delay>();
for (size_t i = 0; useDelayForLatency_ && i < delayPayloads.size(); i++) {
- if (!delayPayloads[i]->getFrom()) {
+ if (!delayPayloads[i]->getFrom()) {
continue;
}
boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
@@ -180,9 +185,10 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
if (messageTimeStamp) {
timeStamp = *messageTimeStamp;
}
-
- addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), label, std::string(avatarManager_->getAvatarPath(from).string()), timeStamp);
onActivity(body);
+ if (!replacedMessage_) {
+ lastMessageUIID_ = addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), label, std::string(avatarManager_->getAvatarPath(from).string()), timeStamp);
+ }
}
chatWindow_->show();
chatWindow_->setUnreadMessageCount(unreadMessages_.size());
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h
index 4898320..e0f1b94 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.h
+++ b/Swift/Controllers/Chat/ChatControllerBase.h
@@ -26,6 +26,7 @@
#include "Swiften/Elements/ErrorPayload.h"
#include "Swiften/Presence/PresenceOracle.h"
#include "Swiften/Queries/IQRouter.h"
+#include "Swiften/Base/IDGenerator.h"
namespace Swift {
class IQRouter;
@@ -66,8 +67,10 @@ namespace Swift {
virtual void dayTicked() {};
private:
+ IDGenerator idGenerator_;
+ std::string lastSentMessageStanzaID_;
void createDayChangeTimer();
- void handleSendMessageRequest(const std::string &body);
+ void handleSendMessageRequest(const std::string &body, bool isCorrectionMessage);
void handleAllMessagesRead();
void handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog>, ErrorPayload::ref error);
std::string getErrorMessage(boost::shared_ptr<ErrorPayload>);
@@ -82,6 +85,8 @@ namespace Swift {
ChatWindow* chatWindow_;
JID toJID_;
bool labelsEnabled_;
+ bool replacedMessage_;
+ std::string lastMessageUIID_;
PresenceOracle* presenceOracle_;
AvatarManager* avatarManager_;
bool useDelayForLatency_;
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index c7bcf1e..aa4416b 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -40,6 +40,7 @@ namespace Swift {
virtual void addSystemMessage(const std::string& message) = 0;
virtual void addPresenceMessage(const std::string& message) = 0;
virtual void addErrorMessage(const std::string& message) = 0;
+ virtual void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time) = 0;
virtual void setContactChatState(ChatState::ChatStateType state) = 0;
virtual void setName(const std::string& name) = 0;
@@ -61,9 +62,11 @@ namespace Swift {
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;
- boost::signal<void (const std::string&)> onSendMessageRequest;
+ boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest;
+ boost::signal<void ()> onSendCorrectionMessageRequest;
boost::signal<void ()> onUserTyping;
boost::signal<void ()> onUserCancelsTyping;
+ boost::signal<void (bool correction)> onSendMessageCorrection;
};
}
#endif
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index 53a90a7..82c5b52 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -34,12 +34,13 @@ namespace Swift {
virtual void setRosterModel(Roster* /*roster*/) {};
virtual void setTabComplete(TabComplete*) {};
virtual void replaceLastMessage(const std::string&) {};
+ virtual void replaceMessage(const std::string&, const std::string&, const boost::posix_time::ptime&) {};
void setAckState(const std::string& /*id*/, AckState /*state*/) {};
virtual void flash() {};
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;
- boost::signal<void (const std::string&)> onSendMessageRequest;
+ boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest;
std::string name_;
std::string lastMessageBody_;