Save reactions between restarts.

This commit is contained in:
levlam 2022-01-24 16:43:38 +03:00
parent 5daf033e0d
commit 6001485409
3 changed files with 134 additions and 7 deletions

View File

@ -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<td_api::updateReactions> StickersManager::get_update_reaction
return td_api::make_object<td_api::updateReactions>(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<string> 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<telegram_api::messages_AvailableReactions> &&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<telegram_api::messages_availableReactions>(available_reactions_ptr);
vector<Reaction> new_reactions;
vector<string> 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());

View File

@ -451,12 +451,24 @@ class StickersManager final : public Actor {
FileId effect_animation_;
FileId around_animation_;
FileId center_animation_;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
};
struct Reactions {
int32 hash_ = 0;
bool are_being_reloaded_ = false;
vector<Reaction> reactions_;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
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<td_api::updateReactions> get_update_reactions_object() const;
SpecialStickerSet &add_special_sticker_set(const SpecialStickerSetType &type);

View File

@ -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 <class StorerT>
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 <class ParserT>
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 <class StorerT>
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 <class ParserT>
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