diff --git a/td/telegram/MessageReaction.cpp b/td/telegram/MessageReaction.cpp index c810b495a..23b8851e9 100644 --- a/td/telegram/MessageReaction.cpp +++ b/td/telegram/MessageReaction.cpp @@ -176,6 +176,7 @@ class GetMessageReactionsListQuery final : public Td::ResultHandler { } vector> reactions; + FlatHashMap> recent_reactions; for (const auto &reaction : ptr->reactions_) { DialogId dialog_id(reaction->peer_id_); if (!dialog_id.is_valid() || @@ -184,12 +185,21 @@ class GetMessageReactionsListQuery final : public Td::ResultHandler { continue; } + if (offset_.empty()) { + recent_reactions[reaction->reaction_].push_back(dialog_id); + } + auto message_sender = get_min_message_sender_object(td_, dialog_id, "GetMessageReactionsListQuery"); if (message_sender != nullptr) { reactions.push_back(td_api::make_object(reaction->reaction_, std::move(message_sender))); } } + if (offset_.empty()) { + td_->messages_manager_->on_get_message_reaction_list({dialog_id_, message_id_}, reaction_, + std::move(recent_reactions), total_count); + } + promise_.set_value( td_api::make_object(total_count, std::move(reactions), ptr->next_offset_)); } diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 97ec45692..44780d15b 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -6810,6 +6810,60 @@ void MessagesManager::update_message_reactions(FullMessageId full_message_id, update_message_interaction_info(full_message_id, -1, -1, false, nullptr, true, std::move(reactions)); } +void MessagesManager::on_get_message_reaction_list(FullMessageId full_message_id, const string &reaction, + FlatHashMap> reactions, int32 total_count) { + const Message *m = get_message_force(full_message_id, "on_get_message_reaction_list"); + if (m == nullptr || m->reactions == nullptr) { + return; + } + + auto are_consistent = [](const vector &lhs, const vector &rhs) { + size_t i = 0; + size_t max_i = td::min(lhs.size(), rhs.size()); + while (i < max_i && lhs[i] == rhs[i]) { + i++; + } + return i == max_i; + }; + + // it's impossible to use received reactions to update message reactions, because there is no way to find, + // which reaction is chosen by the current user, so just reload message reactions for consistency + bool need_reload = false; + if (reaction.empty()) { + // received list and total_count for all reactions + int32 old_total_count = 0; + for (const auto &message_reaction : m->reactions->reactions_) { + need_reload |= + !are_consistent(reactions[message_reaction.get_reaction()], message_reaction.get_recent_chooser_dialog_ids()); + old_total_count += message_reaction.get_choose_count(); + reactions.erase(message_reaction.get_reaction()); + } + need_reload |= old_total_count != total_count || !reactions.empty(); + } else { + // received list and total_count for a single reaction + const auto *message_reaction = m->reactions->get_reaction(reaction); + if (message_reaction == nullptr) { + need_reload = reactions.count(reaction) != 0 || total_count > 0; + } else { + need_reload = !are_consistent(reactions[reaction], message_reaction->get_recent_chooser_dialog_ids()) || + message_reaction->get_choose_count() != total_count; + } + } + + if (!need_reload) { + return; + } + + LOG(INFO) << "Need reload reactions in " << full_message_id << " for consistency"; + + auto it = pending_reactions_.find(full_message_id); + if (it != pending_reactions_.end()) { + it->second.was_updated = true; + } else { + reload_message_reactions(td_, full_message_id.get_dialog_id(), {full_message_id.get_message_id()}); + } +} + void MessagesManager::on_update_message_interaction_info(FullMessageId full_message_id, int32 view_count, int32 forward_count, bool has_reply_info, tl_object_ptr &&reply_info) { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 99c4aaee3..cd8a35c75 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -341,6 +341,9 @@ class MessagesManager final : public Actor { void update_message_reactions(FullMessageId full_message_id, unique_ptr &&reactions); + void on_get_message_reaction_list(FullMessageId full_message_id, const string &reaction, + FlatHashMap> reactions, int32 total_count); + void on_update_message_interaction_info(FullMessageId full_message_id, int32 view_count, int32 forward_count, bool has_reply_info, tl_object_ptr &&reply_info);