Added user status support

This commit is contained in:
vvaltman 2014-11-11 21:10:03 +03:00
parent 9d57c85f20
commit ba4e76ed96
8 changed files with 110 additions and 12 deletions

View File

@ -2006,6 +2006,25 @@ void callback_extf (struct tgl_state *TLS, void *extra, int success, char *buf)
mprint_end (ev);
}
void user_status_upd (struct tgl_state *TLS, struct tgl_user *U) {
if (disable_output && !notify_ev) { return; }
if (!binlog_read) { return; }
if (log_level < 2) { return; }
struct in_ev *ev = notify_ev;
mprint_start (ev);
mpush_color (ev, COLOR_YELLOW);
mprintf (ev, "User ");
print_user_name (ev, U->id, (void *)U);
if (U->status.online > 0) {
mprintf (ev, " online");
} else {
mprintf (ev, " offline");
}
mprintf (ev, "\n");
mpop_color (ev);
mprint_end (ev);
}
struct tgl_update_callback upd_cb = {
.new_msg = print_message_gw,
.marked_read = mark_read_upd,
@ -2021,7 +2040,8 @@ struct tgl_update_callback upd_cb = {
.chat_update = chat_update_gw,
.secret_chat_update = secret_chat_update_gw,
.msg_receive = print_message_gw,
.our_id = our_id_gw
.our_id = our_id_gw,
.user_status_update = user_status_upd
};

View File

@ -1106,8 +1106,7 @@ void tgl_do_mark_read (struct tgl_state *TLS, tgl_peer_id_t id, void (*callback)
if (P->last) {
tgl_do_messages_mark_read_encr (TLS, id, P->encr_chat.access_hash, P->last->date, callback, callback_extra);
} else {
tgl_do_messages_mark_read_encr (TLS, id, P->encr_chat.access_hash, time (0) - 10, callback, callback_extra);
tgl_do_messages_mark_read_encr (TLS, id, P->encr_chat.access_hash, 0, callback, callback_extra);
}
}
/* }}} */

View File

@ -135,19 +135,40 @@ int tglf_fetch_file_location (struct tgl_state *TLS, struct tgl_file_location *l
return 0;
}
int tglf_fetch_user_status (struct tgl_state *TLS, struct tgl_user_status *S) {
int tglf_fetch_user_status (struct tgl_state *TLS, struct tgl_user_status *S, struct tgl_user *U) {
unsigned x = fetch_int ();
assert (x == CODE_user_status_empty || x == CODE_user_status_online || x == CODE_user_status_offline);
switch (x) {
case CODE_user_status_empty:
if (S->online) {
tgl_insert_status_update (TLS, U);
tgl_remove_status_expire (TLS, U);
}
S->online = 0;
S->when = 0;
break;
case CODE_user_status_online:
S->online = 1;
S->when = fetch_int ();
{
int when = fetch_int ();
if (S->online != 1) {
tgl_insert_status_update (TLS, U);
tgl_insert_status_expire (TLS, U);
S->online = 1;
} else {
if (when != S->when) {
tgl_remove_status_expire (TLS, U);
tgl_insert_status_expire (TLS, U);
}
}
}
break;
case CODE_user_status_offline:
if (S->online != -1) {
tgl_insert_status_update (TLS, U);
if (S->online == 1) {
tgl_remove_status_expire (TLS, U);
}
}
S->online = -1;
S->when = fetch_int ();
break;
@ -221,7 +242,7 @@ int tglf_fetch_user (struct tgl_state *TLS, struct tgl_user *U) {
bl_do_user_add (TLS, tgl_get_peer_id (U->id), s1, l1, s2, l2, access_hash, phone, phone_len, x == CODE_user_contact);
bl_do_user_set_username (TLS, U, s3, l3);
assert (tglf_fetch_user_photo (TLS, U) >= 0);
assert (tglf_fetch_user_status (TLS, &U->status) >= 0);
assert (tglf_fetch_user_status (TLS, &U->status, U) >= 0);
if (x == CODE_user_self) {
fetch_bool ();
@ -253,7 +274,7 @@ int tglf_fetch_user (struct tgl_state *TLS, struct tgl_user *U) {
}
assert (tglf_fetch_user_photo (TLS, U) >= 0);
tglf_fetch_user_status (TLS, &U->status);
tglf_fetch_user_status (TLS, &U->status, U);
if (x == CODE_user_self) {
fetch_bool ();
}

View File

@ -22,7 +22,7 @@
#include "tgl.h"
int tglf_fetch_file_location (struct tgl_state *TLS, struct tgl_file_location *loc);
int tglf_fetch_user_status (struct tgl_state *TLS, struct tgl_user_status *S);
int tglf_fetch_user_status (struct tgl_state *TLS, struct tgl_user_status *S, struct tgl_user *U);
int tglf_fetch_user (struct tgl_state *TLS, struct tgl_user *U);
struct tgl_user *tglf_fetch_alloc_user (struct tgl_state *TLS);
struct tgl_user *tglf_fetch_alloc_user_full (struct tgl_state *TLS);

View File

@ -234,6 +234,7 @@ struct tgl_encr_file {
struct tgl_user_status {
int online;
int when;
struct tgl_timer *ev;
};
struct tgl_user {

5
tgl.h
View File

@ -93,6 +93,7 @@ struct tgl_update_callback {
void (*msg_receive)(struct tgl_state *TLS, struct tgl_message *M);
void (*our_id)(struct tgl_state *TLS, int id);
void (*notification)(struct tgl_state *TLS, char *type, char *message);
void (*user_status_update)(struct tgl_state *TLS, struct tgl_user *U);
char *(*create_print_name) (struct tgl_state *TLS, tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
};
@ -204,6 +205,10 @@ struct tgl_state {
struct tree_query *queries_tree;
char *base_path;
struct tree_user *online_updates;
struct tgl_timer *online_updates_timer;
};
#pragma pack(pop)
//extern struct tgl_state tgl_state;

View File

@ -23,6 +23,7 @@
#include "binlog.h"
#include "auto.h"
#include "structures.h"
#include "tree.h"
#include <assert.h>
@ -130,14 +131,13 @@ void tglu_work_update (struct tgl_state *TLS, struct connection *c, long long ms
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *U = tgl_peer_get (TLS, user_id);
if (U) {
tglf_fetch_user_status (TLS, &U->user.status);
tglf_fetch_user_status (TLS, &U->user.status, &U->user);
if (TLS->callback.status_notification) {
TLS->callback.status_notification (TLS, (void *)U);
}
} else {
struct tgl_user_status t;
tglf_fetch_user_status (TLS, &t);
assert (skip_type_any (TYPE_TO_PARAM (user_status)) >= 0);
}
}
break;
@ -544,3 +544,51 @@ void tglu_work_updates_to_long (struct tgl_state *TLS, struct connection *c, lon
vlogprintf (E_NOTICE, "updates too long... Getting difference\n");
tgl_do_get_difference (TLS, 0, 0, 0);
}
#define user_cmp(a,b) (tgl_get_peer_id ((a)->id) - tgl_get_peer_id ((b)->id))
DEFINE_TREE(user, struct tgl_user *,user_cmp,0)
static void notify_status (struct tgl_user *U, void *ex) {
struct tgl_state *TLS = ex;
if (TLS->callback.user_status_update) {
TLS->callback.user_status_update (TLS, U);
}
}
static void status_notify (struct tgl_state *TLS, void *arg) {
tree_act_ex_user (TLS->online_updates, notify_status, TLS);
tree_clear_user (TLS->online_updates);
TLS->online_updates = NULL;
TLS->timer_methods->free (TLS->online_updates_timer);
TLS->online_updates_timer = NULL;
}
void tgl_insert_status_update (struct tgl_state *TLS, struct tgl_user *U) {
if (!tree_lookup_user (TLS->online_updates, U)) {
TLS->online_updates = tree_insert_user (TLS->online_updates, U, lrand48 ());
}
if (!TLS->online_updates_timer) {
TLS->online_updates_timer = TLS->timer_methods->alloc (TLS, status_notify, 0);
TLS->timer_methods->insert (TLS->online_updates_timer, 0);
}
}
static void user_expire (struct tgl_state *TLS, void *arg) {
struct tgl_user *U = arg;
TLS->timer_methods->free (U->status.ev);
U->status.ev = 0;
U->status.online = -1;
U->status.when = tglt_get_double_time ();
tgl_insert_status_update (TLS, U);
}
void tgl_insert_status_expire (struct tgl_state *TLS, struct tgl_user *U) {
assert (!U->status.ev);
U->status.ev = TLS->timer_methods->alloc (TLS, user_expire, U);
TLS->timer_methods->insert (U->status.ev, U->status.when - tglt_get_double_time ());
}
void tgl_remove_status_expire (struct tgl_state *TLS, struct tgl_user *U) {
TLS->timer_methods->free (U->status.ev);
U->status.ev = 0;
}

View File

@ -32,4 +32,8 @@ void tglu_fetch_pts (struct tgl_state *TLS);
void tglu_fetch_qts (struct tgl_state *TLS);
void tglu_fetch_seq (struct tgl_state *TLS);
void tglu_fetch_date (struct tgl_state *TLS);
void tgl_insert_status_update (struct tgl_state *TLS, struct tgl_user *U);
void tgl_insert_status_expire (struct tgl_state *TLS, struct tgl_user *U);
void tgl_remove_status_expire (struct tgl_state *TLS, struct tgl_user *U);
#endif