diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index ff39e0872..bbbabdade 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3751,6 +3751,10 @@ getPollVoters chat_id:int53 message_id:int53 option_id:int32 offset:int32 limit: stopPoll chat_id:int53 message_id:int53 reply_markup:ReplyMarkup = Ok; +//@description Hides a suggested action @action Suggested action to hide +hideSuggestedAction action:SuggestedAction = Ok; + + //@description Returns information about a button of type inlineKeyboardButtonTypeLoginUrl. The method needs to be called when the user presses the button //@chat_id Chat identifier of the message with the button @message_id Message identifier of the message with the button @button_id Button identifier getLoginUrlInfo chat_id:int53 message_id:int53 button_id:int32 = LoginUrlInfo; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index d2cafd30a..f92509651 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 680ec028c..fac032650 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -1060,6 +1060,29 @@ td_api::object_ptr ConfigManager::get_update_sug transform(removed_actions, get_suggested_action_object)); } +void ConfigManager::dismiss_suggested_action(SuggestedAction suggested_action, Promise &&promise) { + if (suggested_action == SuggestedAction::Empty) { + return promise.set_error(Status::Error(400, "Action must be non-empty")); + } + auto action_str = get_suggested_action_str(suggested_action); + if (action_str.empty()) { + return promise.set_value(Unit()); + } + + if (!td::contains(suggested_actions_, suggested_action)) { + return promise.set_value(Unit()); + } + + dismiss_suggested_action_request_count_++; + auto &queries = dismiss_suggested_action_queries_[suggested_action]; + queries.push_back(std::move(promise)); + if (queries.size() == 1) { + G()->net_query_dispatcher().dispatch_with_callback( + G()->net_query_creator().create(telegram_api::help_dismissSuggestion(action_str)), + actor_shared(this, 100 + static_cast(suggested_action))); + } +} + void ConfigManager::do_dismiss_suggested_action(SuggestedAction suggested_action) { if (td::remove(suggested_actions_, suggested_action)) { send_closure(G()->td(), &Td::send_update, get_update_suggested_actions({}, {suggested_action})); @@ -1068,6 +1091,29 @@ void ConfigManager::do_dismiss_suggested_action(SuggestedAction suggested_action void ConfigManager::on_result(NetQueryPtr res) { auto token = get_link_token(); + if (token >= 100 && token <= 200) { + SuggestedAction suggested_action = static_cast(static_cast(token - 100)); + auto promises = std::move(dismiss_suggested_action_queries_[suggested_action]); + dismiss_suggested_action_queries_.erase(suggested_action); + CHECK(!promises.empty()); + CHECK(dismiss_suggested_action_request_count_ >= promises.size()); + dismiss_suggested_action_request_count_ -= promises.size(); + + auto result_ptr = fetch_result(std::move(res)); + if (result_ptr.is_error()) { + for (auto &promise : promises) { + promise.set_error(result_ptr.error().clone()); + } + return; + } + do_dismiss_suggested_action(suggested_action); + get_app_config(Auto()); + + for (auto &promise : promises) { + promise.set_value(Unit()); + } + return; + } if (token == 6 || token == 7) { is_set_archive_and_mute_request_sent_ = false; bool archive_and_mute = (token == 7); @@ -1616,7 +1662,8 @@ void ConfigManager::process_app_config(tl_object_ptr &c shared_config.set_option_empty("default_ton_blockchain_config"); shared_config.set_option_empty("default_ton_blockchain_name"); - if (!is_set_content_settings_request_sent_) { // do not update suggested actions while changing content settings + // do not update suggested actions while changing content settings or dismissing an action + if (!is_set_content_settings_request_sent_ && dismiss_suggested_action_request_count_ == 0) { std::sort(suggested_actions.begin(), suggested_actions.end()); suggested_actions.erase(std::unique(suggested_actions.begin(), suggested_actions.end()), suggested_actions.end()); if (suggested_actions != suggested_actions_) { @@ -1625,7 +1672,8 @@ void ConfigManager::process_app_config(tl_object_ptr &c auto old_it = suggested_actions_.begin(); auto new_it = suggested_actions.begin(); while (old_it != suggested_actions_.end() || new_it != suggested_actions.end()) { - if (new_it == suggested_actions.end() || std::less()(*old_it, *new_it)) { + if (old_it != suggested_actions_.end() && + (new_it == suggested_actions.end() || std::less()(*old_it, *new_it))) { removed_actions.push_back(*old_it++); } else if (old_it == suggested_actions_.end() || std::less()(*new_it, *old_it)) { added_actions.push_back(*new_it++); diff --git a/td/telegram/ConfigManager.h b/td/telegram/ConfigManager.h index e789da2d7..11b968e2b 100644 --- a/td/telegram/ConfigManager.h +++ b/td/telegram/ConfigManager.h @@ -24,6 +24,8 @@ #include "td/utils/Status.h" #include "td/utils/Time.h" +#include + namespace td { extern int VERBOSITY_NAME(config_recoverer); @@ -95,6 +97,8 @@ class ConfigManager : public NetQueryCallback { void set_archive_and_mute(bool archive_and_mute, Promise &&promise); + void dismiss_suggested_action(SuggestedAction suggested_action, Promise &&promise); + void on_dc_options_update(DcOptions dc_options); void get_current_state(vector> &updates) const; @@ -119,6 +123,8 @@ class ConfigManager : public NetQueryCallback { bool last_set_archive_and_mute_ = false; vector suggested_actions_; + size_t dismiss_suggested_action_request_count_ = 0; + std::map>> dismiss_suggested_action_queries_; void start_up() override; void hangup_shared() override; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 25320f689..4c7e72758 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -83,6 +83,7 @@ #include "td/telegram/StickerSetId.h" #include "td/telegram/StickersManager.h" #include "td/telegram/StorageManager.h" +#include "td/telegram/SuggestedAction.h" #include "td/telegram/TdDb.h" #include "td/telegram/TopDialogCategory.h" #include "td/telegram/TopDialogManager.h" @@ -7226,6 +7227,13 @@ void Td::on_request(uint64 id, td_api::stopPoll &request) { std::move(request.reply_markup_), std::move(promise)); } +void Td::on_request(uint64 id, const td_api::hideSuggestedAction &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure_later(config_manager_, &ConfigManager::dismiss_suggested_action, get_suggested_action(request.action_), + std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::getLoginUrlInfo &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 76718db61..f37106d6d 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -941,6 +941,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, td_api::stopPoll &request); + void on_request(uint64 id, const td_api::hideSuggestedAction &request); + void on_request(uint64 id, const td_api::getLoginUrlInfo &request); void on_request(uint64 id, const td_api::getLoginUrl &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 4b9ee46c5..2aca2ccbb 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1194,6 +1194,16 @@ class CliClient final : public Actor { return nullptr; } + static td_api::object_ptr as_suggested_action(Slice action) { + if (action == "unarchive") { + return td_api::make_object(); + } + if (action == "number") { + return td_api::make_object(); + } + return nullptr; + } + static td_api::object_ptr as_passport_element_type(Slice passport_element_type) { if (passport_element_type == "address" || passport_element_type == "a") { return td_api::make_object(); @@ -3996,6 +4006,8 @@ class CliClient final : public Actor { send_request( td_api::make_object(as_chat_id(chat_id), token, to_integer(x))); + } else if (op == "hsa" || op == "glu" || op == "glua") { + send_request(td_api::make_object(as_suggested_action(args))); } else if (op == "glui" || op == "glu" || op == "glua") { string chat_id; string message_id;