diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index cf7babcd..2764e9e1 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -645,6 +645,30 @@ static PurpleDebugUiOps debugUiOps = NULL }; +static void buddyTyping(PurpleAccount *account, const char *who, gpointer null) { + std::string w = who; + size_t pos = w.find("/"); + if (pos != std::string::npos) + w.erase((int) pos, w.length() - (int) pos); + np->handleBuddyTyping(np->m_accounts[account], w); +} + +static void buddyTyped(PurpleAccount *account, const char *who, gpointer null) { + std::string w = who; + size_t pos = w.find("/"); + if (pos != std::string::npos) + w.erase((int) pos, w.length() - (int) pos); + np->handleBuddyTyped(np->m_accounts[account], w); +} + +static void buddyTypingStopped(PurpleAccount *account, const char *who, gpointer null){ + std::string w = who; + size_t pos = w.find("/"); + if (pos != std::string::npos) + w.erase((int) pos, w.length() - (int) pos); + np->handleBuddyStoppedTyping(np->m_accounts[account], w); +} + static bool initPurple(Config &cfg) { bool ret; @@ -661,6 +685,7 @@ static bool initPurple(Config &cfg) { ret = purple_core_init("spectrum"); if (ret) { static int blist_handle; + static int conversation_handle; purple_set_blist(purple_blist_new()); purple_blist_load(); @@ -686,9 +711,9 @@ static bool initPurple(Config &cfg) { // purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", &conversation_handle, PURPLE_CALLBACK(newMessageReceived), NULL); -// purple_signal_connect(purple_conversations_get_handle(), "buddy-typing", &conversation_handle, PURPLE_CALLBACK(buddyTyping), NULL); -// purple_signal_connect(purple_conversations_get_handle(), "buddy-typed", &conversation_handle, PURPLE_CALLBACK(buddyTyped), NULL); -// purple_signal_connect(purple_conversations_get_handle(), "buddy-typing-stopped", &conversation_handle, PURPLE_CALLBACK(buddyTypingStopped), NULL); + purple_signal_connect(purple_conversations_get_handle(), "buddy-typing", &conversation_handle, PURPLE_CALLBACK(buddyTyping), NULL); + purple_signal_connect(purple_conversations_get_handle(), "buddy-typed", &conversation_handle, PURPLE_CALLBACK(buddyTyped), NULL); + purple_signal_connect(purple_conversations_get_handle(), "buddy-typing-stopped", &conversation_handle, PURPLE_CALLBACK(buddyTypingStopped), NULL); purple_signal_connect(purple_connections_get_handle(), "signed-on", &blist_handle,PURPLE_CALLBACK(signed_on), NULL); // purple_signal_connect(purple_blist_get_handle(), "buddy-removed", &blist_handle,PURPLE_CALLBACK(buddyRemoved), NULL); // purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", &blist_handle,PURPLE_CALLBACK(buddySignedOn), NULL); diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index 836d377f..88d4945c 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -58,6 +58,12 @@ class NetworkPlugin { void handleVCard(const std::string &user, unsigned int id, const std::string &legacyName, const std::string &fullName, const std::string &nickname, const std::string &photo); + void handleBuddyTyping(const std::string &user, const std::string &buddyName); + + void handleBuddyTyped(const std::string &user, const std::string &buddyName); + + void handleBuddyStoppedTyping(const std::string &user, const std::string &buddyName); + virtual void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) = 0; virtual void handleLogoutRequest(const std::string &user, const std::string &legacyName) = 0; virtual void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message) = 0; diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index 93154ec8..9faebccf 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -67,6 +67,7 @@ class NetworkPluginServer { void handleParticipantChangedPayload(const std::string &payload); void handleRoomChangedPayload(const std::string &payload); void handleVCardPayload(const std::string &payload); + void handleChatStatePayload(const std::string &payload, Swift::ChatState::ChatStateType type); void handleUserCreated(User *user); void handleRoomJoined(User *user, const std::string &room, const std::string &nickname, const std::string &password); diff --git a/src/networkplugin.cpp b/src/networkplugin.cpp index 7343fa16..6d0b88cc 100644 --- a/src/networkplugin.cpp +++ b/src/networkplugin.cpp @@ -123,6 +123,45 @@ void NetworkPlugin::handleBuddyChanged(const std::string &user, const std::strin send(message); } +void NetworkPlugin::handleBuddyTyping(const std::string &user, const std::string &buddyName) { + pbnetwork::Buddy buddy; + buddy.set_username(user); + buddy.set_buddyname(buddyName); + + std::string message; + buddy.SerializeToString(&message); + + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_TYPING); + + send(message); +} + +void NetworkPlugin::handleBuddyTyped(const std::string &user, const std::string &buddyName) { + pbnetwork::Buddy buddy; + buddy.set_username(user); + buddy.set_buddyname(buddyName); + + std::string message; + buddy.SerializeToString(&message); + + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_TYPED); + + send(message); +} + +void NetworkPlugin::handleBuddyStoppedTyping(const std::string &user, const std::string &buddyName) { + pbnetwork::Buddy buddy; + buddy.set_username(user); + buddy.set_buddyname(buddyName); + + std::string message; + buddy.SerializeToString(&message); + + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_STOPPED_TYPING); + + send(message); +} + void NetworkPlugin::handleConnected(const std::string &user) { std::cout << "LOGIN SENT\n"; pbnetwork::Connected d; diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index cdea43fd..d3995836 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -223,6 +223,30 @@ void NetworkPluginServer::handleVCardPayload(const std::string &data) { m_vcardResponder->sendVCard(payload.id(), vcard); } +void NetworkPluginServer::handleChatStatePayload(const std::string &data, Swift::ChatState::ChatStateType type) { + pbnetwork::Buddy payload; + if (payload.ParseFromString(data) == false) { + // TODO: ERROR + return; + } + + User *user = m_userManager->getUser(payload.username()); + if (!user) + return; + + NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(payload.buddyname()); + if (!conv) { + std::cout << "handling chatstate: NO conv with buddyname=" << payload.buddyname() << "\n"; + return; + } + + boost::shared_ptr msg(new Swift::Message()); + msg->addPayload(boost::make_shared(type)); + + conv->handleMessage(msg); + +} + void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) { pbnetwork::Buddy payload; if (payload.ParseFromString(data) == false) { @@ -375,6 +399,15 @@ void NetworkPluginServer::handleDataRead(Client *c, const Swift::SafeByteArray & case pbnetwork::WrapperMessage_Type_TYPE_VCARD: handleVCardPayload(wrapper.payload()); break; + case pbnetwork::WrapperMessage_Type_TYPE_BUDDY_TYPING: + handleChatStatePayload(wrapper.payload(), Swift::ChatState::Composing); + break; + case pbnetwork::WrapperMessage_Type_TYPE_BUDDY_TYPED: + handleChatStatePayload(wrapper.payload(), Swift::ChatState::Paused); + break; + case pbnetwork::WrapperMessage_Type_TYPE_BUDDY_STOPPED_TYPING: + handleChatStatePayload(wrapper.payload(), Swift::ChatState::Active); + break; default: return; } diff --git a/src/pbnetwork.proto b/src/pbnetwork.proto index 75de5fba..1cbf782d 100644 --- a/src/pbnetwork.proto +++ b/src/pbnetwork.proto @@ -25,9 +25,9 @@ message Logout { message Buddy { required string userName = 1; required string buddyName = 2; - required string alias = 3; - required string groups = 4; - required int32 status = 5; + optional string alias = 3; + optional string groups = 4; + optional int32 status = 5; optional string statusMessage = 6; optional string iconHash = 7; } @@ -89,6 +89,9 @@ message WrapperMessage { TYPE_ROOM_SUBJECT_CHANGED = 15; TYPE_VCARD = 16; TYPE_STATUS_CHANGED = 17; + TYPE_BUDDY_TYPING = 18; + TYPE_BUDDY_STOPPED_TYPING = 19; + TYPE_BUDDY_TYPED = 20; } required Type type = 1; optional bytes payload = 2;