From b12ea9fb05e636213b35d46ddaec3e255e1a6992 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Wed, 29 Jul 2020 22:32:24 +0200 Subject: weechat: Protocol version 2, display replies --- weechat/tomsg.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 122 insertions(+), 11 deletions(-) (limited to 'weechat/tomsg.c') diff --git a/weechat/tomsg.c b/weechat/tomsg.c index 04213ae..e008104 100644 --- a/weechat/tomsg.c +++ b/weechat/tomsg.c @@ -21,6 +21,8 @@ WEECHAT_PLUGIN_PRIORITY(1000) static const char *errpfx,*netpfx; +#define PROTOCOL_VERSION 2 + #define NICK_COLOR "default" #define NICK_AWAY_COLOR "weechat.color.nicklist_away" @@ -56,6 +58,86 @@ static struct t_weechat_plugin *weechat_plugin; static struct t_hashtable *conntable; +static void display_message( + struct roomdata *room, + int64_t timestamp, + const char *username, + const char *message, + int64_t msgid, + bool is_reply +) { + char tags[128]; + int pos = snprintf(tags, sizeof tags, "tomsgid_%" PRIi64, msgid); + strcpy(tags + pos, room->nmembers <= 2 ? ",notify_private" : ",notify_message"); + if (is_reply) { + strcat(tags, ",tomsg_reply"); + } + + weechat_printf_date_tags( + room->buffer, timestamp / 1000000LL, + tags, + "%s\t%s", username, message + ); +} + +static void edit_reply_message( + struct roomdata *room, + int64_t msgid, + const char *new_message +) { + struct t_hdata *buffer_h = weechat_hdata_get("buffer"); + struct t_hdata *lines_h = weechat_hdata_get("lines"); + struct t_hdata *line_h = weechat_hdata_get("line"); + struct t_hdata *line_data_h = weechat_hdata_get("line_data"); + + struct t_gui_lines *lines_ptr = weechat_hdata_pointer(buffer_h, room->buffer, "lines"); + if (!lines_ptr) { + debugf("ERROR: Cannot get lines_ptr!"); + return; + } + + struct t_gui_line *line_ptr = weechat_hdata_pointer(lines_h, lines_ptr, "last_line"); + struct t_gui_line_data *line_data_ptr; + + while (line_ptr) { + line_data_ptr = weechat_hdata_pointer(line_h, line_ptr, "data"); + + const int tags_count = weechat_hdata_integer(line_data_h, line_data_ptr, "tags_count"); + bool have_reply_tag = false; + bool have_msgid_tag = false; + for (int i = 0; i < tags_count; i++) { + char key[32]; + snprintf(key, sizeof key, "%d|tags_array", i); + const char *tag = weechat_hdata_string(line_data_h, line_data_ptr, key); + if (strcmp(tag, "tomsg_reply") == 0) { + have_reply_tag = true; + } else if (memcmp(tag, "tomsgid_", 8) == 0) { + int64_t this_id = strtoll(tag + 8, NULL, 10); + if (this_id == msgid) have_msgid_tag = true; + } + } + + if (have_reply_tag && have_msgid_tag) break; + + line_ptr = weechat_hdata_pointer(line_h, line_ptr, "prev_line"); + } + + if (line_ptr) { + debugf("edit_reply_message: found line\n"); + struct t_hashtable *hashtable = + weechat_hashtable_new( + 8, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, NULL, NULL); + if (hashtable) { + weechat_hashtable_set(hashtable, "message", new_message); + weechat_hdata_update(line_data_h, line_data_ptr, hashtable); + weechat_hashtable_free(hashtable); + } + } else { + debugf("edit_reply_message: not found!\n"); + } +} + + static void room_update_attributes(struct roomdata *room){ bool private=room->nmembers<=2; weechat_buffer_set(room->buffer,"localvar_set_type",private?"private":"channel"); @@ -194,6 +276,28 @@ static void members_net_callback(int fd,struct net_response res,void *payload){ room_update_attributes(room); } +struct room_and_msgid { + struct roomdata *room; + int64_t msgid; +}; + +static void reply_get_message_net_callback(int fd, struct net_response res, void *payload) { + (void)fd; + struct room_and_msgid *data = (struct room_and_msgid*)payload; + + debugf("Got reply from get_message for msgid=%" PRIi64 "\n", res.msgid); + + const char *green = weechat_color("green"); + + size_t prefixlen = strlen(green) + 3 + strlen(res.username) + 2; + char *buffer = malloc(prefixlen + strlen(res.message) + 1); + sprintf(buffer, "%s> <%s> %s", weechat_color("green"), res.username, res.message); + edit_reply_message(data->room, data->msgid, buffer); + free(buffer); + + free(data); +} + static void push_net_callback(int fd,struct net_response res,void *payload){ (void)payload; debugf("push_net_callback(fd=%d,res={.type=%d})\n",fd,res.type); @@ -215,15 +319,22 @@ static void push_net_callback(int fd,struct net_response res,void *payload){ create_room_buffer(room); } - if(res.type==NET_MESSAGE){ - bool private=room->nmembers<=2; - weechat_printf_date_tags( - room->buffer,res.timestamp/1000000LL,private?"notify_private":"notify_message", - "%s\t%s",res.username,res.message); - } else if(res.type==NET_HISTORY){ - weechat_printf_date_tags( - room->buffer,res.timestamp/1000000LL,NULL, - "%s\t%s",res.username,res.message); + if(res.type==NET_MESSAGE||res.type==NET_HISTORY){ + if(res.replyid!=-1){ + debugf("Found reply msgid=%" PRIi64 " replyid=%" PRIi64 "\n",res.msgid,res.replyid); + char str[128]; + snprintf(str,sizeof str,"%s> ...",weechat_color("green")); + display_message(room,res.timestamp,res.username,str,res.msgid,true); + display_message(room,res.timestamp,"",res.message,res.msgid,false); + + struct room_and_msgid *payload=malloc(sizeof(struct room_and_msgid)); + assert(payload); + payload->room=room; + payload->msgid=res.msgid; + net_sendf(fd,reply_get_message_net_callback,payload,"get_message %" PRIi64,res.replyid); + } else { + display_message(room,res.timestamp,res.username,res.message,res.msgid,false); + } } else if(res.type==NET_JOIN){ weechat_printf(room->buffer,"%sUser %s joined this room",netpfx,res.username); if(room->buffer_nickgroup){ @@ -477,7 +588,7 @@ static void version_net_callback(int fd,struct net_response res,void *payload){ weechat_printf(conn->buffer,"Version negotiation complete."); } else { conn_destroy(conn); - weechat_printf(NULL,"tomsg: Server has incompatible protocol version (we want 1)!"); + weechat_printf(NULL,"tomsg: Server has incompatible protocol version (we want %d)!",PROTOCOL_VERSION); } } @@ -506,7 +617,7 @@ static int connect_cb(const void *_p,void *hostname,int status,int _g,int fd,con weechat_hashtable_set(conntable,&fd,conn); - net_sendf(fd,version_net_callback,NULL,"version 1"); + net_sendf(fd,version_net_callback,NULL,"version %d", PROTOCOL_VERSION); return WEECHAT_RC_OK; } -- cgit v1.2.3-54-g00ecf