/soc/2015/jgeboski/facebook: 3e818c95dfd9: facebook: mark as rea...
James Geboski
jgeboski at gmail.com
Thu Aug 13 06:22:19 EDT 2015
Changeset: 3e818c95dfd9b0e8ec7a63feeaccbe29055f5c13
Author: James Geboski <jgeboski at gmail.com>
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)
More information about the Commits
mailing list