/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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.