diff --git a/td/telegram/AnimationsManager.cpp b/td/telegram/AnimationsManager.cpp index 0075615b..c7ed56a7 100644 --- a/td/telegram/AnimationsManager.cpp +++ b/td/telegram/AnimationsManager.cpp @@ -38,11 +38,11 @@ namespace td { class GetSavedGifsQuery : public Td::ResultHandler { - bool is_reload_ = false; + bool is_repair_ = false; public: - void send(bool is_reload, int32 hash) { - is_reload_ = is_reload; + void send(bool is_repair, int32 hash) { + is_repair_ = is_repair; LOG(INFO) << "Send get saved animations request with hash = " << hash; send_query(G()->net_query_creator().create(create_storer(telegram_api::messages_getSavedGifs(hash)))); } @@ -54,12 +54,12 @@ class GetSavedGifsQuery : public Td::ResultHandler { } auto ptr = result_ptr.move_as_ok(); - td->animations_manager_->on_get_saved_animations(is_reload_, std::move(ptr)); + td->animations_manager_->on_get_saved_animations(is_repair_, std::move(ptr)); } void on_error(uint64 id, Status status) override { LOG(ERROR) << "Receive error for get saved animations: " << status; - td->animations_manager_->on_get_saved_animations_failed(is_reload_, std::move(status)); + td->animations_manager_->on_get_saved_animations_failed(is_repair_, std::move(status)); } }; @@ -436,13 +436,13 @@ void AnimationsManager::reload_saved_animations(bool force) { } } -void AnimationsManager::reload_saved_animations_force(Promise &&promise) { +void AnimationsManager::repair_saved_animations(Promise &&promise) { if (td_->auth_manager_->is_bot()) { return promise.set_error(Status::Error(400, "Bots has no saved animations")); } - reload_saved_animations_queries_.push_back(std::move(promise)); - if (reload_saved_animations_queries_.size() == 1u) { + repair_saved_animations_queries_.push_back(std::move(promise)); + if (repair_saved_animations_queries_.size() == 1u) { td_->create_handler()->send(true, 0); } } @@ -512,16 +512,16 @@ void AnimationsManager::on_load_saved_animations_finished(vector &&saved } void AnimationsManager::on_get_saved_animations( - bool is_reload, tl_object_ptr &&saved_animations_ptr) { + bool is_repair, tl_object_ptr &&saved_animations_ptr) { CHECK(!td_->auth_manager_->is_bot()); - if (!is_reload) { + if (!is_repair) { next_saved_animations_load_time_ = Time::now_cached() + Random::fast(30 * 60, 50 * 60); } CHECK(saved_animations_ptr != nullptr); int32 constructor_id = saved_animations_ptr->get_id(); if (constructor_id == telegram_api::messages_savedGifsNotModified::ID) { - if (is_reload) { + if (is_repair) { return on_get_saved_animations_failed(true, Status::Error(500, "Failed to reload saved animations")); } LOG(INFO) << "Saved animations are not modified"; @@ -546,14 +546,14 @@ void AnimationsManager::on_get_saved_animations( LOG(ERROR) << "Receive " << static_cast(document.first) << " instead of animation as saved animation"; continue; } - if (!is_reload) { + if (!is_repair) { saved_animation_ids.push_back(document.second); } } - if (is_reload) { - auto promises = std::move(reload_saved_animations_queries_); - reload_saved_animations_queries_.clear(); + if (is_repair) { + auto promises = std::move(repair_saved_animations_queries_); + repair_saved_animations_queries_.clear(); for (auto &promise : promises) { promise.set_value(Unit()); } @@ -566,12 +566,12 @@ void AnimationsManager::on_get_saved_animations( } } -void AnimationsManager::on_get_saved_animations_failed(bool is_reload, Status error) { +void AnimationsManager::on_get_saved_animations_failed(bool is_repair, Status error) { CHECK(error.is_error()); - if (!is_reload) { + if (!is_repair) { next_saved_animations_load_time_ = Time::now_cached() + Random::fast(5, 10); } - auto &queries = is_reload ? reload_saved_animations_queries_ : load_saved_animations_queries_; + auto &queries = is_repair ? repair_saved_animations_queries_ : load_saved_animations_queries_; auto promises = std::move(queries); queries.clear(); for (auto &promise : promises) { diff --git a/td/telegram/AnimationsManager.h b/td/telegram/AnimationsManager.h index 7f12ca6d..4dec1a83 100644 --- a/td/telegram/AnimationsManager.h +++ b/td/telegram/AnimationsManager.h @@ -60,11 +60,11 @@ class AnimationsManager : public Actor { void reload_saved_animations(bool force); - void reload_saved_animations_force(Promise &&promise); + void repair_saved_animations(Promise &&promise); - void on_get_saved_animations(bool is_reload, tl_object_ptr &&saved_animations_ptr); + void on_get_saved_animations(bool is_repair, tl_object_ptr &&saved_animations_ptr); - void on_get_saved_animations_failed(bool is_reload, Status error); + void on_get_saved_animations_failed(bool is_repair, Status error); vector get_saved_animations(Promise &&promise); @@ -141,7 +141,7 @@ class AnimationsManager : public Actor { double next_saved_animations_load_time_ = 0; bool are_saved_animations_loaded_ = false; vector> load_saved_animations_queries_; - vector> reload_saved_animations_queries_; + vector> repair_saved_animations_queries_; FileSourceId saved_animations_file_source_id_; }; diff --git a/td/telegram/FileReferenceManager.cpp b/td/telegram/FileReferenceManager.cpp index 61e8186d..375355f2 100644 --- a/td/telegram/FileReferenceManager.cpp +++ b/td/telegram/FileReferenceManager.cpp @@ -36,6 +36,7 @@ fileSourceWebPage url:string = FileSource; // repair fileSourceWallpapers = FileSource; // repaired with account.getWallPapers fileSourceSavedAnimations = FileSource; // repaired with messages.getSavedGifs fileSourceRecentStickers is_attached:Bool = FileSource; // repaired with messages.getRecentStickers, not reliable +fileSourceFavoriteStickers = FileSource; // repaired with messages.getFavedStickers, not reliable */ FileSourceId FileReferenceManager::get_current_file_source_id() const { @@ -90,6 +91,11 @@ FileSourceId FileReferenceManager::create_recent_stickers_file_source(bool is_at return add_file_source_id(source, PSLICE() << "recent " << (is_attached ? "attached " : "") << "stickers"); } +FileSourceId FileReferenceManager::create_favorite_stickers_file_source() { + FileSourceFavoriteStickers source; + return add_file_source_id(source, PSLICE() << "favorite stickers"); +} + bool FileReferenceManager::add_file_source(NodeId node_id, FileSourceId file_source_id) { VLOG(file_references) << "Add " << file_source_id << " for file " << node_id; return nodes_[node_id].file_source_ids.add(file_source_id); @@ -234,12 +240,14 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source std::move(promise)); }, [&](const FileSourceSavedAnimations &source) { - send_closure_later(G()->animations_manager(), &AnimationsManager::reload_saved_animations_force, - std::move(promise)); + send_closure_later(G()->animations_manager(), &AnimationsManager::repair_saved_animations, std::move(promise)); }, [&](const FileSourceRecentStickers &source) { - send_closure_later(G()->stickers_manager(), &StickersManager::reload_recent_stickers_force, source.is_attached, + send_closure_later(G()->stickers_manager(), &StickersManager::repair_recent_stickers, source.is_attached, std::move(promise)); + }, + [&](const FileSourceFavoriteStickers &source) { + send_closure_later(G()->stickers_manager(), &StickersManager::repair_favorite_stickers, std::move(promise)); })); } diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index ec4c6b9a..43df6516 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -42,6 +42,7 @@ class FileReferenceManager : public Actor { FileSourceId create_web_page_file_source(string url); FileSourceId create_saved_animations_file_source(); FileSourceId create_recent_stickers_file_source(bool is_attached); + FileSourceId create_favorite_stickers_file_source(); using NodeId = FileId; void repair_file_reference(NodeId node_id, Promise<> promise); @@ -105,11 +106,12 @@ class FileReferenceManager : public Actor { struct FileSourceRecentStickers { bool is_attached; }; + struct FileSourceFavoriteStickers {}; // append only using FileSource = Variant; + FileSourceWebPage, FileSourceSavedAnimations, FileSourceRecentStickers, FileSourceFavoriteStickers>; vector file_sources_; int64 query_generation_{0}; diff --git a/td/telegram/FileReferenceManager.hpp b/td/telegram/FileReferenceManager.hpp index 939fabcc..b0705485 100644 --- a/td/telegram/FileReferenceManager.hpp +++ b/td/telegram/FileReferenceManager.hpp @@ -41,7 +41,8 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer [&](const FileSourceWallpapers &source) {}, [&](const FileSourceWebPage &source) { td::store(source.url, storer); }, [&](const FileSourceSavedAnimations &source) {}, - [&](const FileSourceRecentStickers &source) { td::store(source.is_attached, storer); })); + [&](const FileSourceRecentStickers &source) { td::store(source.is_attached, storer); }, + [&](const FileSourceFavoriteStickers &source) {})); } template @@ -84,6 +85,8 @@ FileSourceId FileReferenceManager::parse_file_source(Td *td, ParserT &parser) { td::parse(is_attached, parser); return td->stickers_manager_->get_recent_stickers_file_source_id(is_attached); } + case 8: + return td->stickers_manager_->get_favorite_stickers_file_source_id(); default: parser.set_error("Invalid type in FileSource"); return FileSourceId(); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 837d348f..c6c24095 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -220,12 +220,12 @@ class GetAttachedStickerSetsQuery : public Td::ResultHandler { }; class GetRecentStickersQuery : public Td::ResultHandler { - bool is_reload_ = false; + bool is_repair_ = false; bool is_attached_ = false; public: - void send(bool is_reload, bool is_attached, int32 hash) { - is_reload_ = is_reload; + void send(bool is_repair, bool is_attached, int32 hash) { + is_repair_ = is_repair; is_attached_ = is_attached; int32 flags = 0; if (is_attached) { @@ -245,12 +245,12 @@ class GetRecentStickersQuery : public Td::ResultHandler { auto ptr = result_ptr.move_as_ok(); LOG(DEBUG) << "Receive result for get recent " << (is_attached_ ? "attached " : "") << "stickers: " << to_string(ptr); - td->stickers_manager_->on_get_recent_stickers(is_reload_, is_attached_, std::move(ptr)); + td->stickers_manager_->on_get_recent_stickers(is_repair_, is_attached_, std::move(ptr)); } void on_error(uint64 id, Status status) override { LOG(ERROR) << "Receive error for get recent " << (is_attached_ ? "attached " : "") << "stickers: " << status; - td->stickers_manager_->on_get_recent_stickers_failed(is_reload_, is_attached_, std::move(status)); + td->stickers_manager_->on_get_recent_stickers_failed(is_repair_, is_attached_, std::move(status)); } }; @@ -339,8 +339,11 @@ class ClearRecentStickersQuery : public Td::ResultHandler { }; class GetFavedStickersQuery : public Td::ResultHandler { + bool is_repair_ = false; + public: - void send(int32 hash) { + void send(bool is_repair, int32 hash) { + is_repair_ = is_repair; LOG(INFO) << "Send get favorite stickers request with hash = " << hash; send_query(G()->net_query_creator().create(create_storer(telegram_api::messages_getFavedStickers(hash)))); } @@ -352,12 +355,12 @@ class GetFavedStickersQuery : public Td::ResultHandler { } auto ptr = result_ptr.move_as_ok(); - td->stickers_manager_->on_get_favorite_stickers(std::move(ptr)); + td->stickers_manager_->on_get_favorite_stickers(is_repair_, std::move(ptr)); } void on_error(uint64 id, Status status) override { LOG(ERROR) << "Receive error for get favorite stickers: " << status; - td->stickers_manager_->on_get_favorite_stickers_failed(std::move(status)); + td->stickers_manager_->on_get_favorite_stickers_failed(is_repair_, std::move(status)); } }; @@ -3624,13 +3627,13 @@ void StickersManager::reload_recent_stickers(bool is_attached, bool force) { } } -void StickersManager::reload_recent_stickers_force(bool is_attached, Promise &&promise) { +void StickersManager::repair_recent_stickers(bool is_attached, Promise &&promise) { if (td_->auth_manager_->is_bot()) { return promise.set_error(Status::Error(400, "Bots has no recent stickers")); } - reload_recent_stickers_queries_[is_attached].push_back(std::move(promise)); - if (reload_recent_stickers_queries_[is_attached].size() == 1u) { + repair_recent_stickers_queries_[is_attached].push_back(std::move(promise)); + if (repair_recent_stickers_queries_[is_attached].size() == 1u) { td_->create_handler()->send(true, is_attached, 0); } } @@ -3702,17 +3705,17 @@ void StickersManager::on_load_recent_stickers_finished(bool is_attached, vector< } } -void StickersManager::on_get_recent_stickers(bool is_reload, bool is_attached, +void StickersManager::on_get_recent_stickers(bool is_repair, bool is_attached, tl_object_ptr &&stickers_ptr) { CHECK(!td_->auth_manager_->is_bot()); - if (!is_reload) { + if (!is_repair) { next_recent_stickers_load_time_[is_attached] = Time::now_cached() + Random::fast(30 * 60, 50 * 60); } CHECK(stickers_ptr != nullptr); int32 constructor_id = stickers_ptr->get_id(); if (constructor_id == telegram_api::messages_recentStickersNotModified::ID) { - if (is_reload) { + if (is_repair) { return on_get_recent_stickers_failed(true, is_attached, Status::Error(500, "Failed to reload recent stickers")); } LOG(INFO) << (is_attached ? "Attached r" : "R") << "ecent stickers are not modified"; @@ -3731,9 +3734,9 @@ void StickersManager::on_get_recent_stickers(bool is_reload, bool is_attached, recent_sticker_ids.push_back(sticker_id); } - if (is_reload) { - auto promises = std::move(reload_recent_stickers_queries_[is_attached]); - reload_recent_stickers_queries_[is_attached].clear(); + if (is_repair) { + auto promises = std::move(repair_recent_stickers_queries_[is_attached]); + repair_recent_stickers_queries_[is_attached].clear(); for (auto &promise : promises) { promise.set_value(Unit()); } @@ -3744,12 +3747,12 @@ void StickersManager::on_get_recent_stickers(bool is_reload, bool is_attached, } } -void StickersManager::on_get_recent_stickers_failed(bool is_reload, bool is_attached, Status error) { +void StickersManager::on_get_recent_stickers_failed(bool is_repair, bool is_attached, Status error) { CHECK(error.is_error()); - if (!is_reload) { + if (!is_repair) { next_recent_stickers_load_time_[is_attached] = Time::now_cached() + Random::fast(5, 10); } - auto &queries = is_reload ? reload_recent_stickers_queries_[is_attached] : load_recent_stickers_queries_[is_attached]; + auto &queries = is_repair ? repair_recent_stickers_queries_[is_attached] : load_recent_stickers_queries_[is_attached]; auto promises = std::move(queries); queries.clear(); for (auto &promise : promises) { @@ -3775,10 +3778,11 @@ int32 StickersManager::get_recent_stickers_hash(const vector &sticker_id } FileSourceId StickersManager::get_recent_stickers_file_source_id(bool is_attached) { - if (!recent_stickers_file_source_id_.is_valid()) { - recent_stickers_file_source_id_ = td_->file_reference_manager_->create_recent_stickers_file_source(is_attached); + if (!recent_stickers_file_source_id_[is_attached].is_valid()) { + recent_stickers_file_source_id_[is_attached] = + td_->file_reference_manager_->create_recent_stickers_file_source(is_attached); } - return recent_stickers_file_source_id_; + return recent_stickers_file_source_id_[is_attached]; } void StickersManager::add_recent_sticker(bool is_attached, const tl_object_ptr &input_file, @@ -3961,15 +3965,15 @@ void StickersManager::send_update_recent_stickers(bool from_database) { if (need_update_recent_stickers_[is_attached]) { need_update_recent_stickers_[is_attached] = false; if (are_recent_stickers_loaded_[is_attached]) { - vector new_recent_sticker_file_ids = recent_sticker_ids_[is_attached]; + vector new_recent_sticker_file_ids; for (auto &sticker_id : recent_sticker_ids_[is_attached]) { append(new_recent_sticker_file_ids, get_sticker_file_ids(sticker_id)); } std::sort(new_recent_sticker_file_ids.begin(), new_recent_sticker_file_ids.end()); - if (new_recent_sticker_file_ids != recent_sticker_file_ids_) { - td_->file_manager_->change_files_source(get_recent_stickers_file_source_id(is_attached), recent_sticker_file_ids_, - new_recent_sticker_file_ids); - recent_sticker_file_ids_ = std::move(new_recent_sticker_file_ids); + if (new_recent_sticker_file_ids != recent_sticker_file_ids_[is_attached]) { + td_->file_manager_->change_files_source(get_recent_stickers_file_source_id(is_attached), + recent_sticker_file_ids_[is_attached], new_recent_sticker_file_ids); + recent_sticker_file_ids_[is_attached] = std::move(new_recent_sticker_file_ids); } recent_stickers_hash_[is_attached] = get_recent_stickers_hash(recent_sticker_ids_[is_attached]); @@ -4029,7 +4033,18 @@ void StickersManager::reload_favorite_stickers(bool force) { (next_favorite_stickers_load_time_ < Time::now() || force)) { LOG_IF(INFO, force) << "Reload favorite stickers"; next_favorite_stickers_load_time_ = -1; - td_->create_handler()->send(get_favorite_stickers_hash()); + td_->create_handler()->send(false, get_favorite_stickers_hash()); + } +} + +void StickersManager::repair_favorite_stickers(Promise &&promise) { + if (td_->auth_manager_->is_bot()) { + return promise.set_error(Status::Error(400, "Bots has no favorite stickers")); + } + + repair_favorite_stickers_queries_.push_back(std::move(promise)); + if (repair_favorite_stickers_queries_.size() == 1u) { + td_->create_handler()->send(true, 0); } } @@ -4098,13 +4113,18 @@ void StickersManager::on_load_favorite_stickers_finished(vector &&favori } void StickersManager::on_get_favorite_stickers( - tl_object_ptr &&favorite_stickers_ptr) { + bool is_repair, tl_object_ptr &&favorite_stickers_ptr) { CHECK(!td_->auth_manager_->is_bot()); - next_favorite_stickers_load_time_ = Time::now_cached() + Random::fast(30 * 60, 50 * 60); + if (!is_repair) { + next_favorite_stickers_load_time_ = Time::now_cached() + Random::fast(30 * 60, 50 * 60); + } CHECK(favorite_stickers_ptr != nullptr); int32 constructor_id = favorite_stickers_ptr->get_id(); if (constructor_id == telegram_api::messages_favedStickersNotModified::ID) { + if (is_repair) { + return on_get_favorite_stickers_failed(true, Status::Error(500, "Failed to reload favorite stickers")); + } LOG(INFO) << "Favorite stickers are not modified"; return; } @@ -4124,16 +4144,27 @@ void StickersManager::on_get_favorite_stickers( favorite_sticker_ids.push_back(sticker_id); } - on_load_favorite_stickers_finished(std::move(favorite_sticker_ids)); + if (is_repair) { + auto promises = std::move(repair_favorite_stickers_queries_); + repair_favorite_stickers_queries_.clear(); + for (auto &promise : promises) { + promise.set_value(Unit()); + } + } else { + on_load_favorite_stickers_finished(std::move(favorite_sticker_ids)); - LOG_IF(ERROR, get_favorite_stickers_hash() != favorite_stickers->hash_) << "Favorite stickers hash mismatch"; + LOG_IF(ERROR, get_favorite_stickers_hash() != favorite_stickers->hash_) << "Favorite stickers hash mismatch"; + } } -void StickersManager::on_get_favorite_stickers_failed(Status error) { +void StickersManager::on_get_favorite_stickers_failed(bool is_repair, Status error) { CHECK(error.is_error()); - next_favorite_stickers_load_time_ = Time::now_cached() + Random::fast(5, 10); - auto promises = std::move(load_favorite_stickers_queries_); - load_favorite_stickers_queries_.clear(); + if (!is_repair) { + next_favorite_stickers_load_time_ = Time::now_cached() + Random::fast(5, 10); + } + auto &queries = is_repair ? repair_favorite_stickers_queries_ : load_favorite_stickers_queries_; + auto promises = std::move(queries); + queries.clear(); for (auto &promise : promises) { promise.set_error(error.clone()); } @@ -4289,6 +4320,17 @@ td_api::object_ptr StickersManager::get_update_f void StickersManager::send_update_favorite_stickers(bool from_database) { if (are_favorite_stickers_loaded_) { + vector new_favorite_sticker_file_ids; + for (auto &sticker_id : favorite_sticker_ids_) { + append(new_favorite_sticker_file_ids, get_sticker_file_ids(sticker_id)); + } + std::sort(new_favorite_sticker_file_ids.begin(), new_favorite_sticker_file_ids.end()); + if (new_favorite_sticker_file_ids != favorite_sticker_file_ids_) { + td_->file_manager_->change_files_source(get_favorite_stickers_file_source_id(), favorite_sticker_file_ids_, + new_favorite_sticker_file_ids); + favorite_sticker_file_ids_ = std::move(new_favorite_sticker_file_ids); + } + send_closure(G()->td(), &Td::send_update, get_update_favorite_stickers_object()); if (!from_database) { diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index d72510ae..f586508a 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -147,10 +147,10 @@ class StickersManager : public Actor { vector get_recent_stickers(bool is_attached, Promise &&promise); - void on_get_recent_stickers(bool is_reload, bool is_attached, + void on_get_recent_stickers(bool is_repair, bool is_attached, tl_object_ptr &&stickers_ptr); - void on_get_recent_stickers_failed(bool is_reload, bool is_attached, Status error); + void on_get_recent_stickers_failed(bool is_repair, bool is_attached, Status error); FileSourceId get_recent_stickers_file_source_id(bool is_attached); @@ -170,9 +170,14 @@ class StickersManager : public Actor { void reload_favorite_stickers(bool force); - void on_get_favorite_stickers(tl_object_ptr &&favorite_stickers_ptr); + void repair_favorite_stickers(Promise &&promise); - void on_get_favorite_stickers_failed(Status error); + void on_get_favorite_stickers(bool is_repair, + tl_object_ptr &&favorite_stickers_ptr); + + void on_get_favorite_stickers_failed(bool is_repair, Status error); + + FileSourceId get_favorite_stickers_file_source_id(); vector get_favorite_stickers(Promise &&promise); @@ -192,7 +197,7 @@ class StickersManager : public Actor { void reload_recent_stickers(bool is_attached, bool force); - void reload_recent_stickers_force(bool is_attached, Promise &&promise); + void repair_recent_stickers(bool is_attached, Promise &&promise); FileId get_sticker_thumbnail_file_id(FileId file_id) const; @@ -491,11 +496,14 @@ class StickersManager : public Actor { vector> load_installed_sticker_sets_queries_[2]; vector> load_featured_sticker_sets_queries_; vector> load_recent_stickers_queries_[2]; - vector> reload_recent_stickers_queries_[2]; + vector> repair_recent_stickers_queries_[2]; vector> load_favorite_stickers_queries_; + vector> repair_favorite_stickers_queries_; - vector recent_sticker_file_ids_; - FileSourceId recent_stickers_file_source_id_; + vector recent_sticker_file_ids_[2]; + FileSourceId recent_stickers_file_source_id_[2]; + vector favorite_sticker_file_ids_; + FileSourceId favorite_stickers_file_source_id_; vector archived_sticker_set_ids_[2]; int32 total_archived_sticker_set_count_[2] = {-1, -1};