diff options
-rw-r--r-- | facebook/facebook.c | 166 |
1 files changed, 153 insertions, 13 deletions
diff --git a/facebook/facebook.c b/facebook/facebook.c index 526ccfe..63250d9 100644 --- a/facebook/facebook.c +++ b/facebook/facebook.c @@ -26,10 +26,13 @@ #define OPT_SELFMESSAGE 0 #endif -typedef enum { - FB_PTRBIT_NEW_BUDDY, - FB_PTRBIT_UNREAD_MSG -} FbPtrBit; +typedef struct { + struct { + gint new_buddy : 1, + unread_msg : 1; + } flags; + FbApiMessage last_message; +} FbBuddyData; static void fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data); @@ -73,7 +76,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); @@ -223,6 +226,7 @@ fb_cb_api_contacts(FbApi *api, GSList *users, gboolean complete, gpointer data) FbApiUser *user; FbData *fata = data; FbId muid; + FbBuddyData *fbd; gchar uid[FB_ID_STRMAX]; GSList *l; GValue val = G_VALUE_INIT; @@ -388,6 +392,7 @@ fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data) bee_user_t *bu; FbApiMessage *msg; FbData *fata = data; + FbBuddyData *fbd; gboolean mark; gboolean selfmess; gchar *str; @@ -443,13 +448,24 @@ fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data) } if (msg->tid == 0) { + fbd = bu->data; if (mark) { fb_api_read(api, msg->uid, FALSE); } else { - FB_UTIL_PTRBIT_SET(bu->data, FB_PTRBIT_UNREAD_MSG, TRUE); + fbd->flags.unread_msg = TRUE; + } + + if (msg->tstamp <= fbd->last_message.tstamp || + (msg->tstamp == fbd->last_message.tstamp && + g_strcmp0(msg->text, fbd->last_message.text) == 0)) + { + continue; } imcb_buddy_msg(ic, uid, (gchar *) msg->text, flags, tstamp); + g_free(fbd->last_message.text); + fbd->last_message = *msg; + fbd->last_message.text = g_strdup(msg->text); continue; } @@ -465,13 +481,25 @@ 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.unread_msg = TRUE; + } + + if (msg->tstamp < fbd->last_message.tstamp || + (msg->tstamp == fbd->last_message.tstamp && + msg->uid == fbd->last_message.uid && + g_strcmp0(msg->text, fbd->last_message.text) == 0)) + { + continue; } imcb_chat_msg(gc, uid, (gchar *) msg->text, flags, tstamp); + g_free(fbd->last_message.text); + fbd->last_message = *msg; + fbd->last_message.text = g_strdup(msg->text); } } } @@ -853,10 +881,10 @@ fb_buddy_msg(struct im_connection *ic, char *to, char *message, int flags) if (set_getbool(&acct->set, "mark_read_reply") && (bu != NULL) && - FB_UTIL_PTRBIT_GET(bu->data, FB_PTRBIT_UNREAD_MSG)) + (((FbBuddyData *)bu->data)->flags.unread_msg)) { fb_api_read(api, uid, FALSE); - FB_UTIL_PTRBIT_SET(bu->data, FB_PTRBIT_UNREAD_MSG, FALSE); + ((FbBuddyData *)bu->data)->flags.unread_msg = FALSE; } fb_api_message(api, uid, FALSE, message); @@ -939,6 +967,10 @@ static void fb_chat_leave(struct groupchat *gc) { FbData *fata = gc->ic->proto_data; + FbBuddyData *fbd = gc->data; + + g_free(fbd->last_message.text); + g_free(gc->data); fb_data_remove_groupchat(fata, gc); imcb_chat_free(gc); @@ -951,16 +983,18 @@ fb_chat_msg(struct groupchat *gc, char *message, int flags) FbApi *api; FbData *fata = gc->ic->proto_data; FbId tid; + FbBuddyData *fbd; api = fb_data_get_api(fata); tid = FB_ID_FROM_STR(gc->title); fb_api_message(api, tid, TRUE, message); + fbd = gc->data; if (set_getbool(&acct->set, "mark_read_reply") && - GPOINTER_TO_INT(gc->data)) + (fbd->flags.unread_msg)) { fb_api_read(api, tid, TRUE); - gc->data = GINT_TO_POINTER(TRUE); + fbd->flags.unread_msg = FALSE; } } @@ -1001,13 +1035,16 @@ 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; + FbBuddyData *fbd = bu->data; + + g_free(fbd->last_message.text); + g_free(bu->data); } static account_t * @@ -1183,6 +1220,108 @@ fb_cmd_fbjoin(irc_t *irc, char **args) irc_rootmsg(irc, "Joining channel %s", chan); } +static gboolean +fb_buddy_by_name(irc_t *irc, const gchar *name, FbId *id) +{ + irc_user_t *iu; + iu = irc_user_by_name(irc, name); + if (iu == NULL) { + return FALSE; + } + + *id = FB_ID_FROM_STR(iu->bu->handle); + return TRUE; +} + +static gboolean +fb_chat_by_channel(irc_t *irc, struct im_connection *ic, const gchar *name, FbId *id) +{ + const gchar *tag; + const gchar *room; + GSList *l; + irc_channel_t *ich; + + for (l = irc->channels; l != NULL; l = l->next) { + ich = l->data; + + tag = set_getstr(&ich->set, "account"); + if (g_strcmp0(tag, ic->acc->tag) != 0) { + continue; + } + + if (g_strcmp0(ich->name, name) != 0) { + continue; + } + + room = set_getstr(&ich->set, "room"); + *id = FB_ID_FROM_STR(room); + + return TRUE; + } + + return FALSE; +} + +static gboolean +fb_chat_by_index(FbData *fata, const gchar *name, FbId *id) +{ + guint i; + FbId tid; + + i = g_ascii_strtoll(name, NULL, 10); + tid = fb_data_get_thread(fata, i - 1); + + if ((i < 1) || (tid == 0)) { + return FALSE; + } + + *id = tid; + return TRUE; +} + +static void +fb_cmd_fbmark(irc_t *irc, char **args) +{ + account_t *acct; + FbApi *api; + FbData *fata; + FbId id; + gchar *name; + guint oset; + guint i; + gboolean is_gc; + struct im_connection *ic; + + acct = fb_cmd_account(irc, args, 1, &oset); + + if (acct == NULL) { + return; + } + + fata = acct->ic->proto_data; + api = fb_data_get_api(fata); + ic = fb_data_get_connection(fata); + + name = args[oset]; + + if (fb_buddy_by_name(irc, name, &id)) { + irc_rootmsg(irc, "Found user %d", id); // XXX + is_gc = FALSE; + } else if (fb_chat_by_channel(irc, ic, name, &id)) { + irc_rootmsg(irc, "Found chat %d", id); // XXX + is_gc = TRUE; + } else if (fb_chat_by_index(fata, name, &id)) { + irc_rootmsg(irc, "Found chat %d", id); // XXX + is_gc = TRUE; + } else { + irc_rootmsg(irc, "Unknown buddy/chat %s", name); + return; + } + + fb_api_read(api, id, is_gc); + irc_rootmsg(irc, "Marked messages %s %s as read", ((is_gc)?"in chat":"from"), name); +} + G_MODULE_EXPORT void init_plugin(void); @@ -1223,6 +1362,7 @@ init_plugin(void) root_command_add("fbchats", 0, fb_cmd_fbchats, 0); root_command_add("fbcreate", 0, fb_cmd_fbcreate, 0); root_command_add("fbjoin", 0, fb_cmd_fbjoin, 0); + root_command_add("fbmark", 0, fb_cmd_fbmark, 0); } |