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 995ad59..3079d0c 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);          }      }  } @@ -850,10 +878,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); @@ -936,6 +964,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); @@ -948,16 +980,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;      }  } @@ -998,13 +1032,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 * @@ -1180,6 +1217,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); @@ -1220,6 +1359,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);  } | 
