aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--facebook/facebook.c166
1 files changed, 153 insertions, 13 deletions
diff --git a/facebook/facebook.c b/facebook/facebook.c
index 0ced73f..a6753ef 100644
--- a/facebook/facebook.c
+++ b/facebook/facebook.c
@@ -28,10 +28,13 @@
#define FB_SSO_HANDLE "facebook_sso_auth"
-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);
@@ -75,7 +78,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);
@@ -228,6 +231,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;
@@ -393,6 +397,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;
@@ -448,13 +453,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;
}
@@ -470,13 +486,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);
}
}
}
@@ -898,10 +926,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);
@@ -984,6 +1012,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);
@@ -996,16 +1028,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;
}
}
@@ -1046,13 +1080,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 *
@@ -1228,6 +1265,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);
@@ -1268,6 +1407,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);
}