diff --git a/td/telegram/MessageReaction.cpp b/td/telegram/MessageReaction.cpp index 441fc70a8..807aca93d 100644 --- a/td/telegram/MessageReaction.cpp +++ b/td/telegram/MessageReaction.cpp @@ -414,7 +414,7 @@ void MessageReaction::update_recent_chooser_dialog_ids(const MessageReaction &ol recent_chooser_min_channels_ = old_reaction.recent_chooser_min_channels_; } -void MessageReaction::set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool can_get_added_reactions) { +void MessageReaction::set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool have_recent_choosers) { if (is_chosen_ == is_chosen) { return; } @@ -423,7 +423,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 (can_get_added_reactions) { + if (have_recent_choosers) { remove_recent_chooser_dialog_id(chooser_dialog_id); if (is_chosen_) { add_recent_chooser_dialog_id(chooser_dialog_id); @@ -601,6 +601,58 @@ void MessageReactions::update_from(const MessageReactions &old_reactions) { } } +bool MessageReactions::add_reaction(const string &reaction, bool is_big, DialogId chooser_dialog_id, + bool have_recent_choosers) { + bool is_found = false; + for (auto it = reactions_.begin(); it != reactions_.end();) { + auto &message_reaction = *it; + if (message_reaction.is_chosen()) { + if (message_reaction.get_reaction() == reaction && !is_big) { + return false; + } + message_reaction.set_is_chosen(false, chooser_dialog_id, have_recent_choosers); + } + if (message_reaction.get_reaction() == reaction) { + message_reaction.set_is_chosen(true, chooser_dialog_id, have_recent_choosers); + is_found = true; + } + + if (message_reaction.is_empty()) { + it = reactions_.erase(it); + } else { + ++it; + } + } + + if (!is_found) { + return true; + } + + vector recent_chooser_dialog_ids; + if (have_recent_choosers) { + recent_chooser_dialog_ids.push_back(chooser_dialog_id); + } + reactions_.emplace_back(reaction, 1, true, std::move(recent_chooser_dialog_ids), Auto()); + return true; +} + +bool MessageReactions::remove_reaction(const string &reaction, DialogId chooser_dialog_id, bool have_recent_choosers) { + for (auto it = reactions_.begin(); it != reactions_.end(); ++it) { + auto &message_reaction = *it; + if (message_reaction.get_reaction() == reaction) { + if (message_reaction.is_chosen()) { + message_reaction.set_is_chosen(false, chooser_dialog_id, have_recent_choosers); + if (message_reaction.is_empty()) { + it = reactions_.erase(it); + } + return true; + } + break; + } + } + return false; +} + void MessageReactions::sort_reactions(const FlatHashMap &active_reaction_pos) { std::sort(reactions_.begin(), reactions_.end(), [&active_reaction_pos](const MessageReaction &lhs, const MessageReaction &rhs) { diff --git a/td/telegram/MessageReaction.h b/td/telegram/MessageReaction.h index 5e8da9939..e77243e61 100644 --- a/td/telegram/MessageReaction.h +++ b/td/telegram/MessageReaction.h @@ -63,7 +63,7 @@ class MessageReaction { return is_chosen_; } - void set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool can_get_added_reactions); + void set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool have_recent_choosers); int32 get_choose_count() const { return choose_count_; @@ -152,6 +152,10 @@ struct MessageReactions { void update_from(const MessageReactions &old_reactions); + bool add_reaction(const string &reaction, bool is_big, DialogId chooser_dialog_id, bool have_recent_choosers); + + bool remove_reaction(const string &reaction, DialogId chooser_dialog_id, bool have_recent_choosers); + void sort_reactions(const FlatHashMap &active_reaction_pos); void fix_chosen_reaction(DialogId my_dialog_id); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 1335a5d26..d7160663b 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -24526,7 +24526,7 @@ void MessagesManager::add_message_reaction(FullMessageId full_message_id, string return promise.set_error(Status::Error(400, "Chat not found")); } - Message *m = get_message_force(d, full_message_id.get_message_id(), "set_message_reaction"); + Message *m = get_message_force(d, full_message_id.get_message_id(), "add_message_reaction"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } @@ -24535,41 +24535,15 @@ void MessagesManager::add_message_reaction(FullMessageId full_message_id, string return promise.set_error(Status::Error(400, "The reaction isn't available for the message")); } - bool can_get_added_reactions = !is_broadcast_channel(dialog_id) && dialog_id.get_type() != DialogType::User && - !is_discussion_message(dialog_id, m); + bool have_recent_choosers = !is_broadcast_channel(dialog_id) && !is_discussion_message(dialog_id, m); if (m->reactions == nullptr) { m->reactions = make_unique(); - m->reactions->can_get_added_reactions_ = can_get_added_reactions; + m->reactions->can_get_added_reactions_ = have_recent_choosers && dialog_id.get_type() != DialogType::User; m->available_reactions_generation = d->available_reactions_generation; } - bool is_found = false; - for (auto it = m->reactions->reactions_.begin(); it != m->reactions->reactions_.end();) { - auto &message_reaction = *it; - if (message_reaction.is_chosen()) { - if (message_reaction.get_reaction() == reaction && !is_big) { - return promise.set_value(Unit()); - } - message_reaction.set_is_chosen(false, get_my_dialog_id(), can_get_added_reactions); - } - if (message_reaction.get_reaction() == reaction) { - message_reaction.set_is_chosen(true, get_my_dialog_id(), can_get_added_reactions); - is_found = true; - } - - if (message_reaction.is_empty()) { - it = m->reactions->reactions_.erase(it); - } else { - ++it; - } - } - - if (!is_found) { - vector recent_chooser_dialog_ids; - if (!is_broadcast_channel(dialog_id)) { - recent_chooser_dialog_ids.push_back(get_my_dialog_id()); - } - m->reactions->reactions_.emplace_back(reaction, 1, true, std::move(recent_chooser_dialog_ids), Auto()); + if (!m->reactions->add_reaction(reaction, is_big, get_my_dialog_id(), have_recent_choosers)) { + return promise.set_value(Unit()); } set_message_reactions(d, m, is_big, add_to_recent, std::move(promise)); @@ -24582,36 +24556,13 @@ void MessagesManager::remove_message_reaction(FullMessageId full_message_id, str return promise.set_error(Status::Error(400, "Chat not found")); } - Message *m = get_message_force(d, full_message_id.get_message_id(), "set_message_reaction"); + Message *m = get_message_force(d, full_message_id.get_message_id(), "remove_message_reaction"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - bool can_get_added_reactions = !is_broadcast_channel(dialog_id) && dialog_id.get_type() != DialogType::User && - !is_discussion_message(dialog_id, m); - if (m->reactions == nullptr) { - return promise.set_value(Unit()); - } - - bool is_found = false; - for (auto it = m->reactions->reactions_.begin(); it != m->reactions->reactions_.end();) { - auto &message_reaction = *it; - if (message_reaction.get_reaction() == reaction) { - if (message_reaction.is_chosen()) { - message_reaction.set_is_chosen(false, get_my_dialog_id(), can_get_added_reactions); - is_found = true; - } else { - return promise.set_value(Unit()); - } - } - - if (message_reaction.is_empty()) { - it = m->reactions->reactions_.erase(it); - } else { - ++it; - } - } - if (!is_found) { + bool have_recent_choosers = !is_broadcast_channel(dialog_id) && !is_discussion_message(dialog_id, m); + if (m->reactions == nullptr || !m->reactions->remove_reaction(reaction, get_my_dialog_id(), have_recent_choosers)) { return promise.set_value(Unit()); }