From 0446ca2b9b772f5e5a479e3a5d5ef9e0a9284b7d Mon Sep 17 00:00:00 2001 From: Eion Robb Date: Mon, 13 Mar 2017 22:27:01 +1300 Subject: [PATCH] Support typing notifications using the group-typing-notifications plugin See https://github.com/EionRobb/pidgin-groupchat-typing-notifications --- telegram-purple.c | 8 ++++++ tgp-chat.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++ tgp-chat.h | 2 ++ 3 files changed, 82 insertions(+) diff --git a/telegram-purple.c b/telegram-purple.c index 6540818..de45ffe 100644 --- a/telegram-purple.c +++ b/telegram-purple.c @@ -55,6 +55,7 @@ struct tgl_update_callback tgp_callback = { // FIXME: what about user_registred, user_activated, new_authorization, our_id ? .type_in_secret_chat_notification = update_secret_chat_typing, + .type_in_chat_notification = update_chat_typing, .chat_update = update_chat_handler, .channel_update = update_channel_handler, .user_update = update_user_handler, @@ -504,6 +505,8 @@ static void update_on_failed_login (struct tgl_state *TLS) { purple_connection_error (tls_get_conn (TLS), TLS->error); } +static gulong chat_conversation_typing_signal = 0; + static void tgprpl_login (PurpleAccount * acct) { info ("tgprpl_login(): Purple is telling the prpl to connect the account"); @@ -603,6 +606,11 @@ static void tgprpl_login (PurpleAccount * acct) { purple_connection_set_state (conn->gc, PURPLE_CONNECTING); tgl_login (TLS); + + if (!chat_conversation_typing_signal) { + chat_conversation_typing_signal = purple_signal_connect(purple_conversations_get_handle(), "chat-conversation-typing", + purple_connection_get_prpl (gc), PURPLE_CALLBACK(tgprpl_send_chat_typing), NULL); + } } static void tgprpl_close (PurpleConnection *gc) { diff --git a/tgp-chat.c b/tgp-chat.c index 2e4a1c1..c6d42de 100644 --- a/tgp-chat.c +++ b/tgp-chat.c @@ -218,6 +218,78 @@ int tgprpl_send_chat (PurpleConnection *gc, int id, const char *message, PurpleM return tgp_msg_send (gc_get_tls (gc), message, P->id); } +unsigned int tgprpl_send_chat_typing (PurpleConversation *conv, PurpleTypingState typing, gpointer ignored) +{ + PurpleConnection *gc = purple_conversation_get_gc (conv); + tgl_peer_t *P; + PurpleConvChat *chat; + int id; + + if (!PURPLE_CONNECTION_IS_CONNECTED (gc)) + return 0; + + if (g_strcmp0(purple_plugin_get_id (purple_connection_get_prpl (gc)), PLUGIN_ID)) + return 0; + + debug ("tgprpl_send_chat_typing()"); + + chat = purple_conversation_get_chat_data (conv); + id = purple_conv_chat_get_id (chat); + + P = tgl_peer_get (gc_get_tls (gc), TGL_MK_CHAT(id)); + if (! P) { + P = tgl_peer_get (gc_get_tls (gc), TGL_MK_CHANNEL(id)); + } + g_return_val_if_fail(P != NULL, -1); + + tgl_do_send_typing (gc_get_tls (gc), P->id, typing == PURPLE_TYPING ? tgl_typing_typing : tgl_typing_cancel, + 0, 0); + + // when the group receives a typing notification it is obvious that the previous messages were read + pending_reads_send_user (gc_get_tls (gc), P->id); + + return 2; +} + +void update_chat_typing (struct tgl_state *TLS, struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status) { + debug ("update_chat_typing()"); + + PurpleConvChat *chat = NULL; + PurpleConversation *conv = purple_find_chat (tls_get_conn (TLS), tgl_get_peer_id (C->id)); + if (conv) { + chat = purple_conversation_get_chat_data (conv); + } + g_return_if_fail(chat != NULL); + + const char *name = tgp_blist_lookup_purple_name (TLS, U->id); + g_return_if_fail(name != NULL); + + PurpleConvChatBuddyFlags flags = purple_conv_chat_user_get_flags (chat, name); + + if (status == tgl_typing_typing) { + flags |= PURPLE_CBFLAGS_TYPING; + } else { + flags &= ~PURPLE_CBFLAGS_TYPING; + } + + purple_conv_chat_user_set_flags(chat, name, flags); +} + +void tgprpl_kick_from_chat (PurpleConnection *gc, int id, const char *who) { + debug ("tgprpl_kick_from_chat()"); + + tgl_peer_t *P = tgl_peer_get (gc_get_tls (gc), TGL_MK_CHAT(id)); + if (! P) { + P = tgl_peer_get (gc_get_tls (gc), TGL_MK_CHANNEL(id)); + } + g_return_if_fail(P != NULL); + + tgl_peer_t *other_id = tgp_blist_lookup_peer_get (gc_get_tls (gc), who); + g_return_if_fail(P != NULL); + + tgl_do_del_user_from_chat (gc_get_tls (gc), P->id, other_id->id, tgp_notify_on_error_gw, NULL); +} + GList *tgprpl_chat_join_info (PurpleConnection *gc) { struct proto_chat_entry *pce; pce = g_new0 (struct proto_chat_entry, 1); diff --git a/tgp-chat.h b/tgp-chat.h index a7154fa..b56332b 100644 --- a/tgp-chat.h +++ b/tgp-chat.h @@ -46,6 +46,7 @@ PurpleChat *tgp_chat_blist_store (struct tgl_state *TLS, tgl_peer_t *P, const ch PurpleConversation *tgp_chat_show (struct tgl_state *TLS, tgl_peer_t *P); int tgprpl_send_chat (PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags); +unsigned int tgprpl_send_chat_typing (PurpleConversation *conv, PurpleTypingState typing, gpointer ignored); char *tgprpl_get_chat_name (GHashTable *data); void tgprpl_chat_join (PurpleConnection *gc, GHashTable *data); GList *tgprpl_chat_join_info (PurpleConnection *gc); @@ -61,5 +62,6 @@ int tgp_channel_loaded (struct tgl_state *TLS, tgl_peer_id_t id); void update_channel_handler (struct tgl_state *TLS, struct tgl_channel *C, unsigned flags); void update_chat_handler (struct tgl_state *TLS, struct tgl_chat *C, unsigned flags); +void update_chat_typing (struct tgl_state *TLS, struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status); #endif