Mark messages as read

Send a mark_read command for each received message as soon as the user is available.
This commit is contained in:
mjentsch 2014-12-24 02:44:10 +01:00
parent 91b8cb5bb1
commit 4fa2b91eaa
6 changed files with 99 additions and 8 deletions

View file

@ -450,3 +450,46 @@ void chat_add_all_users (PurpleConversation *pc, struct tgl_chat *chat) {
p2tgl_conv_add_user(pc, *uid, NULL, flags, 0);
}
}
static void pending_reads_cb (struct tgl_state *TLS, void *extra, int success)
{
debug ("ack state: %d", success);
}
static gint pending_reads_compare (gconstpointer a, gconstpointer b)
{
return !memcmp ((tgl_peer_id_t *)a, (tgl_peer_id_t *)b, sizeof(tgl_peer_id_t));
}
void pending_reads_send_all (GQueue *queue, struct tgl_state *TLS)
{
debug ("send all pending ack");
tgl_peer_id_t *pending;
while ((pending = (tgl_peer_id_t*) g_queue_pop_head(queue))) {
tgl_do_mark_read (TLS, *pending, pending_reads_cb, queue);
debug ("tgl_do_mark_read (%d)", pending->id);
free (pending);
}
}
void pending_reads_add (GQueue *queue, tgl_peer_id_t id)
{
tgl_peer_id_t *copy = malloc (sizeof(tgl_peer_id_t));
*copy = id;
if (! g_queue_find_custom (queue, copy, pending_reads_compare)) {
g_queue_push_tail (queue, copy);
}
}
void pending_reads_clear (GQueue *queue)
{
tgl_peer_id_t *pending;
while ((pending = (tgl_peer_id_t*) g_queue_pop_head(queue))) {
free (pending);
}
}

View file

@ -19,6 +19,9 @@
*/
#ifndef __TELEGRAM_BASE_H__
#define __TELEGRAM_BASE_H__
#include "telegram-purple.h"
void read_state_file (struct tgl_state *TLS);
void read_auth_file (struct tgl_state *TLS);
void write_auth_file (struct tgl_state *TLS);
@ -29,4 +32,9 @@ PurpleConversation *chat_show (PurpleConnection *gc, int id);
int chat_add_message (struct tgl_state *TLS, struct tgl_message *M, char *text);
void chat_add_all_users (PurpleConversation *pc, struct tgl_chat *chat);
void request_code_entered (gpointer data, const gchar *code);
void pending_reads_send_all (GQueue *queue, struct tgl_state *TLS);
void pending_reads_add (GQueue *queue, tgl_peer_id_t id);
void pending_reads_clear (GQueue *queue);
#endif

View file

@ -331,6 +331,12 @@ static void update_message_received (struct tgl_state *TLS, struct tgl_message *
p2tgl_got_im (TLS, M->to_id, text, PURPLE_MESSAGE_SEND, M->date);
} else {
p2tgl_got_im (TLS, M->from_id, text, PURPLE_MESSAGE_RECV, M->date);
pending_reads_add (conn->pending_reads, M->from_id);
PurpleStatus *status = purple_account_get_active_status(conn->pa);
if (p2tgl_status_is_present(status)) {
pending_reads_send_all (conn->pending_reads, conn->TLS);
}
}
}
break;
@ -552,16 +558,25 @@ static GList *tgprpl_status_types (PurpleAccount * acct) {
debug ("tgprpl_status_types()\n");
GList *types = NULL;
PurpleStatusType *type;
type = purple_status_type_new_with_attrs (PURPLE_STATUS_AVAILABLE, NULL, NULL,
1, 1, 0, "last online", "last online", purple_value_new (PURPLE_TYPE_STRING), NULL);
type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, NULL, NULL, FALSE, TRUE, FALSE);
types = g_list_prepend (types, type);
type = purple_status_type_new_with_attrs (PURPLE_STATUS_MOBILE, NULL, NULL, 1,
1, 0, "last online", "last online", purple_value_new (PURPLE_TYPE_STRING), NULL);
type = purple_status_type_new_full(PURPLE_STATUS_MOBILE, NULL, NULL, FALSE, TRUE, FALSE);
types = g_list_prepend (types, type);
type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, NULL, NULL, FALSE, TRUE, FALSE);
types = g_list_prepend (types, type);
type = purple_status_type_new (PURPLE_STATUS_OFFLINE, NULL, NULL, 1);
types = g_list_append (types, type);
/*
The states below are only registered internally so that we get notified about
state changes to away and unavailable. This is useful for deciding when to send
No other peer should ever have those states.
*/
type = purple_status_type_new_full(PURPLE_STATUS_AWAY, NULL, NULL, FALSE, TRUE, FALSE);
types = g_list_prepend (types, type);
type = purple_status_type_new_full(PURPLE_STATUS_UNAVAILABLE, NULL, NULL, FALSE, TRUE, FALSE);
types = g_list_prepend (types, type);
return g_list_reverse (types);
}
@ -609,7 +624,8 @@ static void tgprpl_login (PurpleAccount * acct) {
conn->gc = gc;
conn->pa = acct;
conn->new_messages = g_queue_new ();
conn->joining_chats = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
conn->pending_reads = g_queue_new ();
conn->joining_chats = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
purple_connection_set_protocol_data (gc, conn);
tgl_set_ev_base (TLS, conn);
@ -628,7 +644,14 @@ static void tgprpl_close (PurpleConnection * gc) {
debug ("tgprpl_close()\n");
telegram_conn *conn = purple_connection_get_protocol_data(gc);
purple_timeout_remove(conn->timer);
pending_reads_clear (conn->pending_reads);
tgl_free_all (conn->TLS);
g_queue_free (conn->new_messages);
g_queue_free (conn->pending_reads);
g_hash_table_destroy (conn->joining_chats);
}
static int tgprpl_send_im (PurpleConnection * gc, const char *who, const char *message, PurpleMessageFlags flags) {
@ -685,7 +708,16 @@ static void tgprpl_get_info (PurpleConnection * gc, const char *username) {
}
static void tgprpl_set_status (PurpleAccount * acct, PurpleStatus * status) {
debug ("tgprpl_set_status()\n");
debug ("tgprpl_set_status(%s)\n", purple_status_get_name (status));
debug ("tgprpl_set_status(currstatus=%s)\n", purple_status_get_name(purple_account_get_active_status(acct)));
PurpleConnection *gc = purple_account_get_connection(acct);
if (!gc) { return; }
telegram_conn *conn = purple_connection_get_protocol_data (gc);
if (p2tgl_status_is_present(status)) {
pending_reads_send_all (conn->pending_reads, conn->TLS);
}
}
static void tgprpl_add_buddy (PurpleConnection * gc, PurpleBuddy * buddy, PurpleGroup * group) {

View file

@ -45,6 +45,7 @@ typedef struct {
PurpleConnection *gc;
int updated;
GQueue *new_messages;
GQueue *pending_reads;
GHashTable *joining_chats;
guint timer;
int in_fallback_chat;

View file

@ -85,6 +85,12 @@ char *p2tgl_strdup_alias(tgl_peer_t *user) {
return g_alias;
}
int p2tgl_status_is_present (PurpleStatus *status)
{
const char *name = purple_status_get_id (status);
return !(strcmp (name, "unavailable") == 0 || strcmp (name, "away") == 0);
}
static PurpleChat *blist_find_chat_by_hasht_cond(PurpleConnection *gc,
int (*fn)(GHashTable *hasht, void *data), void *data) {
PurpleAccount *account = purple_connection_get_account(gc);

View file

@ -36,6 +36,7 @@ tgl_peer_t *p2tgl_get_peer (tgl_peer_id_t peer);
tgl_peer_t *p2tgl_get_peer_by_id (int id);
char *p2tgl_strdup_alias(tgl_peer_t *user);
int p2tgl_status_is_present (PurpleStatus *status);
PurpleConversation *p2tgl_got_joined_chat (struct tgl_state *TLS, struct tgl_chat *chat);
void p2tgl_got_chat_invite (PurpleConnection *gc, tgl_peer_t *chat, tgl_peer_id_t inviter, const char *message);