Display chat and channel icons, refactor image loading code

This commit is contained in:
mjentsch 2016-02-10 02:03:46 +01:00
parent 1070b5a6e7
commit 581e024254
6 changed files with 52 additions and 128 deletions

View file

@ -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 {

View file

@ -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);
}

View file

@ -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));
}
}
}
}

View file

@ -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);
}

View file

@ -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

View file

@ -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);