/soc/2015/jgeboski/facebook: 3e818c95dfd9: facebook: mark as rea...
James Geboski <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 3e818c95dfd9b0e8ec7a63feeaccbe29055f5c13 Author: James Geboski <[email protected]> Date: 2015-08-13 06:22 -0400 Branch: facebook URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/3e818c95dfd9 Description: facebook: mark as read only if the conversation is focused diffstat: libpurple/protocols/facebook/data.c | 80 ++++++++++++++++++++++++++------ libpurple/protocols/facebook/data.h | 13 ++++- libpurple/protocols/facebook/facebook.c | 68 ++++++++++++++++++++++++++- 3 files changed, 139 insertions(+), 22 deletions(-) diffs (truncated from 338 to 300 lines): diff --git a/libpurple/protocols/facebook/data.c b/libpurple/protocols/facebook/data.c --- a/libpurple/protocols/facebook/data.c +++ b/libpurple/protocols/facebook/data.c @@ -35,7 +35,8 @@ struct _FbDataPrivate GQueue *msgs; GHashTable *icons; GHashTable *icona; - guint syncev; + GHashTable *unread; + GHashTable *evs; }; static const gchar *fb_props_strs[] = { @@ -54,9 +55,13 @@ static void fb_data_dispose(GObject *obj) { FbDataPrivate *priv = FB_DATA(obj)->priv; + GHashTableIter iter; + gpointer ptr; - if (priv->syncev > 0) { - purple_timeout_remove(priv->syncev); + g_hash_table_iter_init(&iter, priv->evs); + + while (g_hash_table_iter_next(&iter, NULL, &ptr)) { + purple_timeout_remove(GPOINTER_TO_UINT(ptr)); } if (G_LIKELY(priv->api != NULL)) { @@ -64,8 +69,11 @@ fb_data_dispose(GObject *obj) } g_queue_free_full(priv->msgs, (GDestroyNotify) fb_api_message_free); + g_hash_table_destroy(priv->icons); g_hash_table_destroy(priv->icona); + g_hash_table_destroy(priv->unread); + g_hash_table_destroy(priv->evs); } static void @@ -92,6 +100,10 @@ fb_data_init(FbData *fata) priv->icona = g_hash_table_new_full(g_direct_hash, g_direct_equal, (GDestroyNotify) fb_data_icon_free, NULL); + priv->unread = g_hash_table_new_full(fb_id_hash, fb_id_equal, g_free, + NULL); + priv->evs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + NULL); } FbData * @@ -211,36 +223,41 @@ fb_data_save(FbData *fata) } void -fb_data_add_sync_timeout(FbData *fata, guint minutes, GSourceFunc func, - gpointer data) +fb_data_add_timeout(FbData *fata, const gchar *name, guint interval, + GSourceFunc func, gpointer data) { FbDataPrivate *priv; + gchar *key; + guint id; g_return_if_fail(FB_IS_DATA(fata)); priv = fata->priv; - if (priv->syncev > 0) { - purple_timeout_remove(priv->syncev); - } + fb_data_clear_timeout(fata, name, TRUE); - minutes *= 60; - priv->syncev = purple_timeout_add_seconds(minutes, func, data); + key = g_strdup(name); + id = purple_timeout_add_seconds(interval, func, data); + g_hash_table_replace(priv->evs, key, GUINT_TO_POINTER(id)); } void -fb_data_clear_sync_timeout(FbData *fata, gboolean remove) +fb_data_clear_timeout(FbData *fata, const gchar *name, gboolean remove) { FbDataPrivate *priv; + gpointer ptr; + guint id; g_return_if_fail(FB_IS_DATA(fata)); priv = fata->priv; - g_return_if_fail(priv->syncev > 0); - if (remove) { - purple_timeout_remove(priv->syncev); + ptr = g_hash_table_lookup(priv->evs, name); + id = GPOINTER_TO_UINT(ptr); + + if ((id > 0) && remove) { + purple_timeout_remove(id); } - priv->syncev = 0; + g_hash_table_remove(priv->evs, name); } FbApi * @@ -276,6 +293,20 @@ fb_data_get_roomlist(FbData *fata) return priv->roomlist; } +gboolean +fb_data_get_unread(FbData *fata, FbId id) +{ + FbDataPrivate *priv; + gpointer *ptr; + + g_return_val_if_fail(FB_IS_DATA(fata), FALSE); + g_return_val_if_fail(id != 0, FALSE); + priv = fata->priv; + + ptr = g_hash_table_lookup(priv->unread, &id); + return GPOINTER_TO_INT(ptr); +} + void fb_data_set_roomlist(FbData *fata, PurpleRoomlist *list) { @@ -288,6 +319,25 @@ fb_data_set_roomlist(FbData *fata, Purpl } void +fb_data_set_unread(FbData *fata, FbId id, gboolean unread) +{ + FbDataPrivate *priv; + gpointer key; + + g_return_if_fail(FB_IS_DATA(fata)); + g_return_if_fail(id != 0); + priv = fata->priv; + + if (!unread) { + g_hash_table_remove(priv->unread, &id); + return; + } + + key = g_memdup(&id, sizeof id); + g_hash_table_replace(priv->unread, key, GINT_TO_POINTER(unread)); +} + +void fb_data_add_message(FbData *fata, FbApiMessage *msg) { FbDataPrivate *priv; diff --git a/libpurple/protocols/facebook/data.h b/libpurple/protocols/facebook/data.h --- a/libpurple/protocols/facebook/data.h +++ b/libpurple/protocols/facebook/data.h @@ -30,6 +30,7 @@ #include "api.h" #include "http.h" +#include "id.h" #define FB_DATA_ICON_MAX 4 @@ -79,11 +80,11 @@ void fb_data_save(FbData *fata); void -fb_data_add_sync_timeout(FbData *fata, guint minutes, GSourceFunc func, - gpointer data); +fb_data_add_timeout(FbData *fata, const gchar *name, guint interval, + GSourceFunc func, gpointer data); void -fb_data_clear_sync_timeout(FbData *fata, gboolean remove); +fb_data_clear_timeout(FbData *fata, const gchar *name, gboolean remove); FbApi * fb_data_get_api(FbData *fata); @@ -94,10 +95,16 @@ fb_data_get_connection(FbData *fata); PurpleRoomlist * fb_data_get_roomlist(FbData *fata); +gboolean +fb_data_get_unread(FbData *fata, FbId id); + void fb_data_set_roomlist(FbData *fata, PurpleRoomlist *list); void +fb_data_set_unread(FbData *fata, FbId id, gboolean unread); + +void fb_data_add_message(FbData *fata, FbApiMessage *msg); GSList * diff --git a/libpurple/protocols/facebook/facebook.c b/libpurple/protocols/facebook/facebook.c --- a/libpurple/protocols/facebook/facebook.c +++ b/libpurple/protocols/facebook/facebook.c @@ -42,6 +42,7 @@ #include "request.h" #include "roomlist.h" #include "server.h" +#include "signals.h" #include "sslconn.h" #include "status.h" #include "util.h" @@ -208,7 +209,7 @@ fb_cb_sync_contacts(gpointer data) FbData *fata = data; api = fb_data_get_api(fata); - fb_data_clear_sync_timeout(fata, FALSE); + fb_data_clear_timeout(fata, "sync-contacts", FALSE); fb_api_contacts(api); return FALSE; } @@ -320,7 +321,9 @@ fb_cb_api_contacts(FbApi *api, GSList *u sync = 5; } - fb_data_add_sync_timeout(fata, sync, fb_cb_sync_contacts, fata); + sync *= 60 * 1000; + fb_data_add_timeout(fata, "sync-contacts", sync, fb_cb_sync_contacts, + fata); } static void @@ -447,7 +450,7 @@ fb_cb_api_messages(FbApi *api, GSList *m if (msg->tid == 0) { if (mark && !msg->isself) { - fb_api_read(api, msg->uid, FALSE); + fb_data_set_unread(fata, msg->uid, TRUE); } fb_util_serv_got_im(gc, uid, html, flags, time(NULL)); @@ -472,7 +475,7 @@ fb_cb_api_messages(FbApi *api, GSList *m } if (mark && !msg->isself) { - fb_api_read(api, msg->tid, TRUE); + fb_data_set_unread(fata, msg->tid, TRUE); } fb_util_serv_got_chat_in(gc, id, uid, html, flags, time(NULL)); @@ -634,6 +637,53 @@ fb_cb_api_typing(FbApi *api, FbApiTyping } } +static gboolean +fb_cb_conv_read(gpointer data) +{ + const gchar *name; + FbApi *api; + FbData *fata; + FbId id; + PurpleConnection *gc; + PurpleConversation *conv = data; + + gc = purple_conversation_get_connection(conv); + fata = purple_connection_get_protocol_data(gc); + name = purple_conversation_get_name(conv); + id = FB_ID_FROM_STR(name); + + fb_data_clear_timeout(fata, "conv-read", FALSE); + + if (!purple_conversation_has_focus(conv) || + !fb_data_get_unread(fata, id)) + { + return FALSE; + } + + api = fb_data_get_api(fata); + fb_data_set_unread(fata, id, FALSE); + fb_api_read(api, id, PURPLE_IS_CHAT_CONVERSATION(conv)); + return FALSE; +} + +static void +fb_cb_conv_updated(PurpleConversation *conv, PurpleConversationUpdateType type, + gpointer data) +{ + FbData *fata = data; + PurpleAccount *acct; + + acct = purple_conversation_get_account(conv); + + if ((type == PURPLE_CONVERSATION_UPDATE_UNSEEN) && + purple_account_get_bool(acct, "mark-read", TRUE)) + { + /* Use event loop for purple_conversation_has_focus() */ + fb_data_add_timeout(fata, "conv-read", 1, fb_cb_conv_read, + conv); + } +} + static void fb_blist_chat_create(GSList *buddies, gpointer data) { @@ -703,6 +753,7 @@ fb_login(PurpleAccount *acct) _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits