From: Drew Fisher Date: Thu, 1 May 2014 04:52:02 +0000 (-0700) Subject: refactor, status messages, incoming typing notifications X-Git-Url: http://git.zarvox.org/shortlog/2011?a=commitdiff_plain;h=aa15c8250e856d4e66f3591d88bc01b5666daa08;p=imoo.git refactor, status messages, incoming typing notifications --- diff --git a/ribbon/ribbonaccounts.cpp b/ribbon/ribbonaccounts.cpp index e87a5cd..c086c33 100644 --- a/ribbon/ribbonaccounts.cpp +++ b/ribbon/ribbonaccounts.cpp @@ -19,6 +19,14 @@ QVariantMap RibbonAccounts::context(PurpleAccount* acct) return m; } +QVariantMap RibbonAccounts::context(PurpleBuddy* buddy) +{ + PurpleAccount* p_acct = purple_buddy_get_account(buddy); + QVariantMap m = context(p_acct); + m["buddy"] = QString::fromUtf8(purple_buddy_get_name(buddy)); + return m; +} + void RibbonAccounts::handleExternalEvent(QString method, QVariantMap params) { qDebug() << "called" << method << "on" << params; diff --git a/ribbon/ribbonaccounts.h b/ribbon/ribbonaccounts.h index 019f9d9..b79aedc 100644 --- a/ribbon/ribbonaccounts.h +++ b/ribbon/ribbonaccounts.h @@ -16,6 +16,7 @@ public: RibbonAccounts(RibbonManager* parent = 0); ~RibbonAccounts(); static QVariantMap context(PurpleAccount* acct); + static QVariantMap context(PurpleBuddy* buddy); public slots: void handleExternalEvent(QString method, QVariantMap params); signals: diff --git a/ribbon/ribbonblist.cpp b/ribbon/ribbonblist.cpp index 8438495..f6ca007 100644 --- a/ribbon/ribbonblist.cpp +++ b/ribbon/ribbonblist.cpp @@ -1,7 +1,9 @@ #include "ribbonblist.h" #include "ribbonmanager.h" +#include "ribbonaccounts.h" #include +#include RibbonBlist::RibbonBlist(RibbonManager* parent) : QObject((QObject*)parent) { @@ -12,22 +14,73 @@ RibbonBlist::~RibbonBlist() { } -static void buddy_signed_on(PurpleBuddy* buddy, void* data) +static void buddy_status_changed(PurpleBuddy* buddy, PurpleStatus* old_status, + PurpleStatus* status, void* data) { - qDebug() << purple_buddy_get_contact_alias(buddy) << "signed on"; + Q_UNUSED(old_status); + PurplePresence* presence = purple_status_get_presence(status); + PurpleStatusType* status_type = purple_status_get_type(status); + + // Some debugging info + qDebug() << "status change:" << purple_buddy_get_contact_alias(buddy); + qDebug() << "\tavailable:" << purple_presence_is_available(presence); + qDebug() << "\tonline:" << purple_presence_is_online(presence); + qDebug() << "\ttype_id:" << purple_status_type_get_id(status_type); + qDebug() << "\ttype_name:" << purple_status_type_get_name(status_type); + + // Get status message, if one is available + QString message(""); + PurplePlugin* prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(buddy))); + if (prpl != NULL) { + PurplePluginProtocolInfo* prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + if (prpl_info && prpl_info->status_text && purple_account_get_connection(purple_buddy_get_account(buddy))) { + char* msg = prpl_info->status_text(buddy); + message = QString::fromUtf8(msg); + qDebug() << "\tstatus:" << message; + } + } + + QVariantMap m = RibbonAccounts::context(buddy); + // Include the buddy's new status + QVariantMap m_status; + m_status["status"] = QString::fromUtf8(purple_status_type_get_id(status_type)); + m_status["status_msg"] = message; + m_status["idle"] = purple_presence_is_idle(presence); + // Only include idle information if the user is flagged as idle + if (purple_presence_is_idle(presence)) { + // libpurple gives us a localized time_t for when the user went idle + QVariantMap idle_data; + idle_data["idle_time"] = QDateTime::fromTime_t(purple_presence_get_idle_time(presence)); + m_status["idle_data"] = idle_data; + } - PurpleAccount* acct = purple_buddy_get_account(buddy); - QVariantMap m; - m["proto"] = QString::fromUtf8(purple_account_get_protocol_id(acct)); - m["account"] = QString::fromUtf8(purple_account_get_username(acct)); - m["buddy"] = QString::fromUtf8(purple_buddy_get_name(buddy)); + m["status"] = m_status; + RibbonBlist* blist = (RibbonBlist*)data; + blist->event(QString::fromUtf8("blist"), + QString::fromUtf8("buddy_status_changed"), + m); +} +static void buddy_signed_on(PurpleBuddy* buddy, void* data) +{ + qDebug() << purple_buddy_get_contact_alias(buddy) << "signed on"; + QVariantMap m = RibbonAccounts::context(buddy); RibbonBlist* blist = (RibbonBlist*)data; blist->event(QString::fromUtf8("blist"), QString::fromUtf8("buddy_signed_on"), m); } +static void buddy_signed_off(PurpleBuddy* buddy, void* data) +{ + qDebug() << purple_buddy_get_contact_alias(buddy) << "signed off"; + QVariantMap m = RibbonAccounts::context(buddy); + RibbonBlist* blist = (RibbonBlist*)data; + blist->event(QString::fromUtf8("blist"), + QString::fromUtf8("buddy_signed_off"), + m); +} + void RibbonBlist::init() { /* Create and load the buddylist */ @@ -39,4 +92,8 @@ void RibbonBlist::init() void *blist_handle = purple_blist_get_handle(); purple_signal_connect(blist_handle, "buddy-signed-on", &handle, PURPLE_CALLBACK(buddy_signed_on), this); + purple_signal_connect(blist_handle, "buddy-signed-off", &handle, + PURPLE_CALLBACK(buddy_signed_off), this); + purple_signal_connect(blist_handle, "buddy-status-changed", &handle, + PURPLE_CALLBACK(buddy_status_changed), this); } diff --git a/ribbon/ribbonconversations.cpp b/ribbon/ribbonconversations.cpp index 7017c46..0b37d88 100644 --- a/ribbon/ribbonconversations.cpp +++ b/ribbon/ribbonconversations.cpp @@ -1,4 +1,5 @@ #include "ribbonconversations.h" +#include "ribbonaccounts.h" #include "ribbonmanager.h" #include "ribbonutil.h" @@ -8,9 +9,20 @@ static void static_received_im_msg(PurpleAccount *account, char *sender, char *message, PurpleConversation *conv, PurpleMessageFlags flags, void* data) { - Q_UNUSED(data); - RibbonManager* r = static_cast(account->ui_data); - r->conversations()->received_im_msg(account, sender, message, conv, flags); + RibbonConversations* c = (RibbonConversations*)data; + c->received_im_msg(account, sender, message, conv, flags); +} + +static void static_buddy_typing(PurpleAccount* account, const char* name, void* data) +{ + RibbonConversations* c = (RibbonConversations*)data; + c->buddy_typing(account, name, RibbonConversations::TYPING); +} + +static void static_buddy_typing_stopped(PurpleAccount* account, const char* name, void* data) +{ + RibbonConversations* c = (RibbonConversations*)data; + c->buddy_typing(account, name, RibbonConversations::STOPPED); } RibbonConversations::RibbonConversations(RibbonManager* parent) : QObject((QObject*)parent) @@ -27,26 +39,60 @@ void RibbonConversations::init() static int handle; void *conversations_handle = purple_conversations_get_handle(); purple_signal_connect(conversations_handle, "received-im-msg", &handle, - PURPLE_CALLBACK(static_received_im_msg), NULL); + PURPLE_CALLBACK(static_received_im_msg), this); + purple_signal_connect(conversations_handle, "buddy-typing", &handle, + PURPLE_CALLBACK(static_buddy_typing), this); + purple_signal_connect(conversations_handle, "buddy-typing-stopped", &handle, + PURPLE_CALLBACK(static_buddy_typing_stopped), this); } void RibbonConversations::received_im_msg(PurpleAccount *account, char *sender, char *message, PurpleConversation *conv, PurpleMessageFlags flags) { Q_UNUSED(flags); - if (conv==NULL) { + if (conv == NULL) { conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); } + QVariantMap m = RibbonAccounts::context(account); + m["buddy"] = QString::fromUtf8(sender); + m["timestamp"] = QDateTime::currentDateTimeUtc(); + m["message"] = QString::fromUtf8(message); + emit event(QString::fromUtf8("conversations"), + QString::fromUtf8("recv_im"), + m); qDebug() << QDateTime::currentDateTime().toString("hh:mm:ss") << sender << purple_conversation_get_name(conv) << message; } +void RibbonConversations::buddy_typing(PurpleAccount *account, const char* buddy, TypingState state) +{ + QVariantMap m = RibbonAccounts::context(account); + m["buddy"] = QString::fromUtf8(buddy); + switch (state) { + case STOPPED: m["state"] = QString::fromUtf8("stopped"); break; + case TYPING: m["state"] = QString::fromUtf8("typing"); break; + } + qDebug() << buddy << "type state is" << m["state"]; + emit event(QString::fromUtf8("conversations"), + QString::fromUtf8("buddy_typing_state"), + m); +} + void RibbonConversations::send_im(QString protocol, QString account, QString buddy, QString message) { qDebug() << "sending im from" << protocol << account << "to" << buddy << ":" << message; PurpleAccount* p_acct = purple_accounts_find(account.toUtf8(), protocol.toUtf8()); - PurpleBuddy* p_buddy = purple_find_buddy(p_acct, buddy.toUtf8()); - // TODO: call the purple functions to send an IM - Q_UNUSED(p_buddy); + if (!p_acct) { + qWarning() << "No such account" << protocol << account; + return; + } + PurpleConversation* p_conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, + buddy.toUtf8(), p_acct); + if (!p_conv) { + // Lazily create conversation objects if needed + p_conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, p_acct, buddy.toUtf8()); + } + PurpleConvIm* p_conv_im = purple_conversation_get_im_data(p_conv); + purple_conv_im_send(p_conv_im, message.toUtf8()); } void RibbonConversations::handleExternalEvent(QString method, QVariantMap context) diff --git a/ribbon/ribbonconversations.h b/ribbon/ribbonconversations.h index c31c026..99e50d8 100644 --- a/ribbon/ribbonconversations.h +++ b/ribbon/ribbonconversations.h @@ -11,11 +11,16 @@ class RibbonManager; class RibbonConversations : public QObject { Q_OBJECT public: + enum TypingState { + STOPPED = 0, + TYPING = 1, + }; RibbonConversations(RibbonManager* parent = 0); ~RibbonConversations(); void init(); void received_im_msg(PurpleAccount *account, char *sender, char *message, PurpleConversation *conv, PurpleMessageFlags flags); + void buddy_typing(PurpleAccount *account, const char* buddy, TypingState state); void handleExternalEvent(QString method, QVariantMap context); signals: void event(QString source, QString signal, QVariantMap context); diff --git a/ribbon/ribbonmanager.cpp b/ribbon/ribbonmanager.cpp index 467bbfa..8f14f34 100644 --- a/ribbon/ribbonmanager.cpp +++ b/ribbon/ribbonmanager.cpp @@ -179,11 +179,11 @@ const char* RibbonManager::get_version(void) void RibbonManager::handleExternalEvent(QString destination, QString method, QVariantMap context) { - // TODO: handle external event - qDebug() << "TODO: do something with" << destination << "." << method << "(" << context << ")"; if (destination == "accounts") { _accounts->handleExternalEvent(method, context); } else if (destination == "conversations") { _conversations->handleExternalEvent(method, context); + } else { + qDebug() << "TODO: do something with" << destination << "." << method << "(" << context << ")"; } }