diff --git a/td/telegram/MessageReaction.cpp b/td/telegram/MessageReaction.cpp index a8a2d6db8..e297488ea 100644 --- a/td/telegram/MessageReaction.cpp +++ b/td/telegram/MessageReaction.cpp @@ -403,6 +403,8 @@ class ReportReactionQuery final : public Td::ResultHandler { }; void MessageReaction::add_recent_chooser_dialog_id(DialogId dialog_id) { + CHECK(!my_recent_chooser_dialog_id_.is_valid()); + my_recent_chooser_dialog_id_ = dialog_id; recent_chooser_dialog_ids_.insert(recent_chooser_dialog_ids_.begin(), dialog_id); if (recent_chooser_dialog_ids_.size() > MAX_RECENT_CHOOSERS + 1) { LOG(ERROR) << "Have " << recent_chooser_dialog_ids_.size() << " recent reaction choosers"; @@ -410,8 +412,14 @@ void MessageReaction::add_recent_chooser_dialog_id(DialogId dialog_id) { } } -bool MessageReaction::remove_recent_chooser_dialog_id(DialogId dialog_id) { - return td::remove(recent_chooser_dialog_ids_, dialog_id); +bool MessageReaction::remove_recent_chooser_dialog_id() { + if (my_recent_chooser_dialog_id_.is_valid()) { + bool is_removed = td::remove(recent_chooser_dialog_ids_, my_recent_chooser_dialog_id_); + CHECK(is_removed); + my_recent_chooser_dialog_id_ = DialogId(); + return true; + } + return false; } void MessageReaction::update_recent_chooser_dialog_ids(const MessageReaction &old_reaction) { @@ -426,6 +434,7 @@ void MessageReaction::update_recent_chooser_dialog_ids(const MessageReaction &ol return; } } + my_recent_chooser_dialog_id_ = old_reaction.my_recent_chooser_dialog_id_; recent_chooser_dialog_ids_ = old_reaction.recent_chooser_dialog_ids_; recent_chooser_min_channels_ = old_reaction.recent_chooser_min_channels_; } @@ -440,7 +449,7 @@ void MessageReaction::set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, if (chooser_dialog_id.is_valid()) { choose_count_ += is_chosen_ ? 1 : -1; if (have_recent_choosers) { - remove_recent_chooser_dialog_id(chooser_dialog_id); + remove_recent_chooser_dialog_id(); if (is_chosen_) { add_recent_chooser_dialog_id(chooser_dialog_id); } @@ -484,6 +493,7 @@ td_api::object_ptr MessageReaction::get_message_reactio bool operator==(const MessageReaction &lhs, const MessageReaction &rhs) { return lhs.reaction_ == rhs.reaction_ && lhs.choose_count_ == rhs.choose_count_ && lhs.is_chosen_ == rhs.is_chosen_ && + lhs.my_recent_chooser_dialog_id_ == rhs.my_recent_chooser_dialog_id_ && lhs.recent_chooser_dialog_ids_ == rhs.recent_chooser_dialog_ids_; } @@ -538,6 +548,7 @@ unique_ptr MessageReactions::get_message_reactions( continue; } + DialogId my_dialog_id; FlatHashSet recent_choosers; vector recent_chooser_dialog_ids; vector> recent_chooser_min_channels; @@ -574,6 +585,12 @@ unique_ptr MessageReactions::get_message_reactions( continue; } } + if (peer_reaction->my_) { + if (my_dialog_id.is_valid() && dialog_id != my_dialog_id) { + LOG(ERROR) << "Receive my reactions with " << dialog_id << " and " << my_dialog_id; + } + my_dialog_id = dialog_id; + } recent_chooser_dialog_ids.push_back(dialog_id); if (peer_reaction->unread_) { @@ -589,7 +606,7 @@ unique_ptr MessageReactions::get_message_reactions( if (is_chosen) { chosen_reaction_order.emplace_back(reaction_count->chosen_order_, reaction_str); } - result->reactions_.push_back({std::move(reaction_str), reaction_count->count_, is_chosen, + result->reactions_.push_back({std::move(reaction_str), reaction_count->count_, is_chosen, my_dialog_id, std::move(recent_chooser_dialog_ids), std::move(recent_chooser_min_channels)}); } if (chosen_reaction_order.size() > 1) { @@ -654,7 +671,7 @@ bool MessageReactions::add_reaction(const string &reaction, bool is_big, DialogI if (have_recent_choosers) { recent_chooser_dialog_ids.push_back(chooser_dialog_id); } - reactions_.push_back({reaction, 1, true, std::move(recent_chooser_dialog_ids), Auto()}); + reactions_.push_back({reaction, 1, true, chooser_dialog_id, std::move(recent_chooser_dialog_ids), Auto()}); new_chosen_reaction_order.emplace_back(reaction); } else if (!added_reaction->is_chosen()) { added_reaction->set_is_chosen(true, chooser_dialog_id, have_recent_choosers); @@ -738,24 +755,34 @@ void MessageReactions::sort_reactions(const FlatHashMap &active_ }); } -void MessageReactions::fix_chosen_reaction(DialogId my_dialog_id) { - bool need_fix = false; +void MessageReactions::fix_chosen_reaction() { + DialogId my_dialog_id; for (auto &reaction : reactions_) { - if (!reaction.is_chosen() && reaction.remove_recent_chooser_dialog_id(my_dialog_id)) { + if (!reaction.is_chosen() && reaction.get_my_recent_chooser_dialog_id().is_valid()) { + my_dialog_id = reaction.get_my_recent_chooser_dialog_id(); LOG(WARNING) << "Fix recent chosen reaction in " << *this; - need_fix = true; + reaction.remove_recent_chooser_dialog_id(); } } - if (!need_fix) { + if (!my_dialog_id.is_valid()) { return; } for (auto &reaction : reactions_) { - if (reaction.is_chosen() && !td::contains(reaction.get_recent_chooser_dialog_ids(), my_dialog_id)) { + if (reaction.is_chosen() && !reaction.get_my_recent_chooser_dialog_id().is_valid()) { reaction.add_recent_chooser_dialog_id(my_dialog_id); } } } +void MessageReactions::fix_my_recent_chooser_dialog_id(DialogId my_dialog_id) { + for (auto &reaction : reactions_) { + if (reaction.is_chosen() && !reaction.get_my_recent_chooser_dialog_id().is_valid() && + td::contains(reaction.get_recent_chooser_dialog_ids(), my_dialog_id)) { + reaction.my_recent_chooser_dialog_id_ = my_dialog_id; + } + } +} + vector MessageReactions::get_chosen_reactions() const { if (!chosen_reaction_order_.empty()) { return chosen_reaction_order_; diff --git a/td/telegram/MessageReaction.h b/td/telegram/MessageReaction.h index caad4b65b..ac6eff522 100644 --- a/td/telegram/MessageReaction.h +++ b/td/telegram/MessageReaction.h @@ -36,6 +36,7 @@ class MessageReaction { string reaction_; int32 choose_count_ = 0; bool is_chosen_ = false; + DialogId my_recent_chooser_dialog_id_; vector recent_chooser_dialog_ids_; vector> recent_chooser_min_channels_; @@ -45,11 +46,13 @@ class MessageReaction { friend struct MessageReactions; - MessageReaction(string reaction, int32 choose_count, bool is_chosen, vector &&recent_chooser_dialog_ids, + MessageReaction(string reaction, int32 choose_count, bool is_chosen, DialogId my_recent_chooser_dialog_id, + vector &&recent_chooser_dialog_ids, vector> &&recent_chooser_min_channels) : reaction_(std::move(reaction)) , choose_count_(choose_count) , is_chosen_(is_chosen) + , my_recent_chooser_dialog_id_(my_recent_chooser_dialog_id) , recent_chooser_dialog_ids_(std::move(recent_chooser_dialog_ids)) , recent_chooser_min_channels_(std::move(recent_chooser_min_channels)) { } @@ -66,7 +69,7 @@ class MessageReaction { void add_recent_chooser_dialog_id(DialogId dialog_id); - bool remove_recent_chooser_dialog_id(DialogId dialog_id); + bool remove_recent_chooser_dialog_id(); void update_recent_chooser_dialog_ids(const MessageReaction &old_reaction); @@ -74,6 +77,10 @@ class MessageReaction { return choose_count_; } + DialogId get_my_recent_chooser_dialog_id() const { + return my_recent_chooser_dialog_id_; + } + const vector &get_recent_chooser_dialog_ids() const { return recent_chooser_dialog_ids_; } @@ -166,7 +173,9 @@ struct MessageReactions { void sort_reactions(const FlatHashMap &active_reaction_pos); - void fix_chosen_reaction(DialogId my_dialog_id); + void fix_chosen_reaction(); + + void fix_my_recent_chooser_dialog_id(DialogId my_dialog_id); vector get_chosen_reactions() const; diff --git a/td/telegram/MessageReaction.hpp b/td/telegram/MessageReaction.hpp index d92185791..ec2b54580 100644 --- a/td/telegram/MessageReaction.hpp +++ b/td/telegram/MessageReaction.hpp @@ -19,10 +19,12 @@ void MessageReaction::store(StorerT &storer) const { CHECK(!is_empty()); bool has_recent_chooser_dialog_ids = !recent_chooser_dialog_ids_.empty(); bool has_recent_chooser_min_channels = !recent_chooser_min_channels_.empty(); + bool has_my_recent_chooser_dialog_id = my_recent_chooser_dialog_id_.is_valid(); BEGIN_STORE_FLAGS(); STORE_FLAG(is_chosen_); STORE_FLAG(has_recent_chooser_dialog_ids); STORE_FLAG(has_recent_chooser_min_channels); + STORE_FLAG(has_my_recent_chooser_dialog_id); END_STORE_FLAGS(); td::store(reaction_, storer); td::store(choose_count_, storer); @@ -32,16 +34,21 @@ void MessageReaction::store(StorerT &storer) const { if (has_recent_chooser_min_channels) { td::store(recent_chooser_min_channels_, storer); } + if (has_my_recent_chooser_dialog_id) { + td::store(my_recent_chooser_dialog_id_, storer); + } } template void MessageReaction::parse(ParserT &parser) { bool has_recent_chooser_dialog_ids; bool has_recent_chooser_min_channels; + bool has_my_recent_chooser_dialog_id; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_chosen_); PARSE_FLAG(has_recent_chooser_dialog_ids); PARSE_FLAG(has_recent_chooser_min_channels); + PARSE_FLAG(has_my_recent_chooser_dialog_id); END_PARSE_FLAGS(); td::parse(reaction_, parser); td::parse(choose_count_, parser); @@ -51,6 +58,9 @@ void MessageReaction::parse(ParserT &parser) { if (has_recent_chooser_min_channels) { td::parse(recent_chooser_min_channels_, parser); } + if (has_my_recent_chooser_dialog_id) { + td::parse(my_recent_chooser_dialog_id_, parser); + } CHECK(!is_empty()); CHECK(!reaction_.empty()); } diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 9f2797f96..41929b5be 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -7111,11 +7111,7 @@ bool MessagesManager::update_message_interaction_info(Dialog *d, Message *m, int reactions->update_from(*m->reactions); } reactions->sort_reactions(active_reaction_pos_); - reactions->fix_chosen_reaction(get_my_dialog_id()); - if (d->default_send_message_as_dialog_id.is_valid()) { - // the reaction could be set by previous owner of the broadcast - // reactions->fix_chosen_reaction(d->default_send_message_as_dialog_id); - } + reactions->fix_chosen_reaction(); } bool need_update_reactions = has_reactions && MessageReactions::need_update_message_reactions(m->reactions.get(), reactions.get()); @@ -14558,7 +14554,7 @@ std::pair> MessagesManager::creat MessageReactions::get_message_reactions(td_, std::move(message_info.reactions), td_->auth_manager_->is_bot()); if (reactions != nullptr) { reactions->sort_reactions(active_reaction_pos_); - reactions->fix_chosen_reaction(get_my_dialog_id()); + reactions->fix_chosen_reaction(); } bool has_forward_info = message_info.forward_header != nullptr; @@ -23034,6 +23030,9 @@ unique_ptr MessagesManager::parse_message(Dialog *d, M break; } } + if (m->reactions != nullptr) { + m->reactions->fix_my_recent_chooser_dialog_id(get_my_dialog_id()); + } } if (m->contains_mention && td_->auth_manager_->is_bot()) { m->contains_mention = false;