From 6001485409bc7bab9f2fdf328a78cf55afd31e29 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 24 Jan 2022 16:43:38 +0300 Subject: [PATCH] Save reactions between restarts. --- td/telegram/StickersManager.cpp | 46 +++++++++++++++++--- td/telegram/StickersManager.h | 18 ++++++++ td/telegram/StickersManager.hpp | 77 +++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 7 deletions(-) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 7324a34b3..f3f7e8ea6 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1309,6 +1309,8 @@ void StickersManager::init() { } send_closure(G()->td(), &Td::send_update, get_update_dice_emojis_object()); + load_reactions(); + on_update_dice_success_values(); on_update_emoji_sounds(); @@ -3149,6 +3151,39 @@ td_api::object_ptr StickersManager::get_update_reaction return td_api::make_object(std::move(reactions)); } +void StickersManager::save_reactions() { + LOG(INFO) << "Save available reactions"; + G()->td_db()->get_binlog_pmc()->set("reactions", log_event_store(reactions_).as_slice().str()); +} + +void StickersManager::load_reactions() { + string reactions = G()->td_db()->get_binlog_pmc()->get("reactions"); + if (reactions.empty()) { + return reload_reactions(); + } + + auto status = log_event_parse(reactions_, reactions); + if (status.is_error()) { + LOG(ERROR) << "Can't load available reactions: " << status; + return reload_reactions(); + } + + LOG(INFO) << "Successfully loaded " << reactions_.reactions_.size() << " available reactions"; + send_closure(G()->td(), &Td::send_update, get_update_reactions_object()); + + update_active_reactions(); +} + +void StickersManager::update_active_reactions() { + vector active_reactions; + for (auto &reaction : reactions_.reactions_) { + if (reaction.is_active_) { + active_reactions.push_back(reaction.reaction_); + } + } + td_->messages_manager_->set_active_reactions(std::move(active_reactions)); +} + void StickersManager::on_get_available_reactions( tl_object_ptr &&available_reactions_ptr) { CHECK(reactions_.are_being_reloaded_); @@ -3168,7 +3203,6 @@ void StickersManager::on_get_available_reactions( CHECK(constructor_id == telegram_api::messages_availableReactions::ID); auto available_reactions = move_tl_object_as(available_reactions_ptr); vector new_reactions; - vector new_active_reactions; for (auto &available_reaction : available_reactions->reactions_) { Reaction reaction; reaction.is_active_ = !available_reaction->inactive_; @@ -3195,16 +3229,15 @@ void StickersManager::on_get_available_reactions( continue; } - if (reaction.is_active_) { - new_active_reactions.push_back(reaction.reaction_); - } new_reactions.push_back(std::move(reaction)); } reactions_.reactions_ = std::move(new_reactions); reactions_.hash_ = available_reactions->hash_; send_closure(G()->td(), &Td::send_update, get_update_reactions_object()); - td_->messages_manager_->set_active_reactions(std::move(new_active_reactions)); + save_reactions(); + + update_active_reactions(); } void StickersManager::on_get_installed_sticker_sets(bool is_masks, @@ -7544,9 +7577,8 @@ void StickersManager::after_get_difference() { if (td_->auth_manager_->is_bot()) { return; } + reload_reactions(); if (td_->is_online()) { - reload_reactions(); - get_installed_sticker_sets(false, Auto()); get_installed_sticker_sets(true, Auto()); get_featured_sticker_sets(0, 1000, Auto()); diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index bd506778e..f4a51c6aa 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -451,12 +451,24 @@ class StickersManager final : public Actor { FileId effect_animation_; FileId around_animation_; FileId center_animation_; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); }; struct Reactions { int32 hash_ = 0; bool are_being_reloaded_ = false; vector reactions_; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); }; class StickerListLogEvent; @@ -678,8 +690,14 @@ class StickersManager final : public Actor { void tear_down() final; + void save_reactions(); + + void load_reactions(); + void reload_reactions(); + void update_active_reactions(); + td_api::object_ptr get_update_reactions_object() const; SpecialStickerSet &add_special_sticker_set(const SpecialStickerSetType &type); diff --git a/td/telegram/StickersManager.hpp b/td/telegram/StickersManager.hpp index 42201a59a..17921857e 100644 --- a/td/telegram/StickersManager.hpp +++ b/td/telegram/StickersManager.hpp @@ -9,9 +9,12 @@ #include "td/telegram/StickersManager.h" #include "td/telegram/files/FileId.hpp" +#include "td/telegram/Global.h" #include "td/telegram/misc.h" #include "td/telegram/Photo.hpp" #include "td/telegram/StickerFormat.h" +#include "td/telegram/StickersManager.h" +#include "td/telegram/Td.h" #include "td/utils/emoji.h" #include "td/utils/logging.h" @@ -364,4 +367,78 @@ void StickersManager::parse_sticker_set_id(StickerSetId &sticker_set_id, ParserT add_sticker_set(sticker_set_id, sticker_set_access_hash); } +template +void StickersManager::Reaction::store(StorerT &storer) const { + StickersManager *stickers_manager = storer.context()->td().get_actor_unsafe()->stickers_manager_.get(); + bool has_around_animation = !around_animation_.empty(); + bool has_center_animation = !center_animation_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_active_); + STORE_FLAG(has_around_animation); + STORE_FLAG(has_center_animation); + END_STORE_FLAGS(); + td::store(reaction_, storer); + td::store(title_, storer); + stickers_manager->store_sticker(static_icon_, false, storer, "Reaction"); + stickers_manager->store_sticker(appear_animation_, false, storer, "Reaction"); + stickers_manager->store_sticker(select_animation_, false, storer, "Reaction"); + stickers_manager->store_sticker(activate_animation_, false, storer, "Reaction"); + stickers_manager->store_sticker(effect_animation_, false, storer, "Reaction"); + if (has_around_animation) { + stickers_manager->store_sticker(around_animation_, false, storer, "Reaction"); + } + if (has_center_animation) { + stickers_manager->store_sticker(center_animation_, false, storer, "Reaction"); + } +} + +template +void StickersManager::Reaction::parse(ParserT &parser) { + StickersManager *stickers_manager = parser.context()->td().get_actor_unsafe()->stickers_manager_.get(); + bool has_around_animation; + bool has_center_animation; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_active_); + PARSE_FLAG(has_around_animation); + PARSE_FLAG(has_center_animation); + END_PARSE_FLAGS(); + td::parse(reaction_, parser); + td::parse(title_, parser); + static_icon_ = stickers_manager->parse_sticker(false, parser); + appear_animation_ = stickers_manager->parse_sticker(false, parser); + select_animation_ = stickers_manager->parse_sticker(false, parser); + activate_animation_ = stickers_manager->parse_sticker(false, parser); + effect_animation_ = stickers_manager->parse_sticker(false, parser); + if (has_around_animation) { + around_animation_ = stickers_manager->parse_sticker(false, parser); + } + if (has_center_animation) { + center_animation_ = stickers_manager->parse_sticker(false, parser); + } +} + +template +void StickersManager::Reactions::store(StorerT &storer) const { + bool has_reactions = !reactions_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_reactions); + END_STORE_FLAGS(); + if (has_reactions) { + td::store(reactions_, storer); + td::store(hash_, storer); + } +} + +template +void StickersManager::Reactions::parse(ParserT &parser) { + bool has_reactions; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_reactions); + END_PARSE_FLAGS(); + if (has_reactions) { + td::parse(reactions_, parser); + td::parse(hash_, parser); + } +} + } // namespace td