From cb5fe8c7cda16150c2dacf1f9e5d3fd9a96558f8 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 8 Apr 2022 17:17:56 +0300 Subject: [PATCH] Move some related to notification settings methods to NotificationSettingsManager. --- td/telegram/MessagesManager.cpp | 347 ++----------------- td/telegram/MessagesManager.h | 8 - td/telegram/NotificationSettingsManager.cpp | 349 ++++++++++++++++++++ td/telegram/NotificationSettingsManager.h | 27 +- 4 files changed, 393 insertions(+), 338 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index df06f19e4..6f688dcdb 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -47,6 +47,7 @@ #include "td/telegram/NotificationGroupType.h" #include "td/telegram/NotificationManager.h" #include "td/telegram/NotificationSettings.hpp" +#include "td/telegram/NotificationSettingsManager.h" #include "td/telegram/NotificationType.h" #include "td/telegram/PublicDialogType.h" #include "td/telegram/ReplyMarkup.h" @@ -4178,273 +4179,6 @@ class DeleteScheduledMessagesQuery final : public Td::ResultHandler { } }; -class GetDialogNotifySettingsQuery final : public Td::ResultHandler { - DialogId dialog_id_; - - public: - void send(DialogId dialog_id) { - dialog_id_ = dialog_id; - auto input_notify_peer = td_->messages_manager_->get_input_notify_peer(dialog_id); - CHECK(input_notify_peer != nullptr); - send_query(G()->net_query_creator().create(telegram_api::account_getNotifySettings(std::move(input_notify_peer)))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - td_->messages_manager_->on_update_dialog_notify_settings(dialog_id_, std::move(ptr), - "GetDialogNotifySettingsQuery"); - td_->messages_manager_->on_get_dialog_notification_settings_query_finished(dialog_id_, Status::OK()); - } - - void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetDialogNotifySettingsQuery"); - td_->messages_manager_->on_get_dialog_notification_settings_query_finished(dialog_id_, std::move(status)); - } -}; - -class GetNotifySettingsExceptionsQuery final : public Td::ResultHandler { - Promise promise_; - - public: - explicit GetNotifySettingsExceptionsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(NotificationSettingsScope scope, bool filter_scope, bool compare_sound) { - int32 flags = 0; - tl_object_ptr input_notify_peer; - if (filter_scope) { - flags |= telegram_api::account_getNotifyExceptions::PEER_MASK; - input_notify_peer = get_input_notify_peer(scope); - } - if (compare_sound) { - flags |= telegram_api::account_getNotifyExceptions::COMPARE_SOUND_MASK; - } - send_query(G()->net_query_creator().create( - telegram_api::account_getNotifyExceptions(flags, false /* ignored */, std::move(input_notify_peer)))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto updates_ptr = result_ptr.move_as_ok(); - auto dialog_ids = UpdatesManager::get_update_notify_settings_dialog_ids(updates_ptr.get()); - vector> users; - vector> chats; - switch (updates_ptr->get_id()) { - case telegram_api::updatesCombined::ID: { - auto updates = static_cast(updates_ptr.get()); - users = std::move(updates->users_); - chats = std::move(updates->chats_); - reset_to_empty(updates->users_); - reset_to_empty(updates->chats_); - break; - } - case telegram_api::updates::ID: { - auto updates = static_cast(updates_ptr.get()); - users = std::move(updates->users_); - chats = std::move(updates->chats_); - reset_to_empty(updates->users_); - reset_to_empty(updates->chats_); - break; - } - } - td_->contacts_manager_->on_get_users(std::move(users), "GetNotifySettingsExceptionsQuery"); - td_->contacts_manager_->on_get_chats(std::move(chats), "GetNotifySettingsExceptionsQuery"); - for (auto &dialog_id : dialog_ids) { - td_->messages_manager_->force_create_dialog(dialog_id, "GetNotifySettingsExceptionsQuery"); - } - td_->updates_manager_->on_get_updates(std::move(updates_ptr), std::move(promise_)); - } - - void on_error(Status status) final { - promise_.set_error(std::move(status)); - } -}; - -class GetScopeNotifySettingsQuery final : public Td::ResultHandler { - Promise promise_; - NotificationSettingsScope scope_; - - public: - explicit GetScopeNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(NotificationSettingsScope scope) { - scope_ = scope; - auto input_notify_peer = get_input_notify_peer(scope); - CHECK(input_notify_peer != nullptr); - send_query(G()->net_query_creator().create(telegram_api::account_getNotifySettings(std::move(input_notify_peer)))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - td_->messages_manager_->on_update_scope_notify_settings(scope_, std::move(ptr)); - - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - promise_.set_error(std::move(status)); - } -}; - -class UpdateDialogNotifySettingsQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - - public: - explicit UpdateDialogNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, const DialogNotificationSettings &new_settings) { - dialog_id_ = dialog_id; - - auto input_notify_peer = td_->messages_manager_->get_input_notify_peer(dialog_id); - if (input_notify_peer == nullptr) { - return on_error(Status::Error(500, "Can't update chat notification settings")); - } - - int32 flags = 0; - if (!new_settings.use_default_mute_until) { - flags |= telegram_api::inputPeerNotifySettings::MUTE_UNTIL_MASK; - } - if (!new_settings.use_default_sound) { - flags |= telegram_api::inputPeerNotifySettings::SOUND_MASK; - } - if (!new_settings.use_default_show_preview) { - flags |= telegram_api::inputPeerNotifySettings::SHOW_PREVIEWS_MASK; - } - if (new_settings.silent_send_message) { - flags |= telegram_api::inputPeerNotifySettings::SILENT_MASK; - } - send_query(G()->net_query_creator().create(telegram_api::account_updateNotifySettings( - std::move(input_notify_peer), - make_tl_object( - flags, new_settings.show_preview, new_settings.silent_send_message, new_settings.mute_until, - make_tl_object())))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - bool result = result_ptr.ok(); - if (!result) { - return on_error(Status::Error(400, "Receive false as result")); - } - - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "UpdateDialogNotifySettingsQuery")) { - LOG(INFO) << "Receive error for set chat notification settings: " << status; - } - - if (!td_->auth_manager_->is_bot() && td_->messages_manager_->get_input_notify_peer(dialog_id_) != nullptr) { - // trying to repair notification settings for this dialog - td_->messages_manager_->send_get_dialog_notification_settings_query(dialog_id_, Promise<>()); - } - - promise_.set_error(std::move(status)); - } -}; - -class UpdateScopeNotifySettingsQuery final : public Td::ResultHandler { - Promise promise_; - NotificationSettingsScope scope_; - - public: - explicit UpdateScopeNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(NotificationSettingsScope scope, const ScopeNotificationSettings &new_settings) { - auto input_notify_peer = get_input_notify_peer(scope); - CHECK(input_notify_peer != nullptr); - int32 flags = telegram_api::inputPeerNotifySettings::MUTE_UNTIL_MASK | - telegram_api::inputPeerNotifySettings::SOUND_MASK | - telegram_api::inputPeerNotifySettings::SHOW_PREVIEWS_MASK; - send_query(G()->net_query_creator().create(telegram_api::account_updateNotifySettings( - std::move(input_notify_peer), make_tl_object( - flags, new_settings.show_preview, false, new_settings.mute_until, - make_tl_object())))); - scope_ = scope; - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - bool result = result_ptr.ok(); - if (!result) { - return on_error(Status::Error(400, "Receive false as result")); - } - - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - LOG(INFO) << "Receive error for set notification settings: " << status; - - if (!td_->auth_manager_->is_bot()) { - // trying to repair notification settings for this scope - td_->messages_manager_->send_get_scope_notification_settings_query(scope_, Promise<>()); - } - - promise_.set_error(std::move(status)); - } -}; - -class ResetNotifySettingsQuery final : public Td::ResultHandler { - Promise promise_; - - public: - explicit ResetNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send() { - send_query(G()->net_query_creator().create(telegram_api::account_resetNotifySettings())); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - bool result = result_ptr.ok(); - if (!result) { - return on_error(Status::Error(400, "Receive false as result")); - } - - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - if (!G()->is_expected_error(status)) { - LOG(ERROR) << "Receive error for reset notification settings: " << status; - } - promise_.set_error(std::move(status)); - } -}; - class GetPeerSettingsQuery final : public Td::ResultHandler { DialogId dialog_id_; @@ -13468,7 +13202,8 @@ void MessagesManager::init() { channels_notification_settings_.disable_pinned_message_notifications = false; channels_notification_settings_.disable_mention_notifications = false; channels_notification_settings_.is_synchronized = false; - send_get_scope_notification_settings_query(NotificationSettingsScope::Channel, Promise<>()); + td_->notification_settings_manager_->send_get_scope_notification_settings_query( + NotificationSettingsScope::Channel, Promise<>()); } } G()->td_db()->get_binlog_pmc()->erase("nsfac"); @@ -20568,8 +20303,8 @@ void MessagesManager::send_update_dialog_notification_settings_query(const Dialo CHECK(!td_->auth_manager_->is_bot()); CHECK(d != nullptr); // TODO do not send two queries simultaneously or use InvokeAfter - td_->create_handler(std::move(promise)) - ->send(d->dialog_id, d->notification_settings); + td_->notification_settings_manager_->update_dialog_notify_settings(d->dialog_id, d->notification_settings, + std::move(promise)); } void MessagesManager::on_updated_dialog_notification_settings(DialogId dialog_id, uint64 generation) { @@ -21679,7 +21414,8 @@ vector MessagesManager::get_dialog_notification_settings_exceptions(No load_folder_dialog_list(folder.first, MAX_GET_DIALOGS, true); } - td_->create_handler(std::move(promise))->send(scope, filter_scope, compare_sound); + td_->notification_settings_manager_->get_notify_settings_exceptions(scope, filter_scope, compare_sound, + std::move(promise)); return {}; } @@ -21688,7 +21424,7 @@ const ScopeNotificationSettings *MessagesManager::get_scope_notification_setting const ScopeNotificationSettings *notification_settings = get_scope_notification_settings(scope); CHECK(notification_settings != nullptr); if (!notification_settings->is_synchronized && !td_->auth_manager_->is_bot()) { - send_get_scope_notification_settings_query(scope, std::move(promise)); + td_->notification_settings_manager_->send_get_scope_notification_settings_query(scope, std::move(promise)); return nullptr; } @@ -21805,8 +21541,8 @@ void MessagesManager::update_scope_notification_settings_on_server(NotificationS } LOG(INFO) << "Update " << scope << " notification settings on server with log_event " << log_event_id; - td_->create_handler(get_erase_log_event_promise(log_event_id)) - ->send(scope, *get_scope_notification_settings(scope)); + td_->notification_settings_manager_->update_scope_notify_settings(scope, *get_scope_notification_settings(scope), + get_erase_log_event_promise(log_event_id)); } void MessagesManager::reset_all_notification_settings() { @@ -21854,7 +21590,7 @@ void MessagesManager::reset_all_notification_settings_on_server(uint64 log_event } LOG(INFO) << "Reset all notification settings"; - td_->create_handler(get_erase_log_event_promise(log_event_id))->send(); + td_->notification_settings_manager_->reset_notify_settings(get_erase_log_event_promise(log_event_id)); } tl_object_ptr MessagesManager::get_dialog_history(DialogId dialog_id, MessageId from_message_id, @@ -30392,7 +30128,8 @@ bool MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f settings_dialog = get_dialog(settings_dialog_id); } if (settings_dialog != nullptr) { - send_get_dialog_notification_settings_query(settings_dialog_id, std::move(promise)); + td_->notification_settings_manager_->send_get_dialog_notification_settings_query(settings_dialog_id, + std::move(promise)); } else { send_get_dialog_query(settings_dialog_id, std::move(promise), 0, "add_new_message_notification"); } @@ -32815,53 +32552,6 @@ void MessagesManager::reload_voice_chat_on_search(const string &username) { } } -void MessagesManager::send_get_dialog_notification_settings_query(DialogId dialog_id, Promise &&promise) { - if (td_->auth_manager_->is_bot() || dialog_id.get_type() == DialogType::SecretChat) { - LOG(WARNING) << "Can't get notification settings for " << dialog_id; - return promise.set_error(Status::Error(500, "Wrong getDialogNotificationSettings query")); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - LOG(WARNING) << "Have no access to " << dialog_id << " to get notification settings"; - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - - auto &promises = get_dialog_notification_settings_queries_[dialog_id]; - promises.push_back(std::move(promise)); - if (promises.size() != 1) { - // query has already been sent, just wait for the result - return; - } - - td_->create_handler()->send(dialog_id); -} - -void MessagesManager::send_get_scope_notification_settings_query(NotificationSettingsScope scope, - Promise &&promise) { - if (td_->auth_manager_->is_bot()) { - LOG(ERROR) << "Can't get notification settings for " << scope; - return promise.set_error(Status::Error(500, "Wrong getScopeNotificationSettings query")); - } - - td_->create_handler(std::move(promise))->send(scope); -} - -void MessagesManager::on_get_dialog_notification_settings_query_finished(DialogId dialog_id, Status &&status) { - CHECK(!td_->auth_manager_->is_bot()); - auto it = get_dialog_notification_settings_queries_.find(dialog_id); - CHECK(it != get_dialog_notification_settings_queries_.end()); - CHECK(!it->second.empty()); - auto promises = std::move(it->second); - get_dialog_notification_settings_queries_.erase(it); - - for (auto &promise : promises) { - if (status.is_ok()) { - promise.set_value(Unit()); - } else { - promise.set_error(status.clone()); - } - } -} - class MessagesManager::RegetDialogLogEvent { public: DialogId dialog_id_; @@ -36612,7 +36302,7 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab d->notification_settings.is_use_default_fixed = true; on_dialog_updated(dialog_id, "reget notification settings"); } else { - send_get_dialog_notification_settings_query(dialog_id, Promise<>()); + td_->notification_settings_manager_->send_get_dialog_notification_settings_query(dialog_id, Promise<>()); } } if (td_->auth_manager_->is_bot() || d->notification_settings.use_default_mute_until || @@ -37947,13 +37637,16 @@ void MessagesManager::load_notification_settings() { return; } if (!users_notification_settings_.is_synchronized) { - send_get_scope_notification_settings_query(NotificationSettingsScope::Private, Promise<>()); + td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Private, + Promise<>()); } if (!chats_notification_settings_.is_synchronized) { - send_get_scope_notification_settings_query(NotificationSettingsScope::Group, Promise<>()); + td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Group, + Promise<>()); } if (!channels_notification_settings_.is_synchronized) { - send_get_scope_notification_settings_query(NotificationSettingsScope::Channel, Promise<>()); + td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Channel, + Promise<>()); } } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index c448f8ffd..49fa3bb74 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -922,12 +922,6 @@ class MessagesManager final : public Actor { void force_create_dialog(DialogId dialog_id, const char *source, bool expect_no_access = false, bool force_update_dialog_pos = false); - void send_get_dialog_notification_settings_query(DialogId dialog_id, Promise &&promise); - - void send_get_scope_notification_settings_query(NotificationSettingsScope scope, Promise &&promise); - - void on_get_dialog_notification_settings_query_finished(DialogId dialog_id, Status &&status); - void on_get_dialog_query_finished(DialogId dialog_id, Status &&status); void remove_sponsored_dialog(); @@ -3498,8 +3492,6 @@ class MessagesManager final : public Actor { }; FlatHashMap message_embedding_codes_[2]; - FlatHashMap>, DialogIdHash> get_dialog_notification_settings_queries_; - FlatHashMap>, DialogIdHash> get_dialog_queries_; FlatHashMap get_dialog_query_log_event_id_; diff --git a/td/telegram/NotificationSettingsManager.cpp b/td/telegram/NotificationSettingsManager.cpp index 9c8ca60a2..9abcefe0c 100644 --- a/td/telegram/NotificationSettingsManager.cpp +++ b/td/telegram/NotificationSettingsManager.cpp @@ -6,8 +6,287 @@ // #include "td/telegram/NotificationSettingsManager.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/ContactsManager.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UpdatesManager.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/logging.h" + namespace td { +class GetDialogNotifySettingsQuery final : public Td::ResultHandler { + DialogId dialog_id_; + + public: + void send(DialogId dialog_id) { + dialog_id_ = dialog_id; + auto input_notify_peer = td_->messages_manager_->get_input_notify_peer(dialog_id); + CHECK(input_notify_peer != nullptr); + send_query(G()->net_query_creator().create(telegram_api::account_getNotifySettings(std::move(input_notify_peer)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + td_->messages_manager_->on_update_dialog_notify_settings(dialog_id_, std::move(ptr), + "GetDialogNotifySettingsQuery"); + td_->notification_settings_manager_->on_get_dialog_notification_settings_query_finished(dialog_id_, Status::OK()); + } + + void on_error(Status status) final { + td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetDialogNotifySettingsQuery"); + td_->notification_settings_manager_->on_get_dialog_notification_settings_query_finished(dialog_id_, + std::move(status)); + } +}; + +class GetNotifySettingsExceptionsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit GetNotifySettingsExceptionsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(NotificationSettingsScope scope, bool filter_scope, bool compare_sound) { + int32 flags = 0; + tl_object_ptr input_notify_peer; + if (filter_scope) { + flags |= telegram_api::account_getNotifyExceptions::PEER_MASK; + input_notify_peer = get_input_notify_peer(scope); + } + if (compare_sound) { + flags |= telegram_api::account_getNotifyExceptions::COMPARE_SOUND_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::account_getNotifyExceptions(flags, false /* ignored */, std::move(input_notify_peer)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto updates_ptr = result_ptr.move_as_ok(); + auto dialog_ids = UpdatesManager::get_update_notify_settings_dialog_ids(updates_ptr.get()); + vector> users; + vector> chats; + switch (updates_ptr->get_id()) { + case telegram_api::updatesCombined::ID: { + auto updates = static_cast(updates_ptr.get()); + users = std::move(updates->users_); + chats = std::move(updates->chats_); + reset_to_empty(updates->users_); + reset_to_empty(updates->chats_); + break; + } + case telegram_api::updates::ID: { + auto updates = static_cast(updates_ptr.get()); + users = std::move(updates->users_); + chats = std::move(updates->chats_); + reset_to_empty(updates->users_); + reset_to_empty(updates->chats_); + break; + } + } + td_->contacts_manager_->on_get_users(std::move(users), "GetNotifySettingsExceptionsQuery"); + td_->contacts_manager_->on_get_chats(std::move(chats), "GetNotifySettingsExceptionsQuery"); + for (auto &dialog_id : dialog_ids) { + td_->messages_manager_->force_create_dialog(dialog_id, "GetNotifySettingsExceptionsQuery"); + } + td_->updates_manager_->on_get_updates(std::move(updates_ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetScopeNotifySettingsQuery final : public Td::ResultHandler { + Promise promise_; + NotificationSettingsScope scope_; + + public: + explicit GetScopeNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(NotificationSettingsScope scope) { + scope_ = scope; + auto input_notify_peer = get_input_notify_peer(scope); + CHECK(input_notify_peer != nullptr); + send_query(G()->net_query_creator().create(telegram_api::account_getNotifySettings(std::move(input_notify_peer)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + td_->messages_manager_->on_update_scope_notify_settings(scope_, std::move(ptr)); + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class UpdateDialogNotifySettingsQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit UpdateDialogNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, const DialogNotificationSettings &new_settings) { + dialog_id_ = dialog_id; + + auto input_notify_peer = td_->messages_manager_->get_input_notify_peer(dialog_id); + if (input_notify_peer == nullptr) { + return on_error(Status::Error(500, "Can't update chat notification settings")); + } + + int32 flags = 0; + if (!new_settings.use_default_mute_until) { + flags |= telegram_api::inputPeerNotifySettings::MUTE_UNTIL_MASK; + } + if (!new_settings.use_default_sound) { + flags |= telegram_api::inputPeerNotifySettings::SOUND_MASK; + } + if (!new_settings.use_default_show_preview) { + flags |= telegram_api::inputPeerNotifySettings::SHOW_PREVIEWS_MASK; + } + if (new_settings.silent_send_message) { + flags |= telegram_api::inputPeerNotifySettings::SILENT_MASK; + } + send_query(G()->net_query_creator().create(telegram_api::account_updateNotifySettings( + std::move(input_notify_peer), + make_tl_object( + flags, new_settings.show_preview, new_settings.silent_send_message, new_settings.mute_until, + make_tl_object())))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + if (!result) { + return on_error(Status::Error(400, "Receive false as result")); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "UpdateDialogNotifySettingsQuery")) { + LOG(INFO) << "Receive error for set chat notification settings: " << status; + } + + if (!td_->auth_manager_->is_bot() && td_->messages_manager_->get_input_notify_peer(dialog_id_) != nullptr) { + // trying to repair notification settings for this dialog + td_->notification_settings_manager_->send_get_dialog_notification_settings_query(dialog_id_, Promise<>()); + } + + promise_.set_error(std::move(status)); + } +}; + +class UpdateScopeNotifySettingsQuery final : public Td::ResultHandler { + Promise promise_; + NotificationSettingsScope scope_; + + public: + explicit UpdateScopeNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(NotificationSettingsScope scope, const ScopeNotificationSettings &new_settings) { + auto input_notify_peer = get_input_notify_peer(scope); + CHECK(input_notify_peer != nullptr); + int32 flags = telegram_api::inputPeerNotifySettings::MUTE_UNTIL_MASK | + telegram_api::inputPeerNotifySettings::SOUND_MASK | + telegram_api::inputPeerNotifySettings::SHOW_PREVIEWS_MASK; + send_query(G()->net_query_creator().create(telegram_api::account_updateNotifySettings( + std::move(input_notify_peer), make_tl_object( + flags, new_settings.show_preview, false, new_settings.mute_until, + make_tl_object())))); + scope_ = scope; + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + if (!result) { + return on_error(Status::Error(400, "Receive false as result")); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for set notification settings: " << status; + + if (!td_->auth_manager_->is_bot()) { + // trying to repair notification settings for this scope + td_->notification_settings_manager_->send_get_scope_notification_settings_query(scope_, Promise<>()); + } + + promise_.set_error(std::move(status)); + } +}; + +class ResetNotifySettingsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ResetNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::account_resetNotifySettings())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + if (!result) { + return on_error(Status::Error(400, "Receive false as result")); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + if (!G()->is_expected_error(status)) { + LOG(ERROR) << "Receive error for reset notification settings: " << status; + } + promise_.set_error(std::move(status)); + } +}; + NotificationSettingsManager::NotificationSettingsManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { } @@ -18,4 +297,74 @@ void NotificationSettingsManager::tear_down() { parent_.reset(); } +void NotificationSettingsManager::send_get_dialog_notification_settings_query(DialogId dialog_id, + Promise &&promise) { + if (td_->auth_manager_->is_bot() || dialog_id.get_type() == DialogType::SecretChat) { + LOG(WARNING) << "Can't get notification settings for " << dialog_id; + return promise.set_error(Status::Error(500, "Wrong getDialogNotificationSettings query")); + } + if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { + LOG(WARNING) << "Have no access to " << dialog_id << " to get notification settings"; + return promise.set_error(Status::Error(400, "Can't access the chat")); + } + + auto &promises = get_dialog_notification_settings_queries_[dialog_id]; + promises.push_back(std::move(promise)); + if (promises.size() != 1) { + // query has already been sent, just wait for the result + return; + } + + td_->create_handler()->send(dialog_id); +} + +void NotificationSettingsManager::send_get_scope_notification_settings_query(NotificationSettingsScope scope, + Promise &&promise) { + if (td_->auth_manager_->is_bot()) { + LOG(ERROR) << "Can't get notification settings for " << scope; + return promise.set_error(Status::Error(500, "Wrong getScopeNotificationSettings query")); + } + + td_->create_handler(std::move(promise))->send(scope); +} + +void NotificationSettingsManager::on_get_dialog_notification_settings_query_finished(DialogId dialog_id, + Status &&status) { + CHECK(!td_->auth_manager_->is_bot()); + auto it = get_dialog_notification_settings_queries_.find(dialog_id); + CHECK(it != get_dialog_notification_settings_queries_.end()); + CHECK(!it->second.empty()); + auto promises = std::move(it->second); + get_dialog_notification_settings_queries_.erase(it); + + for (auto &promise : promises) { + if (status.is_ok()) { + promise.set_value(Unit()); + } else { + promise.set_error(status.clone()); + } + } +} + +void NotificationSettingsManager::update_dialog_notify_settings(DialogId dialog_id, + const DialogNotificationSettings &new_settings, + Promise &&promise) { + td_->create_handler(std::move(promise))->send(dialog_id, new_settings); +} + +void NotificationSettingsManager::update_scope_notify_settings(NotificationSettingsScope scope, + const ScopeNotificationSettings &new_settings, + Promise &&promise) { + td_->create_handler(std::move(promise))->send(scope, new_settings); +} + +void NotificationSettingsManager::reset_notify_settings(Promise &&promise) { + td_->create_handler(std::move(promise))->send(); +} + +void NotificationSettingsManager::get_notify_settings_exceptions(NotificationSettingsScope scope, bool filter_scope, + bool compare_sound, Promise &&promise) { + td_->create_handler(std::move(promise))->send(scope, filter_scope, compare_sound); +} + } // namespace td diff --git a/td/telegram/NotificationSettingsManager.h b/td/telegram/NotificationSettingsManager.h index 92b994c3a..c3d39df1e 100644 --- a/td/telegram/NotificationSettingsManager.h +++ b/td/telegram/NotificationSettingsManager.h @@ -6,9 +6,14 @@ // #pragma once +#include "td/telegram/DialogId.h" +#include "td/telegram/NotificationSettings.h" + #include "td/actor/actor.h" +#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" namespace td { @@ -23,14 +28,30 @@ class NotificationSettingsManager final : public Actor { NotificationSettingsManager &operator=(NotificationSettingsManager &&) = delete; ~NotificationSettingsManager() final; - private: - struct SponsoredMessage; - struct DialogSponsoredMessages; + void send_get_dialog_notification_settings_query(DialogId dialog_id, Promise &&promise); + void send_get_scope_notification_settings_query(NotificationSettingsScope scope, Promise &&promise); + + void on_get_dialog_notification_settings_query_finished(DialogId dialog_id, Status &&status); + + void update_dialog_notify_settings(DialogId dialog_id, const DialogNotificationSettings &new_settings, + Promise &&promise); + + void update_scope_notify_settings(NotificationSettingsScope scope, const ScopeNotificationSettings &new_settings, + Promise &&promise); + + void reset_notify_settings(Promise &&promise); + + void get_notify_settings_exceptions(NotificationSettingsScope scope, bool filter_scope, bool compare_sound, + Promise &&promise); + + private: void tear_down() final; Td *td_; ActorShared<> parent_; + + FlatHashMap>, DialogIdHash> get_dialog_notification_settings_queries_; }; } // namespace td