Use struct for SuggestedAction.

This commit is contained in:
levlam 2021-02-21 01:06:45 +03:00
parent a41bca4b0e
commit a14c9071f1
5 changed files with 91 additions and 61 deletions

View File

@ -58,7 +58,6 @@
#include "td/utils/UInt.h" #include "td/utils/UInt.h"
#include <algorithm> #include <algorithm>
#include <functional>
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
@ -1080,7 +1079,7 @@ void ConfigManager::set_archive_and_mute(bool archive_and_mute, Promise<Unit> &&
return promise.set_error(Status::Error(500, "Request aborted")); return promise.set_error(Status::Error(500, "Request aborted"));
} }
if (archive_and_mute) { if (archive_and_mute) {
do_dismiss_suggested_action(SuggestedAction::EnableArchiveAndMuteNewChats); do_dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::EnableArchiveAndMuteNewChats});
} }
last_set_archive_and_mute_ = archive_and_mute; last_set_archive_and_mute_ = archive_and_mute;
@ -1125,16 +1124,16 @@ void ConfigManager::do_set_ignore_sensitive_content_restrictions(bool ignore_sen
void ConfigManager::do_set_archive_and_mute(bool archive_and_mute) { void ConfigManager::do_set_archive_and_mute(bool archive_and_mute) {
if (archive_and_mute) { if (archive_and_mute) {
do_dismiss_suggested_action(SuggestedAction::EnableArchiveAndMuteNewChats); do_dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::EnableArchiveAndMuteNewChats});
} }
G()->shared_config().set_option_boolean("archive_and_mute_new_chats_from_unknown_users", archive_and_mute); G()->shared_config().set_option_boolean("archive_and_mute_new_chats_from_unknown_users", archive_and_mute);
} }
void ConfigManager::dismiss_suggested_action(SuggestedAction suggested_action, Promise<Unit> &&promise) { void ConfigManager::dismiss_suggested_action(SuggestedAction suggested_action, Promise<Unit> &&promise) {
if (suggested_action == SuggestedAction::Empty) { if (suggested_action == SuggestedAction()) {
return promise.set_error(Status::Error(400, "Action must be non-empty")); return promise.set_error(Status::Error(400, "Action must be non-empty"));
} }
auto action_str = get_suggested_action_str(suggested_action); auto action_str = suggested_action.get_suggested_action_str();
if (action_str.empty()) { if (action_str.empty()) {
return promise.set_value(Unit()); return promise.set_value(Unit());
} }
@ -1144,13 +1143,14 @@ void ConfigManager::dismiss_suggested_action(SuggestedAction suggested_action, P
} }
dismiss_suggested_action_request_count_++; dismiss_suggested_action_request_count_++;
auto &queries = dismiss_suggested_action_queries_[suggested_action]; auto type = static_cast<int32>(suggested_action.type_);
auto &queries = dismiss_suggested_action_queries_[type];
queries.push_back(std::move(promise)); queries.push_back(std::move(promise));
if (queries.size() == 1) { if (queries.size() == 1) {
G()->net_query_dispatcher().dispatch_with_callback( G()->net_query_dispatcher().dispatch_with_callback(
G()->net_query_creator().create( G()->net_query_creator().create(
telegram_api::help_dismissSuggestion(make_tl_object<telegram_api::inputPeerEmpty>(), action_str)), telegram_api::help_dismissSuggestion(make_tl_object<telegram_api::inputPeerEmpty>(), action_str)),
actor_shared(this, 100 + static_cast<int32>(suggested_action))); actor_shared(this, 100 + type));
} }
} }
@ -1163,9 +1163,10 @@ void ConfigManager::do_dismiss_suggested_action(SuggestedAction suggested_action
void ConfigManager::on_result(NetQueryPtr res) { void ConfigManager::on_result(NetQueryPtr res) {
auto token = get_link_token(); auto token = get_link_token();
if (token >= 100 && token <= 200) { if (token >= 100 && token <= 200) {
SuggestedAction suggested_action = static_cast<SuggestedAction>(static_cast<int32>(token - 100)); auto type = static_cast<int32>(token - 100);
auto promises = std::move(dismiss_suggested_action_queries_[suggested_action]); SuggestedAction suggested_action{static_cast<SuggestedAction::Type>(type)};
dismiss_suggested_action_queries_.erase(suggested_action); auto promises = std::move(dismiss_suggested_action_queries_[type]);
dismiss_suggested_action_queries_.erase(type);
CHECK(!promises.empty()); CHECK(!promises.empty());
CHECK(dismiss_suggested_action_request_count_ >= promises.size()); CHECK(dismiss_suggested_action_request_count_ >= promises.size());
dismiss_suggested_action_request_count_ -= promises.size(); dismiss_suggested_action_request_count_ -= promises.size();
@ -1668,10 +1669,11 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
CHECK(action != nullptr); CHECK(action != nullptr);
if (action->get_id() == telegram_api::jsonString::ID) { if (action->get_id() == telegram_api::jsonString::ID) {
Slice action_str = static_cast<telegram_api::jsonString *>(action.get())->value_; Slice action_str = static_cast<telegram_api::jsonString *>(action.get())->value_;
auto suggested_action = get_suggested_action(action_str); SuggestedAction suggested_action(action_str);
if (suggested_action != SuggestedAction::Empty) { if (suggested_action != SuggestedAction()) {
if (archive_and_mute && suggested_action == SuggestedAction::EnableArchiveAndMuteNewChats) { if (archive_and_mute &&
LOG(INFO) << "Skip SuggestedAction::EnableArchiveAndMuteNewChats"; suggested_action == SuggestedAction{SuggestedAction::Type::EnableArchiveAndMuteNewChats}) {
LOG(INFO) << "Skip EnableArchiveAndMuteNewChats suggested action";
} else { } else {
suggested_actions.push_back(suggested_action); suggested_actions.push_back(suggested_action);
} }
@ -1790,10 +1792,9 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
auto old_it = suggested_actions_.begin(); auto old_it = suggested_actions_.begin();
auto new_it = suggested_actions.begin(); auto new_it = suggested_actions.begin();
while (old_it != suggested_actions_.end() || new_it != suggested_actions.end()) { while (old_it != suggested_actions_.end() || new_it != suggested_actions.end()) {
if (old_it != suggested_actions_.end() && if (old_it != suggested_actions_.end() && (new_it == suggested_actions.end() || *old_it < *new_it)) {
(new_it == suggested_actions.end() || std::less<SuggestedAction>()(*old_it, *new_it))) {
removed_actions.push_back(*old_it++); removed_actions.push_back(*old_it++);
} else if (old_it == suggested_actions_.end() || std::less<SuggestedAction>()(*new_it, *old_it)) { } else if (old_it == suggested_actions_.end() || *new_it < *old_it) {
added_actions.push_back(*new_it++); added_actions.push_back(*new_it++);
} else { } else {
old_it++; old_it++;

View File

@ -136,7 +136,7 @@ class ConfigManager : public NetQueryCallback {
vector<SuggestedAction> suggested_actions_; vector<SuggestedAction> suggested_actions_;
size_t dismiss_suggested_action_request_count_ = 0; size_t dismiss_suggested_action_request_count_ = 0;
std::map<SuggestedAction, vector<Promise<Unit>>> dismiss_suggested_action_queries_; std::map<int32, vector<Promise<Unit>>> dismiss_suggested_action_queries_;
static constexpr uint64 REFCNT_TOKEN = std::numeric_limits<uint64>::max() - 2; static constexpr uint64 REFCNT_TOKEN = std::numeric_limits<uint64>::max() - 2;

View File

@ -10,53 +10,57 @@
namespace td { namespace td {
SuggestedAction get_suggested_action(Slice action_str) { void SuggestedAction::init(Type type) {
if (action_str == Slice("AUTOARCHIVE_POPULAR")) { type_ = type;
return SuggestedAction::EnableArchiveAndMuteNewChats;
}
if (action_str == Slice("NEWCOMER_TICKS")) {
return SuggestedAction::SeeTicksHint;
}
return SuggestedAction::Empty;
} }
string get_suggested_action_str(SuggestedAction action) { SuggestedAction::SuggestedAction(Slice action_str) {
switch (action) { if (action_str == Slice("AUTOARCHIVE_POPULAR")) {
case SuggestedAction::EnableArchiveAndMuteNewChats: init(Type::EnableArchiveAndMuteNewChats);
} else if (action_str == Slice("NEWCOMER_TICKS")) {
init(Type::SeeTicksHint);
}
}
SuggestedAction::SuggestedAction(const td_api::object_ptr<td_api::SuggestedAction> &action_object) {
if (action_object == nullptr) {
return;
}
switch (action_object->get_id()) {
case td_api::suggestedActionEnableArchiveAndMuteNewChats::ID:
init(Type::EnableArchiveAndMuteNewChats);
break;
case td_api::suggestedActionCheckPhoneNumber::ID:
init(Type::CheckPhoneNumber);
break;
case td_api::suggestedActionSeeTicksHint::ID:
init(Type::SeeTicksHint);
break;
default:
UNREACHABLE();
}
}
string SuggestedAction::get_suggested_action_str() const {
switch (type_) {
case Type::EnableArchiveAndMuteNewChats:
return "AUTOARCHIVE_POPULAR"; return "AUTOARCHIVE_POPULAR";
case SuggestedAction::SeeTicksHint: case Type::SeeTicksHint:
return "NEWCOMER_TICKS"; return "NEWCOMER_TICKS";
default: default:
return string(); return string();
} }
} }
SuggestedAction get_suggested_action(const td_api::object_ptr<td_api::SuggestedAction> &action_object) { td_api::object_ptr<td_api::SuggestedAction> SuggestedAction::get_suggested_action_object() const {
if (action_object == nullptr) { switch (type_) {
return SuggestedAction::Empty; case Type::Empty:
}
switch (action_object->get_id()) {
case td_api::suggestedActionEnableArchiveAndMuteNewChats::ID:
return SuggestedAction::EnableArchiveAndMuteNewChats;
case td_api::suggestedActionCheckPhoneNumber::ID:
return SuggestedAction::CheckPhoneNumber;
case td_api::suggestedActionSeeTicksHint::ID:
return SuggestedAction::SeeTicksHint;
default:
UNREACHABLE();
return SuggestedAction::Empty;
}
}
td_api::object_ptr<td_api::SuggestedAction> get_suggested_action_object(SuggestedAction action) {
switch (action) {
case SuggestedAction::Empty:
return nullptr; return nullptr;
case SuggestedAction::EnableArchiveAndMuteNewChats: case Type::EnableArchiveAndMuteNewChats:
return td_api::make_object<td_api::suggestedActionEnableArchiveAndMuteNewChats>(); return td_api::make_object<td_api::suggestedActionEnableArchiveAndMuteNewChats>();
case SuggestedAction::CheckPhoneNumber: case Type::CheckPhoneNumber:
return td_api::make_object<td_api::suggestedActionCheckPhoneNumber>(); return td_api::make_object<td_api::suggestedActionCheckPhoneNumber>();
case SuggestedAction::SeeTicksHint: case Type::SeeTicksHint:
return td_api::make_object<td_api::suggestedActionSeeTicksHint>(); return td_api::make_object<td_api::suggestedActionSeeTicksHint>();
default: default:
UNREACHABLE(); UNREACHABLE();
@ -66,8 +70,11 @@ td_api::object_ptr<td_api::SuggestedAction> get_suggested_action_object(Suggeste
td_api::object_ptr<td_api::updateSuggestedActions> get_update_suggested_actions_object( td_api::object_ptr<td_api::updateSuggestedActions> get_update_suggested_actions_object(
const vector<SuggestedAction> &added_actions, const vector<SuggestedAction> &removed_actions) { const vector<SuggestedAction> &added_actions, const vector<SuggestedAction> &removed_actions) {
return td_api::make_object<td_api::updateSuggestedActions>(transform(added_actions, get_suggested_action_object), auto get_object = [](const SuggestedAction &action) {
transform(removed_actions, get_suggested_action_object)); return action.get_suggested_action_object();
};
return td_api::make_object<td_api::updateSuggestedActions>(transform(added_actions, get_object),
transform(removed_actions, get_object));
} }
} // namespace td } // namespace td

View File

@ -13,15 +13,37 @@
namespace td { namespace td {
enum class SuggestedAction : int32 { Empty, EnableArchiveAndMuteNewChats, CheckPhoneNumber, SeeTicksHint }; struct SuggestedAction {
enum class Type : int32 { Empty, EnableArchiveAndMuteNewChats, CheckPhoneNumber, SeeTicksHint };
Type type_ = Type::Empty;
SuggestedAction get_suggested_action(Slice action_str); void init(Type type);
string get_suggested_action_str(SuggestedAction action); SuggestedAction() = default;
SuggestedAction get_suggested_action(const td_api::object_ptr<td_api::SuggestedAction> &action_object); explicit SuggestedAction(Type type) : type_(type) {
}
td_api::object_ptr<td_api::SuggestedAction> get_suggested_action_object(SuggestedAction action); explicit SuggestedAction(Slice action_str);
explicit SuggestedAction(const td_api::object_ptr<td_api::SuggestedAction> &action_object);
string get_suggested_action_str() const;
td_api::object_ptr<td_api::SuggestedAction> get_suggested_action_object() const;
};
inline bool operator==(const SuggestedAction &lhs, const SuggestedAction &rhs) {
return lhs.type_ == rhs.type_;
}
inline bool operator!=(const SuggestedAction &lhs, const SuggestedAction &rhs) {
return !(lhs == rhs);
}
inline bool operator<(const SuggestedAction &lhs, const SuggestedAction &rhs) {
return static_cast<int32>(lhs.type_) < static_cast<int32>(rhs.type_);
}
td_api::object_ptr<td_api::updateSuggestedActions> get_update_suggested_actions_object( td_api::object_ptr<td_api::updateSuggestedActions> get_update_suggested_actions_object(
const vector<SuggestedAction> &added_actions, const vector<SuggestedAction> &removed_actions); const vector<SuggestedAction> &added_actions, const vector<SuggestedAction> &removed_actions);

View File

@ -7530,7 +7530,7 @@ void Td::on_request(uint64 id, td_api::stopPoll &request) {
void Td::on_request(uint64 id, const td_api::hideSuggestedAction &request) { void Td::on_request(uint64 id, const td_api::hideSuggestedAction &request) {
CHECK_IS_USER(); CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE(); CREATE_OK_REQUEST_PROMISE();
send_closure_later(config_manager_, &ConfigManager::dismiss_suggested_action, get_suggested_action(request.action_), send_closure_later(config_manager_, &ConfigManager::dismiss_suggested_action, SuggestedAction(request.action_),
std::move(promise)); std::move(promise));
} }