From d6502458f58a807d0b43c8471b61b84aea352814 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 12 Oct 2021 22:05:14 +0300 Subject: [PATCH] Allow to get option "is_location_visible". --- td/telegram/ContactsManager.cpp | 75 +++++++++++++++++++++++++++------ td/telegram/ContactsManager.h | 4 ++ td/telegram/Td.cpp | 8 ++++ 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index f9c6d369a..fc73d9099 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -5775,20 +5775,6 @@ void ContactsManager::search_dialogs_nearby(const Location &location, td_->create_handler(std::move(query_promise))->send(location, false, -1); } -void ContactsManager::set_location(const Location &location, Promise &&promise) { - if (location.empty()) { - return promise.set_error(Status::Error(400, "Invalid location specified")); - } - last_user_location_ = location; - try_send_set_location_visibility_query(); - - auto query_promise = PromiseCreator::lambda( - [promise = std::move(promise)](Result> result) mutable { - promise.set_value(Unit()); - }); - td_->create_handler(std::move(query_promise))->send(location, true, -1); -} - vector> ContactsManager::get_chats_nearby_object( const vector &dialogs_nearby) { return transform(dialogs_nearby, [](const DialogNearby &dialog_nearby) { @@ -5851,6 +5837,20 @@ void ContactsManager::on_get_dialogs_nearby(Result &&promise) { + if (location.empty()) { + return promise.set_error(Status::Error(400, "Invalid location specified")); + } + last_user_location_ = location; + try_send_set_location_visibility_query(); + + auto query_promise = PromiseCreator::lambda( + [promise = std::move(promise)](Result> result) mutable { + promise.set_value(Unit()); + }); + td_->create_handler(std::move(query_promise))->send(location, true, -1); +} + void ContactsManager::set_location_visibility() { bool is_location_visible = G()->shared_config().get_option_boolean("is_location_visible"); auto pending_location_visibility_expire_date = is_location_visible ? std::numeric_limits::max() : 0; @@ -5918,6 +5918,53 @@ void ContactsManager::on_set_location_visibility_expire_date(int32 set_expire_da update_is_location_visible(); } +void ContactsManager::get_is_location_visible(Promise &&promise) { + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)]( + Result> result) mutable { + send_closure(actor_id, &ContactsManager::on_get_is_location_visible, std::move(result), std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(Location(), true, -1); +} + +void ContactsManager::on_get_is_location_visible(Result> &&result, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + if (result.is_error()) { + if (result.error().message() == "GEO_POINT_INVALID" && pending_location_visibility_expire_date_ == -1 && + location_visibility_expire_date_ > 0) { + set_location_visibility_expire_date(0); + update_is_location_visible(); + } + return promise.set_value(Unit()); + } + + auto updates_ptr = result.move_as_ok(); + if (updates_ptr->get_id() != telegram_api::updates::ID) { + LOG(ERROR) << "Receive " << oneline(to_string(*updates_ptr)) << " instead of updates"; + return promise.set_value(Unit()); + } + + auto updates = std::move(telegram_api::move_object_as(updates_ptr)->updates_); + if (updates.size() != 1 || updates[0]->get_id() != telegram_api::updatePeerLocated::ID) { + LOG(ERROR) << "Receive unexpected " << to_string(updates); + return promise.set_value(Unit()); + } + + auto peers = std::move(static_cast(updates[0].get())->peers_); + if (peers.size() != 1 || peers[0]->get_id() != telegram_api::peerSelfLocated::ID) { + LOG(ERROR) << "Receive unexpected " << to_string(peers); + return promise.set_value(Unit()); + } + + auto location_visibility_expire_date = static_cast(peers[0].get())->expires_; + if (location_visibility_expire_date != location_visibility_expire_date_) { + set_location_visibility_expire_date(location_visibility_expire_date); + update_is_location_visible(); + } + + promise.set_value(Unit()); +} + int32 ContactsManager::on_update_peer_located(vector> &&peers, bool from_update) { auto now = G()->unix_time(); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 37dd7c431..df4156be9 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -317,6 +317,8 @@ class ContactsManager final : public Actor { void set_location_visibility(); + void get_is_location_visible(Promise &&promise); + FileId get_profile_photo_file_id(int64 photo_id) const; void set_profile_photo(const td_api::object_ptr &input_photo, Promise &&promise); @@ -1386,6 +1388,8 @@ class ContactsManager final : public Actor { void set_location_visibility_expire_date(int32 expire_date); + void on_get_is_location_visible(Result> &&result, Promise &&promise); + void update_is_location_visible(); static bool is_channel_public(const Channel *c); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 8e0fad362..9e41dde06 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7209,6 +7209,14 @@ void Td::on_request(uint64 id, td_api::getOption &request) { send_closure_later(config_manager_, &ConfigManager::get_content_settings, std::move(promise)); return; } + if (!is_bot && request.name_ == "is_location_visible") { + auto promise = PromiseCreator::lambda([actor_id = actor_id(this), id](Result &&result) { + // the option is already updated on success, ignore errors + send_closure(actor_id, &Td::send_result, id, G()->shared_config().get_option_value("is_location_visible")); + }); + send_closure_later(contacts_manager_actor_, &ContactsManager::get_is_location_visible, std::move(promise)); + return; + } break; case 'o': if (request.name_ == "online") {