diff --git a/td/telegram/FileReferenceManager.cpp b/td/telegram/FileReferenceManager.cpp index 0748c34ca..4922825c2 100644 --- a/td/telegram/FileReferenceManager.cpp +++ b/td/telegram/FileReferenceManager.cpp @@ -13,6 +13,7 @@ #include "td/telegram/files/FileManager.h" #include "td/telegram/Global.h" #include "td/telegram/MessagesManager.h" +#include "td/telegram/NotificationSettingsManager.h" #include "td/telegram/StickerSetId.h" #include "td/telegram/StickersManager.h" #include "td/telegram/Td.h" @@ -60,6 +61,7 @@ fileSourceBackground background_id:int64 access_hash:int64 = FileSource; // repa fileSourceBasicGroupFull basic_group_id:int32 = FileSource; // repaired with messages.getFullChat fileSourceSupergroupFull supergroup_id:int32 = FileSource; // repaired with messages.getFullChannel fileSourceAppConfig = FileSource; // repaired with help.getAppConfig, not reliable +fileSourceSavedRingtones = FileSource; // repaired with account.getSavedRingtones */ FileSourceId FileReferenceManager::get_current_file_source_id() const { @@ -131,6 +133,11 @@ bool FileReferenceManager::add_file_source(NodeId node_id, FileSourceId file_sou return is_added; } +FileSourceId FileReferenceManager::create_saved_ringtones_file_source() { + FileSourceSavedRingtones source; + return add_file_source_id(source, "saved notification sounds"); +} + bool FileReferenceManager::remove_file_source(NodeId node_id, FileSourceId file_source_id) { CHECK(node_id.is_valid()); bool is_removed = nodes_[node_id].file_source_ids.remove(file_source_id); @@ -305,6 +312,10 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source }, [&](const FileSourceAppConfig &source) { send_closure_later(G()->config_manager(), &ConfigManager::reget_app_config, std::move(promise)); + }, + [&](const FileSourceSavedRingtones &source) { + send_closure_later(G()->notification_settings_manager(), &NotificationSettingsManager::repair_saved_ringtones, + std::move(promise)); })); } diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index 1b581dc4c..986fe0212 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -52,6 +52,7 @@ class FileReferenceManager final : public Actor { FileSourceId create_chat_full_file_source(ChatId chat_id); FileSourceId create_channel_full_file_source(ChannelId channel_id); FileSourceId create_app_config_file_source(); + FileSourceId create_saved_ringtones_file_source(); using NodeId = FileId; void repair_file_reference(NodeId node_id, Promise<> promise); @@ -144,12 +145,15 @@ class FileReferenceManager final : public Actor { struct FileSourceAppConfig { // empty }; + struct FileSourceSavedRingtones { + // empty + }; // append only - using FileSource = - Variant; + using FileSource = Variant; vector file_sources_; int64 query_generation_{0}; diff --git a/td/telegram/FileReferenceManager.hpp b/td/telegram/FileReferenceManager.hpp index f0b5ea214..fc533955a 100644 --- a/td/telegram/FileReferenceManager.hpp +++ b/td/telegram/FileReferenceManager.hpp @@ -15,6 +15,7 @@ #include "td/telegram/files/FileSourceId.h" #include "td/telegram/FullMessageId.h" #include "td/telegram/MessagesManager.h" +#include "td/telegram/NotificationSettingsManager.h" #include "td/telegram/StickersManager.h" #include "td/telegram/Td.h" #include "td/telegram/UserId.h" @@ -50,7 +51,7 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer }, [&](const FileSourceChatFull &source) { td::store(source.chat_id, storer); }, [&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); }, - [&](const FileSourceAppConfig &source) {})); + [&](const FileSourceAppConfig &source) {}, [&](const FileSourceSavedRingtones &source) {})); } template @@ -114,6 +115,8 @@ FileSourceId FileReferenceManager::parse_file_source(Td *td, ParserT &parser) { } case 12: return td->stickers_manager_->get_app_config_file_source_id(); + case 13: + return td->notification_settings_manager_->get_saved_ringtones_file_source_id(); default: parser.set_error("Invalid type in FileSource"); return FileSourceId(); diff --git a/td/telegram/NotificationSettingsManager.cpp b/td/telegram/NotificationSettingsManager.cpp index 3c966cf7d..ca7bd9dc8 100644 --- a/td/telegram/NotificationSettingsManager.cpp +++ b/td/telegram/NotificationSettingsManager.cpp @@ -53,7 +53,7 @@ class UploadRingtoneQuery final : public Td::ResultHandler { file_id_ = file_id; send_query(G()->net_query_creator().create( - telegram_api::account_uploadRingtone(std::move(input_file), file_name, mime_type))); + telegram_api::account_uploadRingtone(std::move(input_file), file_name, mime_type), {{"ringtone"}})); } void on_result(BufferSlice packet) final { @@ -1052,6 +1052,7 @@ void NotificationSettingsManager::on_remove_saved_ringtone(int64 ringtone_id, Pr CHECK(file_view.has_remote_location()); if (file_view.remote_location().get_id() == ringtone_id) { saved_ringtone_file_ids_.erase(it); + on_saved_ringtones_updated(false); break; } } @@ -1078,38 +1079,64 @@ Result NotificationSettingsManager::get_ringtone( void NotificationSettingsManager::reload_saved_ringtones(Promise &&promise) { if (!is_active()) { - return; + return promise.set_error(Status::Error(400, "Don't need to reload saved notification sounds")); } - reload_saved_ringtone_queries_.push_back(std::move(promise)); - if (reload_saved_ringtone_queries_.size() == 1) { + reload_saved_ringtones_queries_.push_back(std::move(promise)); + if (reload_saved_ringtones_queries_.size() == 1) { auto query_promise = PromiseCreator::lambda( [actor_id = actor_id(this)](Result> &&result) { - send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, std::move(result)); + send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, false, std::move(result)); }); td_->create_handler(std::move(query_promise))->send(saved_ringtone_hash_); } } +void NotificationSettingsManager::repair_saved_ringtones(Promise &&promise) { + if (!is_active()) { + return promise.set_error(Status::Error(400, "Don't need to repair saved notification sounds")); + } + + repair_saved_ringtones_queries_.push_back(std::move(promise)); + if (repair_saved_ringtones_queries_.size() == 1u) { + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this)](Result> &&result) { + send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, true, std::move(result)); + }); + td_->create_handler(std::move(query_promise))->send(0); + } +} + void NotificationSettingsManager::on_reload_saved_ringtones( - Result> &&result) { + bool is_repair, Result> &&result) { if (!is_active()) { are_saved_ringtones_loaded_ = true; - set_promises(reload_saved_ringtone_queries_); + set_promises(reload_saved_ringtones_queries_); + set_promises(repair_saved_ringtones_queries_); return; } if (result.is_error()) { - fail_promises(reload_saved_ringtone_queries_, result.move_as_error()); - set_timeout_in(Random::fast(60, 120)); + if (is_repair) { + fail_promises(repair_saved_ringtones_queries_, result.move_as_error()); + } else { + fail_promises(reload_saved_ringtones_queries_, result.move_as_error()); + set_timeout_in(Random::fast(60, 120)); + } return; } - set_timeout_in(Random::fast(3600, 4800)); + if (!is_repair) { + set_timeout_in(Random::fast(3600, 4800)); + } auto saved_ringtones_ptr = result.move_as_ok(); auto constructor_id = saved_ringtones_ptr->get_id(); if (constructor_id == telegram_api::account_savedRingtonesNotModified::ID) { - are_saved_ringtones_loaded_ = true; - set_promises(reload_saved_ringtone_queries_); + if (is_repair) { + fail_promises(repair_saved_ringtones_queries_, Status::Error(500, "Failed to repair saved animations")); + } else { + are_saved_ringtones_loaded_ = true; + set_promises(reload_saved_ringtones_queries_); + } return; } CHECK(constructor_id == telegram_api::account_savedRingtones::ID); @@ -1130,12 +1157,42 @@ void NotificationSettingsManager::on_reload_saved_ringtones( } bool need_update = new_saved_ringtone_file_ids != saved_ringtone_file_ids_; + are_saved_ringtones_loaded_ = true; if (need_update || saved_ringtone_hash_ != new_hash) { saved_ringtone_hash_ = new_hash; saved_ringtone_file_ids_ = std::move(new_saved_ringtone_file_ids); + + if (need_update) { + on_saved_ringtones_updated(false); + } } - are_saved_ringtones_loaded_ = true; - set_promises(reload_saved_ringtone_queries_); + if (is_repair) { + set_promises(repair_saved_ringtones_queries_); + } else { + set_promises(reload_saved_ringtones_queries_); + } +} + +void NotificationSettingsManager::on_saved_ringtones_updated(bool from_database) { + CHECK(are_saved_ringtones_loaded_); + vector new_sorted_saved_ringtone_file_ids = saved_ringtone_file_ids_; + std::sort(new_sorted_saved_ringtone_file_ids.begin(), new_sorted_saved_ringtone_file_ids.end()); + if (new_sorted_saved_ringtone_file_ids != sorted_saved_ringtone_file_ids_) { + td_->file_manager_->change_files_source(get_saved_ringtones_file_source_id(), sorted_saved_ringtone_file_ids_, + new_sorted_saved_ringtone_file_ids); + sorted_saved_ringtone_file_ids_ = std::move(new_sorted_saved_ringtone_file_ids); + } + + if (!from_database) { + // save_saved_ringtones_to_database(); + } +} + +FileSourceId NotificationSettingsManager::get_saved_ringtones_file_source_id() { + if (!saved_ringtones_file_source_id_.is_valid()) { + saved_ringtones_file_source_id_ = td_->file_reference_manager_->create_saved_ringtones_file_source(); + } + return saved_ringtones_file_source_id_; } void NotificationSettingsManager::send_get_dialog_notification_settings_query(DialogId dialog_id, diff --git a/td/telegram/NotificationSettingsManager.h b/td/telegram/NotificationSettingsManager.h index 75437bc7e..a15f2c8e6 100644 --- a/td/telegram/NotificationSettingsManager.h +++ b/td/telegram/NotificationSettingsManager.h @@ -8,6 +8,7 @@ #include "td/telegram/DialogId.h" #include "td/telegram/files/FileId.h" +#include "td/telegram/files/FileSourceId.h" #include "td/telegram/NotificationSettings.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" @@ -59,6 +60,10 @@ class NotificationSettingsManager final : public Actor { void reload_saved_ringtones(Promise &&promise); + void repair_saved_ringtones(Promise &&promise); + + FileSourceId get_saved_ringtones_file_source_id(); + void send_save_ringtone_query(FileId ringtone_file_id, bool unsave, Promise> &&promise); @@ -125,7 +130,10 @@ class NotificationSettingsManager final : public Actor { void on_remove_saved_ringtone(int64 ringtone_id, Promise &&promise); - void on_reload_saved_ringtones(Result> &&result); + void on_reload_saved_ringtones(bool is_repair, + Result> &&result); + + void on_saved_ringtones_updated(bool from_database); ScopeNotificationSettings *get_scope_notification_settings(NotificationSettingsScope scope); @@ -167,6 +175,8 @@ class NotificationSettingsManager final : public Actor { int64 saved_ringtone_hash_ = 0; vector saved_ringtone_file_ids_; + vector sorted_saved_ringtone_file_ids_; + FileSourceId saved_ringtones_file_source_id_; std::shared_ptr upload_ringtone_callback_; @@ -180,7 +190,8 @@ class NotificationSettingsManager final : public Actor { }; FlatHashMap being_uploaded_ringtones_; - vector> reload_saved_ringtone_queries_; + vector> reload_saved_ringtones_queries_; + vector> repair_saved_ringtones_queries_; FlatHashMap>, DialogIdHash> get_dialog_notification_settings_queries_; };