summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2010-09-03 15:07:47 (GMT)
committerKevin Smith <git@kismith.co.uk>2010-09-03 19:06:29 (GMT)
commita0185934b0c929622c5526b84235b86cd44aad1d (patch)
tree2b377a5e8754c35e1a40fe7405dd75804e66fd73 /Swift/Controllers
parentfde15d66a75334b23ca8bbd56b44e33893c813c4 (diff)
downloadswift-contrib-a0185934b0c929622c5526b84235b86cd44aad1d.zip
swift-contrib-a0185934b0c929622c5526b84235b86cd44aad1d.tar.bz2
XEP-0198 Ack support in the UI
Resolves: #7
Diffstat (limited to 'Swift/Controllers')
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp30
-rw-r--r--Swift/Controllers/Chat/ChatController.h5
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp8
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.h8
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp2
-rw-r--r--Swift/Controllers/Chat/ChatsManager.h2
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h12
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h5
8 files changed, 56 insertions, 16 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index 52288c2..9154b9a 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -12,6 +12,7 @@
#include "Swiften/Chat/ChatStateNotifier.h"
#include "Swiften/Chat/ChatStateMessageSender.h"
#include "Swiften/Chat/ChatStateTracker.h"
+#include "Swiften/Client/StanzaChannel.h"
#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
#include "Swift/Controllers/NickResolver.h"
@@ -32,6 +33,7 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ
nickResolver_ = nickResolver;
presenceOracle_->onPresenceChange.connect(boost::bind(&ChatController::handlePresenceChange, this, _1, _2));
chatStateTracker_->onChatStateChange.connect(boost::bind(&ChatWindow::setContactChatState, chatWindow_, _1));
+ stanzaChannel_->onStanzaAcked.connect(boost::bind(&ChatController::handleStanzaAcked, this, _1));
String nick = nickResolver_->jidToNick(toJID_);
chatWindow_->setName(nick);
String startMessage("Starting chat with " + nick);
@@ -43,6 +45,7 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ
chatWindow_->addSystemMessage(startMessage);
chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
+
}
ChatController::~ChatController() {
@@ -80,12 +83,35 @@ void ChatController::preSendMessageRequest(boost::shared_ptr<Message> message) {
}
}
-void ChatController::postSendMessage(const String& body) {
- addMessage(body, "me", true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel() : boost::optional<SecurityLabel>(), String(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
+void ChatController::postSendMessage(const String& body, boost::shared_ptr<Stanza> sentStanza) {
+ String id = addMessage(body, "me", true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel() : boost::optional<SecurityLabel>(), String(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
+ if (stanzaChannel_->getStreamManagementEnabled()) {
+ chatWindow_->setAckState(id, ChatWindow::Pending);
+ unackedStanzas_[sentStanza] = id;
+ }
lastWasPresence_ = false;
chatStateNotifier_->userSentMessage();
}
+void ChatController::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) {
+ String id = unackedStanzas_[stanza];
+ if (id != "") {
+ chatWindow_->setAckState(id, ChatWindow::Received);
+ }
+ unackedStanzas_.erase(unackedStanzas_.find(stanza));
+}
+
+void ChatController::setEnabled(bool enabled) {
+ if (!enabled) {
+ std::map<boost::shared_ptr<Stanza>, String>::iterator it = unackedStanzas_.begin();
+ for ( ; it != unackedStanzas_.end(); it++) {
+ chatWindow_->setAckState(it->second, ChatWindow::Failed);
+ }
+ unackedStanzas_.clear();
+ }
+ ChatControllerBase::setEnabled(enabled);
+}
+
String ChatController::senderDisplayNameFromMessage(const JID& from) {
return nickResolver_->jidToNick(from);
}
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index d833094..971fca9 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -20,16 +20,18 @@ namespace Swift {
ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController);
virtual ~ChatController();
virtual void setToJID(const JID& jid);
+ virtual void setEnabled(bool enabled);
private:
void handlePresenceChange(boost::shared_ptr<Presence> newPresence, boost::shared_ptr<Presence> previousPresence);
String getStatusChangeString(boost::shared_ptr<Presence> presence);
bool isIncomingMessageFromMe(boost::shared_ptr<Message> message);
- void postSendMessage(const String &body);
+ void postSendMessage(const String &body, boost::shared_ptr<Stanza> sentStanza);
void preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent);
void preSendMessageRequest(boost::shared_ptr<Message>);
String senderDisplayNameFromMessage(const JID& from);
virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const;
+ void handleStanzaAcked(boost::shared_ptr<Stanza> stanza);
private:
NickResolver* nickResolver_;
@@ -39,6 +41,7 @@ namespace Swift {
ChatStateTracker* chatStateTracker_;
bool isInMUC_;
bool lastWasPresence_;
+ std::map<boost::shared_ptr<Stanza>, String> unackedStanzas_;
};
}
#endif
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index e38d12d..b7dd1c0 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -79,7 +79,7 @@ void ChatControllerBase::handleSendMessageRequest(const String &body) {
message->addPayload(boost::shared_ptr<Delay>(new Delay(now, selfJID_)));
}
stanzaChannel_->sendMessage(message);
- postSendMessage(message->getBody());
+ postSendMessage(message->getBody(), boost::dynamic_pointer_cast<Stanza>(message));
}
void ChatControllerBase::handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog> catalog, const boost::optional<ErrorPayload>& error) {
@@ -106,11 +106,11 @@ void ChatControllerBase::activateChatWindow() {
chatWindow_->activate();
}
-void ChatControllerBase::addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) {
+String ChatControllerBase::addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) {
if (message.beginsWith("/me ")) {
- chatWindow_->addAction(message.getSplittedAtFirst(' ').second, senderName, senderIsSelf, label, avatarPath, time);
+ return chatWindow_->addAction(message.getSplittedAtFirst(' ').second, senderName, senderIsSelf, label, avatarPath, time);
} else {
- chatWindow_->addMessage(message, senderName, senderIsSelf, label, avatarPath, time);
+ return chatWindow_->addMessage(message, senderName, senderIsSelf, label, avatarPath, time);
}
}
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h
index 61d0ab7..2466690 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.h
+++ b/Swift/Controllers/Chat/ChatControllerBase.h
@@ -15,6 +15,7 @@
#include <boost/optional.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
+#include "Swiften/Elements/Stanza.h"
#include "Swiften/Base/String.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "Swiften/Events/MessageEvent.h"
@@ -40,13 +41,16 @@ namespace Swift {
void activateChatWindow();
void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info);
void handleIncomingMessage(boost::shared_ptr<MessageEvent> message);
- void addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time);
+ String addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time);
virtual void setEnabled(bool enabled);
virtual void setToJID(const JID& jid) {toJID_ = jid;};
protected:
ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController);
- virtual void postSendMessage(const String&) {};
+ /**
+ * Pass the Message appended, and the stanza used to send it.
+ */
+ virtual void postSendMessage(const String&, boost::shared_ptr<Stanza>) {};
virtual String senderDisplayNameFromMessage(const JID& from) = 0;
virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message>) = 0;
virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {};
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index dfe75d6..acc5e1d 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -8,8 +8,6 @@
#include <boost/bind.hpp>
-#include "Swiften/Client/Client.h"
-
#include "Swift/Controllers/Chat/ChatController.h"
#include "Swift/Controllers/EventController.h"
#include "Swift/Controllers/Chat/MUCController.h"
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index d7a6275..3efd507 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -61,7 +61,7 @@ namespace Swift {
EventController* eventController_;
JID jid_;
StanzaChannel* stanzaChannel_;
- IQRouter* iqRouter_;;
+ IQRouter* iqRouter_;
ChatWindowFactory* chatWindowFactory_;
NickResolver* nickResolver_;
PresenceOracle* presenceOracle_;
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 4d00dca..1ee632c 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -25,11 +25,18 @@ namespace Swift {
class ChatWindow {
public:
+ enum AckState {Pending, Received, Failed};
ChatWindow() {}
virtual ~ChatWindow() {};
- virtual void addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) = 0;
- virtual void addAction(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) = 0;
+ /** Add message to window.
+ * @return id of added message (for acks).
+ */
+ virtual String addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) = 0;
+ /** Adds action to window.
+ * @return id of added message (for acks);
+ */
+ virtual String addAction(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time) = 0;
virtual void addSystemMessage(const String& message) = 0;
virtual void addPresenceMessage(const String& message) = 0;
virtual void addErrorMessage(const String& message) = 0;
@@ -49,6 +56,7 @@ namespace Swift {
virtual void setRosterModel(Roster* model) = 0;
virtual void setTabComplete(TabComplete* completer) = 0;
virtual void replaceLastMessage(const String& message) = 0;
+ virtual void setAckState(const String& id, AckState state) = 0;
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index 822a128..4e7a117 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -14,8 +14,8 @@ namespace Swift {
MockChatWindow() {};
virtual ~MockChatWindow();
- virtual void addMessage(const String& message, const String& /*senderName*/, bool /*senderIsSelf*/, const boost::optional<SecurityLabel>& /*label*/, const String& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message;};
- virtual void addAction(const String& message, const String& /*senderName*/, bool /*senderIsSelf*/, const boost::optional<SecurityLabel>& /*label*/, const String& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message;};
+ virtual String addMessage(const String& message, const String& /*senderName*/, bool /*senderIsSelf*/, const boost::optional<SecurityLabel>& /*label*/, const String& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message; return "";};
+ virtual String addAction(const String& message, const String& /*senderName*/, bool /*senderIsSelf*/, const boost::optional<SecurityLabel>& /*label*/, const String& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message; return "";};
virtual void addSystemMessage(const String& /*message*/) {};
virtual void addErrorMessage(const String& /*message*/) {};
virtual void addPresenceMessage(const String& /*message*/) {};
@@ -34,6 +34,7 @@ namespace Swift {
virtual void setRosterModel(Roster* /*roster*/) {};
virtual void setTabComplete(TabComplete*) {};
virtual void replaceLastMessage(const Swift::String&) {};
+ void setAckState(const String& /*id*/, AckState /*state*/) {};
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;