aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--facebook/facebook.c68
1 files changed, 56 insertions, 12 deletions
diff --git a/facebook/facebook.c b/facebook/facebook.c
index a9cae84..32c022e 100644
--- a/facebook/facebook.c
+++ b/facebook/facebook.c
@@ -38,6 +38,22 @@ typedef enum {
FB_PTRBIT_UNREAD_MSG
} FbPtrBit;
+typedef struct {
+ gint flags;
+ FbApiMessage last_message;
+} FbBuddyData;
+
+#define FB_GET_FLAG(f, b) \
+ ((((FbBuddyData *)(f)->data)->flags) & (1 << (b)))
+
+#define FB_SET_FLAG(f, b, v) \
+ G_STMT_START { \
+ FbBuddyData *__fbd; \
+ __fbd = (f)->data; \
+ (__fbd->flags) &= ~(1 << (b)); \
+ (__fbd->flags) |= ((v) << (b)); \
+ } G_STMT_END
+
static void
fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data);
@@ -80,7 +96,7 @@ fb_groupchat_new(struct im_connection *ic, FbId tid, const gchar *name)
}
gc = imcb_chat_new(ic, stid);
- gc->data = GINT_TO_POINTER(FALSE);
+ gc->data = g_new0(FbBuddyData, 1);
fb_data_add_groupchat(fata, gc);
@@ -218,6 +234,7 @@ fb_cb_api_contacts(FbApi *api, GSList *users, gboolean complete, gpointer data)
GSList *l;
GValue val = G_VALUE_INIT;
struct im_connection *ic;
+ FbBuddyData *fbd;
ic = fb_data_get_connection(fata);
@@ -239,7 +256,7 @@ fb_cb_api_contacts(FbApi *api, GSList *users, gboolean complete, gpointer data)
imcb_rename_buddy(ic, uid, user->name);
bu = imcb_buddy_by_handle(ic, uid);
- FB_UTIL_PTRBIT_SET(bu->data, FB_PTRBIT_NEW_BUDDY, TRUE);
+ FB_SET_FLAG(bu, FB_PTRBIT_NEW_BUDDY, TRUE);
}
if (!complete) {
@@ -256,8 +273,8 @@ fb_cb_api_contacts(FbApi *api, GSList *users, gboolean complete, gpointer data)
continue;
}
- if (FB_UTIL_PTRBIT_GET(bu->data, FB_PTRBIT_NEW_BUDDY)) {
- FB_UTIL_PTRBIT_SET(bu->data, FB_PTRBIT_NEW_BUDDY, FALSE);
+ if (FB_GET_FLAG(bu, FB_PTRBIT_NEW_BUDDY)) {
+ FB_SET_FLAG(bu, FB_PTRBIT_NEW_BUDDY, FALSE);
} else {
imcb_remove_buddy(ic, bu->handle, NULL);
}
@@ -379,6 +396,7 @@ fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data)
struct groupchat *gc;
struct im_connection *ic;
bee_user_t *bu;
+ FbBuddyData *fbd;
ic = fb_data_get_connection(fata);
acct = ic->acc;
@@ -422,10 +440,16 @@ fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data)
if (mark) {
fb_api_read(api, msg->uid, FALSE);
} else {
- FB_UTIL_PTRBIT_SET(bu->data, FB_PTRBIT_UNREAD_MSG, TRUE);
+ FB_SET_FLAG(bu, FB_PTRBIT_UNREAD_MSG, TRUE);
+ }
+
+ fbd = bu->data;
+ if (msg->tstamp <= fbd->last_message.tstamp) {
+ continue;
}
imcb_buddy_msg(ic, uid, (gchar *) msg->text, flags, tstamp);
+ fbd->last_message = *msg;
continue;
}
@@ -441,13 +465,21 @@ fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data)
}
if (gc != NULL) {
+ fbd = gc->data;
if (mark) {
fb_api_read(api, msg->tid, TRUE);
} else {
- gc->data = GINT_TO_POINTER(TRUE);
+ fbd->flags = TRUE;
+ }
+
+ if (msg->tstamp < fbd->last_message.tstamp ||
+ (msg->tstamp == fbd->last_message.tstamp &&
+ msg->uid == fbd->last_message.uid)) {
+ continue;
}
imcb_chat_msg(gc, uid, (gchar *) msg->text, flags, tstamp);
+ fbd->last_message = *msg;
}
}
}
@@ -773,15 +805,22 @@ fb_buddy_msg(struct im_connection *ic, char *to, char *message, int flags)
FbId uid;
account_t *acct;
bee_user_t *bu;
+ FbBuddyData *fbd;
acct = ic->acc;
api = fb_data_get_api(fata);
uid = FB_ID_FROM_STR(to);
fb_api_message(api, uid, FALSE, message);
bu = bee_user_by_handle(ic->bee, ic, to);
- if (set_getbool(&acct->set, "mark_read_reply") && bu != NULL && FB_UTIL_PTRBIT_GET(bu->data, FB_PTRBIT_UNREAD_MSG)) {
+ if (bu == NULL) {
+ return 0;
+ }
+
+ fbd = bu->data;
+ if (set_getbool(&acct->set, "mark_read_reply") &&
+ FB_GET_FLAG(bu, FB_PTRBIT_UNREAD_MSG)) {
fb_api_read(api, uid, FALSE);
- FB_UTIL_PTRBIT_SET(bu->data, FB_PTRBIT_UNREAD_MSG, FALSE);
+ FB_SET_FLAG(bu, FB_PTRBIT_UNREAD_MSG, FALSE);
}
return 0;
}
@@ -863,6 +902,8 @@ fb_chat_leave(struct groupchat *gc)
{
FbData *fata = gc->ic->proto_data;
+ g_free(gc->data);
+
fb_data_remove_groupchat(fata, gc);
imcb_chat_free(gc);
}
@@ -874,14 +915,17 @@ fb_chat_msg(struct groupchat *gc, char *message, int flags)
FbData *fata = gc->ic->proto_data;
FbId tid;
account_t *acct;
+ FbBuddyData *fbd;
acct = gc->ic->acc;
api = fb_data_get_api(fata);
tid = FB_ID_FROM_STR(gc->title);
fb_api_message(api, tid, TRUE, message);
- if (set_getbool(&acct->set, "mark_read_reply") && GPOINTER_TO_INT(gc->data)) {
+
+ fbd = gc->data;
+ if (set_getbool(&acct->set, "mark_read_reply") && fbd->flags) {
fb_api_read(api, tid, TRUE);
- gc->data = GINT_TO_POINTER(TRUE);
+ fbd->flags = FALSE;
}
}
@@ -922,13 +966,13 @@ fb_away_states(struct im_connection *ic)
static void
fb_buddy_data_add(struct bee_user *bu)
{
- bu->data = GINT_TO_POINTER(0);
+ bu->data = g_new0(FbBuddyData, 1);
}
static void
fb_buddy_data_free(struct bee_user *bu)
{
- bu->data = NULL;
+ g_free(bu->data);
}
static account_t *