From 581e024254e199dcc5eb55b97e394a553cacf4f0 Mon Sep 17 00:00:00 2001 From: mjentsch Date: Wed, 10 Feb 2016 02:03:46 +0100 Subject: [PATCH] Display chat and channel icons, refactor image loading code --- telegram-purple.c | 4 +- tgp-blist.c | 3 +- tgp-chat.c | 9 ++- tgp-info.c | 149 +++++++++++++--------------------------------- tgp-info.h | 13 +--- tgp-msg.c | 2 +- 6 files changed, 52 insertions(+), 128 deletions(-) diff --git a/telegram-purple.c b/telegram-purple.c index 1997754..a355c0f 100644 --- a/telegram-purple.c +++ b/telegram-purple.c @@ -78,7 +78,7 @@ static void _update_buddy (struct tgl_state *TLS, tgl_peer_t *user, unsigned fla } if (flags & TGL_UPDATE_PHOTO) { debug ("update photo"); - tgp_info_update_photo (buddy, user); + tgp_info_update_photo (&buddy->node, user); } } } @@ -140,7 +140,7 @@ static void update_user_handler (struct tgl_state *TLS, struct tgl_user *user, u if (buddy) { p2tgl_prpl_got_user_status (TLS, user->id, &user->status); - tgp_info_update_photo (buddy, tgl_peer_get (TLS, user->id)); + tgp_info_update_photo (&buddy->node, tgl_peer_get (TLS, user->id)); } } } else { diff --git a/tgp-blist.c b/tgp-blist.c index 46cfa2c..49379da 100644 --- a/tgp-blist.c +++ b/tgp-blist.c @@ -162,9 +162,8 @@ void tgp_blist_contact_add (struct tgl_state *TLS, struct tgl_user *U) { buddy = tgp_blist_buddy_new (TLS, P); purple_blist_add_buddy (buddy, NULL, tgp_blist_group_init (_("Telegram")), NULL); - tgp_info_update_photo (buddy, P); + tgp_info_update_photo (&buddy->node, P); } - p2tgl_prpl_got_user_status (TLS, U->id, &U->status); } diff --git a/tgp-chat.c b/tgp-chat.c index 0a055b8..a7631c4 100644 --- a/tgp-chat.c +++ b/tgp-chat.c @@ -48,7 +48,7 @@ tgl_peer_id_t tgp_chat_get_id (PurpleChat *C) { return TGL_MK_CHAT(atoi (id)); } -static void tgp_chat_blist_store (struct tgl_state *TLS, tgl_peer_t *P, const char *group) { +void tgp_chat_blist_store (struct tgl_state *TLS, tgl_peer_t *P, const char *group) { g_return_if_fail(tgl_get_peer_type (P->id) == TGL_PEER_CHAT || tgl_get_peer_type (P->id) == TGL_PEER_CHANNEL); PurpleChat *PC = tgp_blist_chat_find (TLS, P->id); @@ -57,15 +57,15 @@ static void tgp_chat_blist_store (struct tgl_state *TLS, tgl_peer_t *P, const ch PC = tgp_chat_new (TLS, tgl_peer_get (TLS, P->id)); if (purple_account_get_bool (tls_get_pa (TLS), TGP_KEY_JOIN_GROUP_CHATS, TGP_DEFAULT_JOIN_GROUP_CHATS)) { purple_blist_add_chat (PC, tgp_blist_group_init (group), NULL); - tgp_info_update_photo (&PC->node, tgl_peer_get (TLS, P->id)); } } + tgp_info_update_photo (&PC->node, tgl_peer_get (TLS, P->id)); } else { if (PC) { purple_blist_remove_chat (PC); } } - + if (PC) { g_hash_table_replace (purple_chat_get_components (PC), g_strdup ("id"), g_strdup_printf ("%d", tgl_get_peer_id (P->id))); @@ -463,6 +463,9 @@ static void update_chat (struct tgl_state *TLS, tgl_peer_t *C, unsigned flags, c if (flags & TGL_UPDATE_DELETED) { // TODO: test if this is actually executed on deletion purple_blist_remove_chat (PC); } + if (flags & TGL_UPDATE_PHOTO) { + tgp_info_update_photo (&PC->node, tgl_peer_get (TLS, C->id)); + } } } } diff --git a/tgp-info.c b/tgp-info.c index 77d94be..acbac47 100644 --- a/tgp-info.c +++ b/tgp-info.c @@ -19,139 +19,70 @@ #include "tgp-info.h" - // load photo -static void tgp_info_load_photo_done (struct tgl_state *TLS, void *extra, int success, - const char *filename) { - struct tgp_info_load_photo_data *data = extra; +static void tgp_info_update_photo_id (PurpleBlistNode *node, long long photo) { + char *llid = g_strdup_printf ("%lld", photo); + debug ("tgp_info_update_photo_id %s", llid); + purple_blist_node_set_string (node, TGP_INFO_PHOTO_ID, llid); + g_free (llid); +} - if (! success) { - data->callback (TLS, data->extra, NULL, 0, 0); +static void tgp_info_load_photo_done (struct tgl_state *TLS, void *extra, int success, const char *filename) { + tgl_peer_t *P = extra; + + g_return_if_fail(success); + + gchar *img = NULL; + size_t len; + GError *err = NULL; + g_file_get_contents (filename, &img, &len, &err); + if (err) { + failure ("getting file contents for %s failed: %s", filename, err->message); + return; + } + + if (tgl_get_peer_type (P->id) == TGL_PEER_USER || tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT) { + PurpleBuddy *B = tgp_blist_buddy_find (TLS, P->id); + g_return_if_fail(B); + + purple_buddy_icons_set_for_user (tls_get_pa (TLS), purple_buddy_get_name (B), + (guchar*) img, len, NULL); + tgp_info_update_photo_id (&B->node, P->user.photo_big.local_id); } else { - gchar *img = NULL; - size_t len; - GError *err = NULL; - g_file_get_contents (filename, &img, &len, &err); - - if (err) { - failure ("getting file contents for %s failed: %s", filename, err->message); - data->callback (TLS, data->extra, NULL, 0, FALSE); - return; - } - data->callback (TLS, data->extra, img, len, success); - } - free (data); -} - -static void tgp_info_update_photo_chat_done (struct tgl_state *TLS, void *extra, int success, struct tgl_chat *C) { - g_return_if_fail(success); - g_return_if_fail(C->photo); - tgl_do_load_photo (TLS, C->photo, tgp_info_load_photo_done, extra); -} - -static void tgp_info_update_photo_user_done (struct tgl_state *TLS, void *extra, int success, struct tgl_user *U) { - g_return_if_fail(success); - g_return_if_fail(U->photo); - tgl_do_load_photo (TLS, U->photo, tgp_info_load_photo_done, extra); -} - -static void tgp_info_update_photo_channel_done (struct tgl_state *TLS, void *extra, int success, struct tgl_channel *CH) { - g_return_if_fail(success); - g_return_if_fail(CH->photo); - tgl_do_load_photo (TLS, CH->photo, tgp_info_load_photo_done, extra); -} - -void tgp_info_load_photo_peer (struct tgl_state *TLS, tgl_peer_t *P, void *extra, - void (*callback) (struct tgl_state *TLS, void *extra, gchar *img, size_t len, int success)) { - assert(callback); - - struct tgp_info_load_photo_data *D = talloc0 (sizeof(struct tgp_info_load_photo_data)); - D->callback = callback; - D->extra = extra; - D->TLS = TLS; - - switch (tgl_get_peer_type (P->id)) { - case TGL_PEER_CHANNEL: - tgl_do_get_channel_info (TLS, P->id, FALSE, tgp_info_update_photo_channel_done, D); - break; - - case TGL_PEER_USER: - tgl_do_get_user_info (TLS, P->id, FALSE, tgp_info_update_photo_user_done, D); - break; - - case TGL_PEER_CHAT: - tgl_do_get_chat_info (TLS, P->id, FALSE, tgp_info_update_photo_chat_done, D); - break; - - case TGL_PEER_ENCR_CHAT: { - tgl_peer_t *parent = tgp_encr_chat_get_partner (TLS, &P->encr_chat); - g_return_if_fail(parent); - tgl_do_get_user_info (TLS, parent->id, FALSE, tgp_info_update_photo_user_done, D); - break; - } - - default: - g_warn_if_reached(); - break; + PurpleChat *C = tgp_blist_chat_find (TLS, P->id); + g_return_if_fail(C); + + purple_buddy_icons_node_set_custom_icon (&C->node, (guchar*) img, len); + tgp_info_update_photo_id (&C->node, P->user.photo_big.local_id); } } - // update photo -static void tgp_info_update_photo_done (struct tgl_state *TLS, void *extra, gchar *img, size_t len, int success) { - PurpleBuddy *node = extra; - g_return_if_fail(success); - purple_buddy_icons_set_for_user (tls_get_pa (TLS), purple_buddy_get_name (node), img, len, NULL); -} - -void tgp_info_update_photo (PurpleBuddy *buddy, tgl_peer_t *P) { - PurpleBlistNode *node = &buddy->node; +void tgp_info_update_photo (PurpleBlistNode *node, tgl_peer_t *P) { tgl_peer_t *parent = NULL; - long long photo = 0; - switch (tgl_get_peer_type (P->id)) { - case TGL_PEER_USER: - photo = P->user.photo_id; - break; - - case TGL_PEER_CHANNEL: - photo = P->channel.photo_id; - break; - - case TGL_PEER_ENCR_CHAT: { - parent = tgp_encr_chat_get_partner (pbn_get_data (node)->TLS, &P->encr_chat); - photo = parent->photo_id; - break; - } - - default: - return; - } + // FIXME: test if this works for encrypted chats + long long photo = P->user.photo_big.local_id; const char *old = purple_blist_node_get_string (node, TGP_INFO_PHOTO_ID); if (old) { long long id = 0; id = atoll (old); if (id == photo) { - debug ("photo id for %s hasn't changed %lld", buddy->name, id); + debug ("photo id for %s hasn't changed %lld", parent ? parent->print_name : P->print_name, id); return; } } if (photo != 0) { - tgp_info_load_photo_peer (pbn_get_data (node)->TLS, parent ? parent : P, node, tgp_info_update_photo_done); + tgl_do_load_file_location (pbn_get_data (node)->TLS, &P->user.photo_big, tgp_info_load_photo_done, P); } else { - purple_buddy_icons_set_for_user (purple_buddy_get_account (buddy), purple_buddy_get_name (buddy), NULL, - 0, NULL); + // set empty photo + purple_buddy_icons_node_set_custom_icon_from_file (node, NULL); + tgp_info_update_photo_id (node, photo); } - - // FIXME: call this in tgp_info_update_photo_done, right now just hope for the best - char *llid = g_strdup_printf ("%lld", photo); - debug ("tgl_info_update_photo %s", llid); - purple_blist_node_set_string (node, TGP_INFO_PHOTO_ID, llid); - g_free (llid); } diff --git a/tgp-info.h b/tgp-info.h index 0abfd2c..46c00df 100644 --- a/tgp-info.h +++ b/tgp-info.h @@ -22,16 +22,7 @@ #include "telegram-purple.h" -#define TGP_INFO_PHOTO_ID "tgp-photo-id" - -struct tgp_info_load_photo_data { - struct tgl_state *TLS; - void (* callback) (struct tgl_state *TLS, void *extra, gchar *img, size_t len, int success); - void *extra; -}; - -void tgp_info_load_photo_peer (struct tgl_state *TLS, tgl_peer_t *P, void *extra, - void (*callback) (struct tgl_state *TLS, void *extra, gchar *img, size_t len, int success)); -void tgp_info_update_photo (PurpleBuddy *buddy, tgl_peer_t *P); +#define TGP_INFO_PHOTO_ID "tgp_photo_id" +void tgp_info_update_photo (PurpleBlistNode *node, tgl_peer_t *P); void tgprpl_info_show (PurpleConnection *gc, const char *who); #endif diff --git a/tgp-msg.c b/tgp-msg.c index 8a4f491..8b454c7 100644 --- a/tgp-msg.c +++ b/tgp-msg.c @@ -164,7 +164,7 @@ static char *format_service_msg (struct tgl_state *TLS, struct tgl_message *M) { // Add the new channel to the buddy list PurpleBuddy *buddy = tgp_blist_buddy_new (TLS, fromPeer); purple_blist_add_buddy (buddy, NULL, tgp_blist_group_init (_("Telegram Channels")), NULL); - tgp_info_update_photo (buddy, fromPeer); + // tgp_info_update_photo (buddy, fromPeer); purple_prpl_got_user_status (tls_get_pa (TLS), tgp_blist_lookup_purple_name (TLS, fromPeer->id), "available", NULL);