diff options
author | Kevin Smith <git@kismith.co.uk> | 2010-02-16 09:05:37 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2010-02-17 08:05:08 (GMT) |
commit | 5a334fd9b676564a8915baad312d92bd86358eec (patch) | |
tree | aaecbbccd9cddcb843c126b8c022f1d1e667efde /Swiften | |
parent | 231c2cb6d00061e70860626467107f4c63f359a0 (diff) | |
download | swift-contrib-5a334fd9b676564a8915baad312d92bd86358eec.zip swift-contrib-5a334fd9b676564a8915baad312d92bd86358eec.tar.bz2 |
Preliminary Chat State Notifications support.
Only covers Active and Composing (Which is very possibly all we care about).
Diffstat (limited to 'Swiften')
-rw-r--r-- | Swiften/Chat/ChatStateMessageSender.cpp | 17 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateMessageSender.h | 15 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateNotifier.cpp | 4 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateNotifier.h | 5 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateTracker.cpp | 24 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateTracker.h | 16 | ||||
-rw-r--r-- | Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp | 10 | ||||
-rw-r--r-- | Swiften/Elements/ChatState.h | 20 | ||||
-rw-r--r-- | Swiften/Parser/PayloadParsers/ChatStateParser.cpp | 35 | ||||
-rw-r--r-- | Swiften/Parser/PayloadParsers/ChatStateParser.h | 18 | ||||
-rw-r--r-- | Swiften/Parser/PayloadParsers/ChatStateParserFactory.h | 25 | ||||
-rw-r--r-- | Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp | 2 | ||||
-rw-r--r-- | Swiften/Parser/SConscript | 1 | ||||
-rw-r--r-- | Swiften/SConscript | 1 | ||||
-rw-r--r-- | Swiften/Serializer/PayloadSerializers/ChatStateSerializer.cpp | 22 | ||||
-rw-r--r-- | Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h | 13 | ||||
-rw-r--r-- | Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp | 2 |
17 files changed, 219 insertions, 11 deletions
diff --git a/Swiften/Chat/ChatStateMessageSender.cpp b/Swiften/Chat/ChatStateMessageSender.cpp index d053cb5..ad1495f 100644 --- a/Swiften/Chat/ChatStateMessageSender.cpp +++ b/Swiften/Chat/ChatStateMessageSender.cpp @@ -1,5 +1,22 @@ #include "Swiften/Chat/ChatStateMessageSender.h" +#include <boost/bind.hpp> + +#include "Swiften/Client/StanzaChannel.h" + namespace Swift { +ChatStateMessageSender::ChatStateMessageSender(ChatStateNotifier* notifier, StanzaChannel* stanzaChannel, const JID& contact) : contact_(contact) { + notifier_ = notifier; + stanzaChannel_ = stanzaChannel; + notifier_->onChatStateChanged.connect(boost::bind(&ChatStateMessageSender::handleChatStateChanged, this, _1)); +} + +void ChatStateMessageSender::handleChatStateChanged(ChatState::ChatStateType state) { + boost::shared_ptr<Message> message(new Message()); + message->setTo(contact_); + message->addPayload(boost::shared_ptr<Payload>(new ChatState(state))); + stanzaChannel_->sendMessage(message); +} + } diff --git a/Swiften/Chat/ChatStateMessageSender.h b/Swiften/Chat/ChatStateMessageSender.h index d27973d..aff0791 100644 --- a/Swiften/Chat/ChatStateMessageSender.h +++ b/Swiften/Chat/ChatStateMessageSender.h @@ -1,7 +1,20 @@ #pragma once +#include "Swiften/Chat/ChatStateNotifier.h" +#include "Swiften/Elements/ChatState.h" +#include "Swiften/JID/JID.h" + namespace Swift { + class StanzaChannel; class ChatStateMessageSender { - + public: + ChatStateMessageSender(ChatStateNotifier* notifier, StanzaChannel* stanzaChannel, const JID& contact); + void setContact(const JID& contact) {contact_ = contact;}; + + private: + void handleChatStateChanged(ChatState::ChatStateType state); + ChatStateNotifier* notifier_; + StanzaChannel* stanzaChannel_; + JID contact_; }; } diff --git a/Swiften/Chat/ChatStateNotifier.cpp b/Swiften/Chat/ChatStateNotifier.cpp index 432f708..7c6560f 100644 --- a/Swiften/Chat/ChatStateNotifier.cpp +++ b/Swiften/Chat/ChatStateNotifier.cpp @@ -16,7 +16,7 @@ void ChatStateNotifier::setContactHas85Caps(bool hasCaps) { void ChatStateNotifier::setUserIsTyping() { if (contactShouldReceiveStates() && !userIsTyping_) { userIsTyping_ = true; - onChatStateChanged(Composing); + onChatStateChanged(ChatState::Composing); } } @@ -27,7 +27,7 @@ void ChatStateNotifier::userSentMessage() { void ChatStateNotifier::userCancelledNewMessage() { if (userIsTyping_) { userIsTyping_ = false; - onChatStateChanged(Active); + onChatStateChanged(ChatState::Active); } } diff --git a/Swiften/Chat/ChatStateNotifier.h b/Swiften/Chat/ChatStateNotifier.h index 90228b7..0ef4255 100644 --- a/Swiften/Chat/ChatStateNotifier.h +++ b/Swiften/Chat/ChatStateNotifier.h @@ -3,10 +3,11 @@ #include <boost/signals.hpp> #include <boost/shared_ptr.hpp> +#include "Swiften/Elements/ChatState.h" + namespace Swift { class ChatStateNotifier { public: - enum ChatState {Active, Composing, Paused, Inactive, Gone}; ChatStateNotifier(); void setContactHas85Caps(bool hasCaps); void setUserIsTyping(); @@ -15,7 +16,7 @@ namespace Swift { void receivedMessageFromContact(bool hasActiveElement); bool contactShouldReceiveStates(); - boost::signal<void (ChatState)> onChatStateChanged; + boost::signal<void (ChatState::ChatStateType)> onChatStateChanged; private: bool contactHas85Caps_; bool isInConversation_; diff --git a/Swiften/Chat/ChatStateTracker.cpp b/Swiften/Chat/ChatStateTracker.cpp index 553d2f4..94e01eb 100644 --- a/Swiften/Chat/ChatStateTracker.cpp +++ b/Swiften/Chat/ChatStateTracker.cpp @@ -1,5 +1,29 @@ #include "Swiften/Chat/ChatStateTracker.h" namespace Swift { +ChatStateTracker::ChatStateTracker() { + currentState_ = ChatState::Gone; +} + +void ChatStateTracker::handleMessageReceived(boost::shared_ptr<Message> message) { + boost::shared_ptr<ChatState> statePayload = message->getPayload<ChatState>(); + if (statePayload) { + changeState(statePayload->getChatState());; + } +} + +void ChatStateTracker::handlePresenceChange(boost::shared_ptr<Presence> newPresence, boost::shared_ptr<Presence>) { + if (newPresence->getType() == Presence::Unavailable) { + onChatStateChange(ChatState::Gone); + } +} + +void ChatStateTracker::changeState(ChatState::ChatStateType state) { + printf("Comparing state %d to old state %d\n", state, currentState_); + if (state != currentState_) { + currentState_ = state; + onChatStateChange(state); + } +} } diff --git a/Swiften/Chat/ChatStateTracker.h b/Swiften/Chat/ChatStateTracker.h index 005c479..e612852 100644 --- a/Swiften/Chat/ChatStateTracker.h +++ b/Swiften/Chat/ChatStateTracker.h @@ -1,7 +1,21 @@ #pragma once +#include <boost/signal.hpp> +#include <boost/shared_ptr.hpp> + +#include "Swiften/Elements/Message.h" +#include "Swiften/Elements/Presence.h" +#include "Swiften/ELements/ChatState.h" + namespace Swift { class ChatStateTracker { - + public: + ChatStateTracker(); + void handleMessageReceived(boost::shared_ptr<Message> message); + void handlePresenceChange(boost::shared_ptr<Presence> newPresence, boost::shared_ptr<Presence> oldPresence); + boost::signal<void (ChatState::ChatStateType)> onChatStateChange; + private: + void changeState(ChatState::ChatStateType state); + ChatState::ChatStateType currentState_; }; } diff --git a/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp index bacfc3a..44ec9d8 100644 --- a/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp +++ b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp @@ -18,15 +18,15 @@ public: int composingCallCount; int activeCallCount; - ChatStateNotifier::ChatState currentState; + ChatState::ChatStateType currentState; private: - void handleChatStateChanged(ChatStateNotifier::ChatState newState) { + void handleChatStateChanged(ChatState::ChatStateType newState) { switch (newState) { - case ChatStateNotifier::Composing: + case ChatState::Composing: composingCallCount++; break; - case ChatStateNotifier::Active: + case ChatState::Active: activeCallCount++; break; default: @@ -86,7 +86,7 @@ public: notifier_->userCancelledNewMessage(); CPPUNIT_ASSERT_EQUAL(1, monitor_->composingCallCount); CPPUNIT_ASSERT_EQUAL(1, monitor_->activeCallCount); - CPPUNIT_ASSERT_EQUAL(ChatStateNotifier::Active, monitor_->currentState); + CPPUNIT_ASSERT_EQUAL(ChatState::Active, monitor_->currentState); } diff --git a/Swiften/Elements/ChatState.h b/Swiften/Elements/ChatState.h new file mode 100644 index 0000000..3378cc3 --- /dev/null +++ b/Swiften/Elements/ChatState.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Swiften/Base/String.h" +#include "Swiften/Elements/Payload.h" + +namespace Swift { + class ChatState : public Payload { + public: + enum ChatStateType {Active, Composing, Paused, Inactive, Gone}; + ChatState(ChatStateType state = Active) { + state_ = state; + } + + ChatStateType getChatState() { return state_; } + void setChatState(ChatStateType state) {state_ = state;} + + private: + ChatStateType state_; + }; +} diff --git a/Swiften/Parser/PayloadParsers/ChatStateParser.cpp b/Swiften/Parser/PayloadParsers/ChatStateParser.cpp new file mode 100644 index 0000000..52d860a --- /dev/null +++ b/Swiften/Parser/PayloadParsers/ChatStateParser.cpp @@ -0,0 +1,35 @@ +#include "Swiften/Parser/PayloadParsers/ChatStateParser.h" + +namespace Swift { + +ChatStateParser::ChatStateParser() : level_(0) { +} + +void ChatStateParser::handleStartElement(const String& element, const String&, const AttributeMap&) { + if (level_ == 0) { + ChatState::ChatStateType state = ChatState::Active; + if (element == "active") { + state = ChatState::Active; + } else if (element == "composing") { + state = ChatState::Composing; + } else if (element == "inactive") { + state = ChatState::Inactive; + } else if (element == "paused") { + state = ChatState::Paused; + } else if (element == "gone") { + state = ChatState::Gone; + } + getPayloadInternal()->setChatState(state); + } + ++level_; +} + +void ChatStateParser::handleEndElement(const String&, const String&) { + --level_; +} + +void ChatStateParser::handleCharacterData(const String&) { + +} + +} diff --git a/Swiften/Parser/PayloadParsers/ChatStateParser.h b/Swiften/Parser/PayloadParsers/ChatStateParser.h new file mode 100644 index 0000000..cd212c0 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/ChatStateParser.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Swiften/Elements/ChatState.h" +#include "Swiften/Parser/GenericPayloadParser.h" + +namespace Swift { + class ChatStateParser : public GenericPayloadParser<ChatState> { + public: + ChatStateParser(); + + virtual void handleStartElement(const String& element, const String&, const AttributeMap& attributes); + virtual void handleEndElement(const String& element, const String&); + virtual void handleCharacterData(const String& data); + + private: + int level_; + }; +} diff --git a/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h b/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h new file mode 100644 index 0000000..1582d09 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Swiften/Parser/PayloadParserFactory.h" +#include "Swiften/Parser/PayloadParsers/ChatStateParser.h" + +namespace Swift { + class PayloadParserFactoryCollection; + + class ChatStateParserFactory : public PayloadParserFactory { + public: + ChatStateParserFactory() { + } + + virtual bool canParse(const String& element, const String& ns, const AttributeMap&) const { + return ns == "http://jabber.org/protocol/chatstates" && + (element == "active" || element == "composing" + || element == "paused" || element == "inactive" || element == "gone"); + } + + virtual PayloadParser* createPayloadParser() { + return new ChatStateParser(); + } + + }; +} diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp index eb4cda0..0857f64 100644 --- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp +++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp @@ -4,6 +4,7 @@ #include "Swiften/Parser/PayloadParserFactory.h" #include "Swiften/Parser/PayloadParsers/ErrorParserFactory.h" #include "Swiften/Parser/PayloadParsers/BodyParserFactory.h" +#include "Swiften/Parser/PayloadParsers/ChatStateParserFactory.h" #include "Swiften/Parser/PayloadParsers/PriorityParserFactory.h" #include "Swiften/Parser/PayloadParsers/ResourceBindParserFactory.h" #include "Swiften/Parser/PayloadParsers/StartSessionParserFactory.h" @@ -41,6 +42,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() { factories_.push_back(shared_ptr<PayloadParserFactory>(new VCardUpdateParserFactory())); factories_.push_back(shared_ptr<PayloadParserFactory>(new VCardParserFactory())); factories_.push_back(shared_ptr<PayloadParserFactory>(new PrivateStorageParserFactory(this))); + factories_.push_back(shared_ptr<PayloadParserFactory>(new ChatStateParserFactory())); foreach(shared_ptr<PayloadParserFactory> factory, factories_) { addFactory(factory.get()); } diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript index 1e1dcd8..7d93d8b 100644 --- a/Swiften/Parser/SConscript +++ b/Swiften/Parser/SConscript @@ -18,6 +18,7 @@ sources = [ "PayloadParserFactory.cpp", "PayloadParserFactoryCollection.cpp", "PayloadParsers/BodyParser.cpp", + "PayloadParsers/ChatStateParser.cpp", "PayloadParsers/DiscoInfoParser.cpp", "PayloadParsers/ErrorParser.cpp", "PayloadParsers/FullPayloadParserFactoryCollection.cpp", diff --git a/Swiften/SConscript b/Swiften/SConscript index e31818c..3f82bfe 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -55,6 +55,7 @@ sources = [ "Serializer/PayloadSerializer.cpp", "Serializer/PayloadSerializerCollection.cpp", "Serializer/PayloadSerializers/CapsInfoSerializer.cpp", + "Serializer/PayloadSerializers/ChatStateSerializer.cpp", "Serializer/PayloadSerializers/DiscoInfoSerializer.cpp", "Serializer/PayloadSerializers/ErrorSerializer.cpp", "Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp", diff --git a/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.cpp b/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.cpp new file mode 100644 index 0000000..0507092 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.cpp @@ -0,0 +1,22 @@ +#include "Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h" + +namespace Swift { + +ChatStateSerializer::ChatStateSerializer() : GenericPayloadSerializer<ChatState>() { +} + +String ChatStateSerializer::serializePayload(boost::shared_ptr<ChatState> chatState) const { + String result("<"); + switch (chatState->getChatState()) { + case ChatState::Active: result += "active"; break; + case ChatState::Composing: result += "composing"; break; + case ChatState::Paused: result += "paused"; break; + case ChatState::Inactive: result += "inactive"; break; + case ChatState::Gone: result += "gone"; break; + default: result += "gone"; break; + } + result += " xmlns=\"http://jabber.org/protocol/chatstates\"/>"; + return result; +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h b/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h new file mode 100644 index 0000000..e99b8b6 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Swiften/Serializer/GenericPayloadSerializer.h" +#include "Swiften/Elements/ChatState.h" + +namespace Swift { + class ChatStateSerializer : public GenericPayloadSerializer<ChatState> { + public: + ChatStateSerializer(); + + virtual String serializePayload(boost::shared_ptr<ChatState> error) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp index fc20018..accf6c6 100644 --- a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp +++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp @@ -2,6 +2,7 @@ #include "Swiften/Base/foreach.h" #include "Swiften/Serializer/PayloadSerializer.h" #include "Swiften/Serializer/PayloadSerializers/BodySerializer.h" +#include "Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h" #include "Swiften/Serializer/PayloadSerializers/PrioritySerializer.h" #include "Swiften/Serializer/PayloadSerializers/ErrorSerializer.h" #include "Swiften/Serializer/PayloadSerializers/RosterSerializer.h" @@ -25,6 +26,7 @@ namespace Swift { FullPayloadSerializerCollection::FullPayloadSerializerCollection() { serializers_.push_back(new BodySerializer()); + serializers_.push_back(new ChatStateSerializer()); serializers_.push_back(new PrioritySerializer()); serializers_.push_back(new ErrorSerializer()); serializers_.push_back(new RosterSerializer()); |