Load top reactions from server.

This commit is contained in:
levlam 2022-09-12 17:28:58 +03:00
parent de1ed3275f
commit 7b6d0ea6b4
5 changed files with 141 additions and 0 deletions

View File

@ -10304,6 +10304,7 @@ void ContactsManager::update_user(User *u, UserId user_id, bool from_binlog, boo
if (td_->option_manager_->get_option_boolean("is_premium") != u->is_premium) {
td_->option_manager_->set_option_boolean("is_premium", u->is_premium);
send_closure(td_->config_manager_, &ConfigManager::request_config, true);
td_->stickers_manager_->reload_top_reactions();
}
}
if (u->is_name_changed || u->is_username_changed || u->is_is_contact_changed) {

View File

@ -21,6 +21,7 @@
#include "td/telegram/LanguagePackManager.h"
#include "td/telegram/logevent/LogEvent.h"
#include "td/telegram/logevent/LogEventHelper.h"
#include "td/telegram/MessageReaction.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/misc.h"
#include "td/telegram/net/DcId.h"
@ -92,6 +93,29 @@ class GetAvailableReactionsQuery final : public Td::ResultHandler {
}
};
class GetTopReactionsQuery final : public Td::ResultHandler {
public:
void send(int64 hash) {
send_query(G()->net_query_creator().create(telegram_api::messages_getTopReactions(50, hash)));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_getTopReactions>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for GetTopReactionsQuery: " << to_string(ptr);
td_->stickers_manager_->on_get_top_reactions(std::move(ptr));
}
void on_error(Status status) final {
LOG(INFO) << "Receive error for GetTopReactionsQuery: " << status;
td_->stickers_manager_->on_get_top_reactions(nullptr);
}
};
class GetAllStickersQuery final : public Td::ResultHandler {
StickerType sticker_type_;
@ -1506,6 +1530,16 @@ void StickersManager::reload_reactions() {
td_->create_handler<GetAvailableReactionsQuery>()->send(reactions_.hash_);
}
void StickersManager::reload_top_reactions() {
if (G()->close_flag() || top_reactions_.is_being_reloaded_) {
return;
}
CHECK(!td_->auth_manager_->is_bot());
top_reactions_.is_being_reloaded_ = true;
load_top_reactions(); // must be after is_being_reloaded_ is set to true to avoid recursion
td_->create_handler<GetTopReactionsQuery>()->send(top_reactions_.hash_);
}
StickersManager::SpecialStickerSet &StickersManager::add_special_sticker_set(const SpecialStickerSetType &type) {
CHECK(!type.is_empty());
auto &result_ptr = special_sticker_sets_[type];
@ -3685,6 +3719,11 @@ void StickersManager::save_reactions() {
G()->td_db()->get_binlog_pmc()->set("reactions", log_event_store(reactions_).as_slice().str());
}
void StickersManager::save_top_reactions() {
LOG(INFO) << "Save top reactions";
G()->td_db()->get_binlog_pmc()->set("top_reactions", log_event_store(top_reactions_).as_slice().str());
}
void StickersManager::load_active_reactions() {
string active_reactions = G()->td_db()->get_binlog_pmc()->get("active_reactions");
if (active_reactions.empty()) {
@ -3732,6 +3771,27 @@ void StickersManager::load_reactions() {
update_active_reactions();
}
void StickersManager::load_top_reactions() {
if (are_top_reactions_loaded_from_database_) {
return;
}
are_top_reactions_loaded_from_database_ = true;
string top_reactions = G()->td_db()->get_binlog_pmc()->get("top_reactions");
if (top_reactions.empty()) {
return reload_top_reactions();
}
auto status = log_event_parse(top_reactions_, top_reactions);
if (status.is_error()) {
LOG(ERROR) << "Can't load top reactions: " << status;
top_reactions_ = {};
return reload_top_reactions();
}
LOG(INFO) << "Successfully loaded " << top_reactions_.reactions_.size() << " top reactions";
}
void StickersManager::update_active_reactions() {
vector<string> active_reactions;
for (auto &reaction : reactions_.reactions_) {
@ -3810,6 +3870,37 @@ void StickersManager::on_get_available_reactions(
update_active_reactions();
}
void StickersManager::on_get_top_reactions(tl_object_ptr<telegram_api::messages_Reactions> &&reactions_ptr) {
CHECK(top_reactions_.is_being_reloaded_);
top_reactions_.is_being_reloaded_ = false;
if (reactions_ptr == nullptr) {
// failed to get top reactions
return;
}
int32 constructor_id = reactions_ptr->get_id();
if (constructor_id == telegram_api::messages_reactionsNotModified::ID) {
LOG(INFO) << "Top reactions are not modified";
return;
}
CHECK(constructor_id == telegram_api::messages_reactions::ID);
auto reactions = move_tl_object_as<telegram_api::messages_reactions>(reactions_ptr);
auto new_reactions =
transform(reactions->reactions_, [](const telegram_api::object_ptr<telegram_api::Reaction> &reaction) {
return get_message_reaction_string(reaction);
});
if (new_reactions == top_reactions_.reactions_ && top_reactions_.hash_ == reactions->hash_) {
LOG(INFO) << "Top reactions are not modified";
return;
}
top_reactions_.reactions_ = std::move(new_reactions);
top_reactions_.hash_ = reactions->hash_;
save_top_reactions();
}
void StickersManager::on_get_installed_sticker_sets(StickerType sticker_type,
tl_object_ptr<telegram_api::messages_AllStickers> &&stickers_ptr) {
auto type = static_cast<int32>(sticker_type);

View File

@ -175,10 +175,14 @@ class StickersManager final : public Actor {
void reload_reactions();
void reload_top_reactions();
void reload_special_sticker_set_by_type(SpecialStickerSetType type, bool is_recursive = false);
void on_get_available_reactions(tl_object_ptr<telegram_api::messages_AvailableReactions> &&available_reactions_ptr);
void on_get_top_reactions(tl_object_ptr<telegram_api::messages_Reactions> &&reactions_ptr);
void on_get_installed_sticker_sets(StickerType sticker_type,
tl_object_ptr<telegram_api::messages_AllStickers> &&stickers_ptr);
@ -551,6 +555,18 @@ class StickersManager final : public Actor {
void parse(ParserT &parser);
};
struct ReactionList {
int64 hash_ = 0;
bool is_being_reloaded_ = false;
vector<string> reactions_;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
};
class CustomEmojiLogEvent;
class StickerListLogEvent;
class StickerSetListLogEvent;
@ -830,10 +846,14 @@ class StickersManager final : public Actor {
void save_reactions();
void save_top_reactions();
void load_active_reactions();
void load_reactions();
void load_top_reactions();
void update_active_reactions();
td_api::object_ptr<td_api::updateActiveEmojiReactions> get_update_active_emoji_reactions_object() const;
@ -1014,7 +1034,11 @@ class StickersManager final : public Actor {
Reactions reactions_;
vector<string> active_reactions_;
ReactionList top_reactions_;
bool are_reactions_loaded_from_database_ = false;
bool are_top_reactions_loaded_from_database_ = false;
FlatHashMap<string, vector<string>> emoji_language_codes_;
FlatHashMap<string, int32> emoji_language_code_versions_;

View File

@ -516,4 +516,28 @@ void StickersManager::Reactions::parse(ParserT &parser) {
}
}
template <class StorerT>
void StickersManager::ReactionList::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::ReactionList::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

View File

@ -1710,6 +1710,7 @@ void UpdatesManager::try_reload_data() {
td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Channel,
Auto());
td_->stickers_manager_->reload_reactions();
td_->stickers_manager_->reload_top_reactions();
for (int32 type = 0; type < MAX_STICKER_TYPE; type++) {
auto sticker_type = static_cast<StickerType>(type);
td_->stickers_manager_->get_installed_sticker_sets(sticker_type, Auto());