Changeset 830864d


Ignore:
Timestamp:
2015-03-15T09:31:18Z (9 years ago)
Author:
dequis <dx@…>
Children:
ac6855b3
Parents:
c0e4c22
git-author:
dequis <dx@…> (05-03-15 10:31:24)
git-committer:
dequis <dx@…> (15-03-15 09:31:18)
Message:

WIP placeholder channels with hipchat implementation

i was going to clean this up and split in two commits but uhhh...
maybe some other day, i'm tired now

not very tested and i'm not 100% happy about the design, but sucks way
less than what i had in the hip-cat branch

feedback still appreciated.

this adds channels to the channel list without creating groupchats for
them, allowing users to /join them. what the hip-cat branch did before
but with proper api and hopefully less dumb behavior

it still 'leaks' them intentionally, just like it did before, but now it
prevents saving them to the xml so yay

also slightly improved channel name generation, refactored
bee_irc_chat_name_hint into three or four functions, and so on

Files:
8 edited

Legend:

Unmodified
Added
Removed
  • irc.h

    rc0e4c22 r830864d  
    147147        IRC_CHANNEL_TEMP = 2,   /* Erase the channel when the user leaves,
    148148                                   and don't save it. */
     149
     150        /* Show a placeholder of the channel in listings, but don't save it */
     151        IRC_CHANNEL_KEEP_PLACEHOLDER = 4,
    149152
    150153        /* Hack: Set this flag right before jumping into IM when we expect
     
    299302void irc_channel_name_strip(char *name);
    300303int irc_channel_name_cmp(const char *a_, const char *b_);
     304char *irc_channel_name_gen(bee_t *bee, const char *name);
     305gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name);
    301306void irc_channel_update_ops(irc_channel_t *ic, char *value);
    302307char *set_eval_irc_channel_ops(struct set *set, char *value);
  • irc_channel.c

    rc0e4c22 r830864d  
    276276                if (ic->irc->status & USTATUS_SHUTDOWN) {
    277277                        /* Don't do anything fancy when we're shutting down anyway. */
    278                 } else if (ic->flags & IRC_CHANNEL_TEMP) {
     278                } else if (ic->flags & IRC_CHANNEL_TEMP && !(ic->flags & IRC_CHANNEL_KEEP_PLACEHOLDER)) {
    279279                        irc_channel_free_soon(ic);
    280280                } else {
     
    556556}
    557557
     558gboolean irc_channel_is_unused(bee_t *bee, char *name)
     559{
     560        char *type, *chat_type;
     561        irc_channel_t *oic;
     562
     563        if (!irc_channel_name_ok(name)) {
     564                return FALSE;
     565        }
     566
     567        if (!(oic = irc_channel_by_name(bee->ui_data, name))) {
     568                return TRUE;
     569        }
     570
     571        type = set_getstr(&oic->set, "type");
     572        chat_type = set_getstr(&oic->set, "chat_type");
     573
     574        if (type && chat_type && oic->data == FALSE &&
     575            strcmp(type, "chat") == 0 &&
     576            strcmp(chat_type, "groupchat") == 0) {
     577                /* There's a channel with this name already, but it looks
     578                   like it's not in use yet. Most likely the IRC client
     579                   rejoined the channel after a reconnect. Remove it so
     580                   we can reuse its name. */
     581                irc_channel_free(oic);
     582                return TRUE;
     583        }
     584
     585        return FALSE;
     586}
     587
     588char *irc_channel_name_gen(bee_t *bee, const char *hint)
     589{
     590        char name[MAX_NICK_LENGTH + 1] = { 0 };
     591
     592        name[0] = '#';
     593        strncpy(name + 1, hint, MAX_NICK_LENGTH - 1);
     594        name[MAX_NICK_LENGTH] = '\0';
     595
     596        irc_channel_name_strip(name);
     597
     598        if (set_getbool(&bee->set, "lcnicks")) {
     599                nick_lc(bee->ui_data, name + 1);
     600        }
     601
     602        while (!irc_channel_is_unused(bee, name)) {
     603                underscore_dedupe(name);
     604        }
     605
     606        return g_strdup(name);
     607}
     608
     609gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name)
     610{
     611        irc_t *irc = ic->irc;
     612        char *full_name;
     613
     614        /* Don't rename a channel if the user's in it already. */
     615        if (ic->flags & IRC_CHANNEL_JOINED) {
     616                return FALSE;
     617        }
     618
     619        if (!(full_name = irc_channel_name_gen(irc->b, name))) {
     620                return FALSE;
     621        }
     622
     623        g_free(ic->name);
     624        ic->name = full_name;
     625
     626        return TRUE;
     627}
     628
    558629static gint irc_channel_user_cmp(gconstpointer a_, gconstpointer b_)
    559630{
  • irc_im.c

    rc0e4c22 r830864d  
    609609}
    610610
     611static gboolean bee_irc_chat_placeholder_new(bee_t *bee, struct im_connection *ic, const char *handle,
     612                                             const char *name, const char *topic)
     613{
     614        irc_t *irc = bee->ui_data;
     615        irc_channel_t *ircc;
     616        char *full_name = irc_channel_name_gen(bee, name);
     617
     618        ircc = irc_channel_new(irc, full_name);
     619
     620        set_setstr(&ircc->set, "type", "chat");
     621        set_setstr(&ircc->set, "chat_type", "placeholder");
     622        set_setstr(&ircc->set, "account", ic->acc->tag);
     623        set_setstr(&ircc->set, "room", (char *) handle);
     624
     625        irc_channel_set_topic(ircc, topic, NULL);
     626
     627        g_free(full_name);
     628
     629        return TRUE;
     630}
     631
    611632static gboolean bee_irc_chat_log(bee_t *bee, struct groupchat *c, const char *text)
    612633{
     
    701722static gboolean bee_irc_chat_name_hint(bee_t *bee, struct groupchat *c, const char *name)
    702723{
    703         irc_t *irc = bee->ui_data;
    704         irc_channel_t *ic = c->ui_data, *oic;
    705         char stripped[MAX_NICK_LENGTH + 1], *full_name;
    706 
    707         if (ic == NULL) {
    708                 return FALSE;
    709         }
    710 
    711         /* Don't rename a channel if the user's in it already. */
    712         if (ic->flags & IRC_CHANNEL_JOINED) {
    713                 return FALSE;
    714         }
    715 
    716         strncpy(stripped, name, MAX_NICK_LENGTH);
    717         stripped[MAX_NICK_LENGTH] = '\0';
    718         irc_channel_name_strip(stripped);
    719         if (set_getbool(&bee->set, "lcnicks")) {
    720                 nick_lc(irc, stripped);
    721         }
    722 
    723         if (stripped[0] == '\0') {
    724                 return FALSE;
    725         }
    726 
    727         full_name = g_strdup_printf("#%s", stripped);
    728         if ((oic = irc_channel_by_name(irc, full_name))) {
    729                 char *type, *chat_type;
    730 
    731                 type = set_getstr(&oic->set, "type");
    732                 chat_type = set_getstr(&oic->set, "chat_type");
    733 
    734                 if (type && chat_type && oic->data == FALSE &&
    735                     strcmp(type, "chat") == 0 &&
    736                     strcmp(chat_type, "groupchat") == 0) {
    737                         /* There's a channel with this name already, but it looks
    738                            like it's not in use yet. Most likely the IRC client
    739                            rejoined the channel after a reconnect. Remove it so
    740                            we can reuse its name. */
    741                         irc_channel_free(oic);
    742                 } else {
    743                         g_free(full_name);
    744                         return FALSE;
    745                 }
    746         }
    747 
    748         g_free(ic->name);
    749         ic->name = full_name;
    750 
    751         return TRUE;
     724        return irc_channel_name_hint(c->ui_data, name);
    752725}
    753726
     
    877850static gboolean bee_irc_channel_chat_join(irc_channel_t *ic)
    878851{
    879         char *acc_s, *room;
     852        char *acc_s, *room, *chat_type;
    880853        account_t *acc;
    881854
    882         if (strcmp(set_getstr(&ic->set, "chat_type"), "room") != 0) {
     855        chat_type = set_getstr(&ic->set, "chat_type");
     856
     857        if (strcmp(chat_type, "room") != 0 && strcmp(chat_type, "placeholder") != 0) {
    883858                return TRUE;
    884859        }
     
    10361011        struct irc_channel *ic = set->data;
    10371012
     1013        ic->flags &= ~(IRC_CHANNEL_TEMP | IRC_CHANNEL_KEEP_PLACEHOLDER);
     1014
    10381015        if (strcmp(value, "groupchat") == 0) {
    10391016                ic->flags |= IRC_CHANNEL_TEMP;
    10401017        } else if (strcmp(value, "room") == 0) {
    1041                 ic->flags &= ~IRC_CHANNEL_TEMP;
     1018                // beep boop
     1019        } else if (strcmp(value, "placeholder") == 0) {
     1020                ic->flags |= IRC_CHANNEL_TEMP | IRC_CHANNEL_KEEP_PLACEHOLDER;
    10421021        } else {
    10431022                return NULL;
     
    11231102        bee_irc_chat_new,
    11241103        bee_irc_chat_free,
     1104        bee_irc_chat_placeholder_new,
    11251105        bee_irc_chat_log,
    11261106        bee_irc_chat_msg,
  • nick.c

    rc0e4c22 r830864d  
    214214}
    215215
     216/* Used for nicks and channel names too! */
     217void underscore_dedupe(char nick[MAX_NICK_LENGTH + 1])
     218{
     219        if (strlen(nick) < (MAX_NICK_LENGTH - 1)) {
     220                nick[strlen(nick) + 1] = 0;
     221                nick[strlen(nick)] = '_';
     222        } else {
     223                /* We've got no more space for underscores,
     224                   so truncate it and replace the last three
     225                   chars with a random "_XX" suffix */
     226                int len = truncate_utf8(nick, MAX_NICK_LENGTH - 3);
     227                nick[len] = '_';
     228                g_snprintf(nick + len + 1, 3, "%2x", rand());
     229        }
     230}
     231
    216232void nick_dedupe(bee_user_t *bu, char nick[MAX_NICK_LENGTH + 1])
    217233{
     
    224240        while (!nick_ok(irc, nick) ||
    225241               ((iu = irc_user_by_name(irc, nick)) && iu->bu != bu)) {
    226                 if (strlen(nick) < (MAX_NICK_LENGTH - 1)) {
    227                         nick[strlen(nick) + 1] = 0;
    228                         nick[strlen(nick)] = '_';
    229                 } else {
    230                         /* We've got no more space for underscores,
    231                            so truncate it and replace the last three
    232                            chars with a random "_XX" suffix */
    233                         int len = truncate_utf8(nick, MAX_NICK_LENGTH - 3);
    234                         nick[len] = '_';
    235                         g_snprintf(nick + len + 1, 3, "%2x", rand());
    236                 }
     242
     243                underscore_dedupe(nick);
    237244
    238245                if (inf_protection-- == 0) {
  • nick.h

    rc0e4c22 r830864d  
    2828char *nick_get(bee_user_t *bu);
    2929char *nick_gen(bee_user_t *bu);
     30void underscore_dedupe(char nick[MAX_NICK_LENGTH + 1]);
    3031void nick_dedupe(bee_user_t * bu, char nick[MAX_NICK_LENGTH + 1]);
    3132int nick_saved(bee_user_t *bu);
  • protocols/bee.h

    rc0e4c22 r830864d  
    115115        gboolean (*chat_new)(bee_t *bee, struct groupchat *c);
    116116        gboolean (*chat_free)(bee_t *bee, struct groupchat *c);
     117        gboolean (*chat_placeholder_new)(bee_t *bee, struct im_connection *ic, const char *handle,
     118                                         const char *name, const char *topic);
    117119        /* System messages of any kind. */
    118120        gboolean (*chat_log)(bee_t *bee, struct groupchat *c, const char *text);
     
    165167 *   user, too. */
    166168G_MODULE_EXPORT struct groupchat *imcb_chat_new(struct im_connection *ic, const char *handle);
     169G_MODULE_EXPORT void imcb_chat_placeholder_new(struct im_connection *ic, const char *handle, const char *name,
     170                                               const char *topic);
    167171G_MODULE_EXPORT void imcb_chat_name_hint(struct groupchat *c, const char *name);
    168172G_MODULE_EXPORT void imcb_chat_free(struct groupchat *c);
  • protocols/bee_chat.c

    rc0e4c22 r830864d  
    5454}
    5555
     56void imcb_chat_placeholder_new(struct im_connection *ic, const char *handle, const char *name, const char *topic)
     57{
     58        bee_t *bee = ic->bee;
     59
     60        if (bee->ui->chat_placeholder_new) {
     61                bee->ui->chat_placeholder_new(bee, ic, handle, name, topic);
     62        }
     63}
     64
    5665void imcb_chat_name_hint(struct groupchat *c, const char *name)
    5766{
  • protocols/jabber/hipchat.c

    rc0e4c22 r830864d  
    132132        while ((c = xt_find_node(c, "item"))) {
    133133                struct xt_node *c2;
    134                 struct groupchat *gc;
    135                 struct irc_channel *ircc;
    136134                char *topic = NULL;
    137                 gboolean new_room = FALSE;
    138135                char *jid = xt_find_attr(c, "jid");
    139136                char *name = xt_find_attr(c, "name");
     
    146143                }
    147144
    148                 gc = bee_chat_by_title(ic->bee, ic, jid);
    149                 if (!gc) {
    150                         gc = imcb_chat_new(ic, jid);
    151                         new_room = TRUE;
    152                 }
    153                 imcb_chat_name_hint(gc, name);
    154                 imcb_chat_topic(gc, NULL, topic, 0);
    155 
    156                 ircc = gc->ui_data;
    157                 set_setstr(&ircc->set, "account", ic->acc->tag);
    158                 set_setstr(&ircc->set, "room", jid);
    159                 set_setstr(&ircc->set, "chat_type", "room");
    160 
    161                 if (new_room) {
    162                         /* This cleans everything but leaves the irc channel around,
    163                          * since it just graduated to a room.*/
    164                         imcb_chat_free(gc);
    165                 }
    166 
     145                imcb_chat_placeholder_new(ic, jid, name, topic);
    167146                c = c->next;
    168147        }
Note: See TracChangeset for help on using the changeset viewer.