From 6f1f64c892d9b11c4c970f2966ca627e56f7cf36 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 10 Mar 2018 17:10:23 +0300 Subject: [PATCH] Better local online status update. GitOrigin-RevId: 941945d3e0b366e4fcd1ed7712f388422968cd28 --- td/telegram/ContactsManager.cpp | 52 ++++++++++++++++++++++++--------- td/telegram/ContactsManager.h | 5 ++-- td/telegram/Td.cpp | 15 +++++++++- td/telegram/Td.h | 1 + 4 files changed, 56 insertions(+), 17 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 870e21d0..3e873094 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -2376,8 +2376,9 @@ void ContactsManager::on_user_online_timeout_callback(void *contacts_manager_ptr CHECK(u != nullptr); LOG(INFO) << "Update " << user_id << " online status to offline"; - send_closure_later(G()->td(), &Td::send_update, - make_tl_object(user_id.get(), get_user_status_object(u))); + send_closure_later( + G()->td(), &Td::send_update, + make_tl_object(user_id.get(), contacts_manager->get_user_status_object(user_id, u))); } void ContactsManager::on_channel_unban_timeout_callback(void *contacts_manager_ptr, int64 channel_id_long) { @@ -3069,7 +3070,7 @@ void ContactsManager::set_my_id(UserId my_id) { } } -void ContactsManager::set_my_online_status(bool is_online, bool send_update) { +void ContactsManager::set_my_online_status(bool is_online, bool send_update, bool is_local) { auto my_id = get_my_id("set_my_online_status"); User *u = get_user_force(my_id); if (u != nullptr) { @@ -3081,11 +3082,22 @@ void ContactsManager::set_my_online_status(bool is_online, bool send_update) { new_online = now - 1; } - if (new_online != u->was_online) { - LOG(INFO) << "Update my online from " << u->was_online << " to " << new_online; - u->was_online = new_online; - - u->is_status_changed = true; + if (is_local) { + LOG(INFO) << "Update my local online from " << my_was_online_local_ << " to " << new_online; + if (!is_online) { + new_online = min(new_online, u->was_online); + } + if (new_online != my_was_online_local_) { + my_was_online_local_ = new_online; + u->is_status_changed = true; + } + } else { + if (my_was_online_local_ != 0 || new_online != u->was_online) { + LOG(INFO) << "Update my online from " << u->was_online << " to " << new_online; + my_was_online_local_ = 0; + u->was_online = new_online; + u->is_status_changed = true; + } } if (send_update) { @@ -6011,7 +6023,7 @@ void ContactsManager::update_user(User *u, UserId user_id, bool from_binlog, boo u->is_status_saved = false; } send_closure(G()->td(), &Td::send_update, - make_tl_object(user_id.get(), get_user_status_object(u))); + make_tl_object(user_id.get(), get_user_status_object(user_id, u))); u->is_status_changed = false; } @@ -6641,8 +6653,11 @@ void ContactsManager::on_update_user_online(User *u, UserId user_id, tl_object_p u->was_online = new_online; u->is_status_changed = true; - if (is_offline && user_id == get_my_id("on_update_user_online")) { - td_->on_online_updated(false, false); + if (user_id == get_my_id("on_update_user_online")) { + my_was_online_local_ = 0; + if (is_offline) { + td_->on_online_updated(false, false); + } } } } @@ -8632,13 +8647,18 @@ std::pair> ContactsManager::search_among_users(const vecto const string &query, int32 limit) { Hints hints; // TODO cache Hints + UserId my_user_id = get_my_id("search_among_users"); for (auto user_id : user_ids) { auto u = get_user(user_id); if (u == nullptr) { continue; } hints.add(user_id.get(), u->first_name + " " + u->last_name + " " + u->username); - hints.set_rating(user_id.get(), -u->was_online); + auto was_online = u->was_online; + if (user_id == my_user_id && my_was_online_local_ != 0) { + was_online = my_was_online_local_; + } + hints.set_rating(user_id.get(), -was_online); } auto result = hints.search(query, limit, true); @@ -9289,11 +9309,15 @@ void ContactsManager::on_upload_profile_photo_error(FileId file_id, Status statu promise.set_error(std::move(status)); // TODO check that status has valid error code } -tl_object_ptr ContactsManager::get_user_status_object(const User *u) { +tl_object_ptr ContactsManager::get_user_status_object(UserId user_id, const User *u) const { if (u->is_bot) { return make_tl_object(std::numeric_limits::max()); } + int32 was_online = u->was_online; + if (user_id == get_my_id("get_user_status_object") && my_was_online_local_ != 0) { + was_online = my_was_online_local_; + } switch (was_online) { case -3: return make_tl_object(); @@ -9347,7 +9371,7 @@ tl_object_ptr ContactsManager::get_user_object(UserId user_id, con } return make_tl_object( - user_id.get(), u->first_name, u->last_name, u->username, u->phone_number, get_user_status_object(u), + user_id.get(), u->first_name, u->last_name, u->username, u->phone_number, get_user_status_object(user_id, u), get_profile_photo_object(td_->file_manager_.get(), &u->photo), get_link_state_object(u->outbound), get_link_state_object(u->inbound), u->is_verified, u->restriction_reason, u->is_received, std::move(type), u->language_code); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 3e87b5e2..fc1bfc34 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -210,7 +210,7 @@ class ContactsManager : public Actor { void on_get_channel_full_fail(ChannelId channel_id, Status &&error); UserId get_my_id(const char *source) const; - void set_my_online_status(bool is_online, bool send_update); + void set_my_online_status(bool is_online, bool send_update, bool is_local); void on_update_online_status_privacy(); @@ -955,7 +955,7 @@ class ContactsManager : public Actor { void reload_dialog_administrators(DialogId dialog_id, int32 hash, Promise &&promise); - static tl_object_ptr get_user_status_object(const User *u); + tl_object_ptr get_user_status_object(UserId user_id, const User *u) const; static tl_object_ptr get_link_state_object(LinkState link); @@ -1004,6 +1004,7 @@ class ContactsManager : public Actor { ActorShared<> parent_; UserId my_id_; UserId support_user_id_; + int32 my_was_online_local_ = 0; std::unordered_map users_; std::unordered_map users_full_; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 9cfeaee2..98ee235d 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -374,8 +374,11 @@ class SetBotUpdatesStatusQuery : public Td::ResultHandler { }; class UpdateStatusQuery : public Td::ResultHandler { + bool is_offline_; + public: NetQueryRef send(bool is_offline) { + is_offline_ = is_offline; auto net_query = G()->net_query_creator().create(create_storer(telegram_api::account_updateStatus(is_offline))); auto result = net_query.get_weak(); send_query(std::move(net_query)); @@ -390,6 +393,7 @@ class UpdateStatusQuery : public Td::ResultHandler { bool result = result_ptr.ok(); LOG(INFO) << "UpdateStatus returned " << result; + td->on_update_status_success(!is_offline_); } void on_error(uint64 id, Status status) override { @@ -3824,7 +3828,7 @@ void Td::on_online_updated(bool force, bool send_update) { return; } if (force || is_online_) { - contacts_manager_->set_my_online_status(is_online_, send_update); + contacts_manager_->set_my_online_status(is_online_, send_update, true); if (!update_status_query_.empty()) { LOG(INFO) << "Cancel previous update status query"; cancel_query(update_status_query_); @@ -3838,6 +3842,15 @@ void Td::on_online_updated(bool force, bool send_update) { } } +void Td::on_update_status_success(bool is_online) { + if (is_online == is_online_) { + if (!update_status_query_.empty()) { + update_status_query_ = NetQueryRef(); + } + contacts_manager_->set_my_online_status(is_online_, true, false); + } +} + void Td::on_channel_unban_timeout(int64 channel_id_long) { if (close_flag_ >= 2) { return; diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 04a7c62a..2038e26c 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -95,6 +95,7 @@ class Td final : public NetQueryCallback { void on_authorization_lost(); void on_online_updated(bool force, bool send_update); + void on_update_status_success(bool is_online); void on_channel_unban_timeout(int64 channel_id_long);