Use MessageSender for recent reaction choosers.

This commit is contained in:
levlam 2022-01-21 13:15:27 +03:00
parent 7c4d333a77
commit 05a069d221
5 changed files with 107 additions and 39 deletions

View File

@ -758,8 +758,8 @@ messageReplyInfo reply_count:int32 recent_replier_ids:vector<MessageSender> last
//@reaction Text representation of the reaction
//@choose_count Number of times the reaction was chosen
//@is_chosen True, if the reaction is chosen by the user
//@recent_chooser_user_ids Identifiers of at most 3 recent users, chosen the reaction
messageReaction reaction:string choose_count:int32 is_chosen:Bool recent_chooser_user_ids:vector<int53> = MessageReaction;
//@recent_chooser_ids Identifiers of at most 3 recent message senders, chosen the reaction; available in basic groups and supergroups
messageReaction reaction:string choose_count:int32 is_chosen:Bool recent_chooser_ids:vector<MessageSender> = MessageReaction;
//@description Contains information about interactions with a message
//@view_count Number of times the message was viewed

View File

@ -7,6 +7,7 @@
#include "td/telegram/MessageReaction.h"
#include "td/telegram/ContactsManager.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/Td.h"
#include "td/utils/algorithm.h"
@ -19,12 +20,30 @@ namespace td {
td_api::object_ptr<td_api::messageReaction> MessageReaction::get_message_reaction_object(Td *td) const {
CHECK(!is_empty());
vector<int64> recent_choosers;
for (auto user_id : recent_chooser_user_ids_) {
if (td->contacts_manager_->have_min_user(user_id)) {
recent_choosers.push_back(td->contacts_manager_->get_user_id_object(user_id, "get_message_reaction_object"));
vector<td_api::object_ptr<td_api::MessageSender>> recent_choosers;
for (auto dialog_id : recent_chooser_dialog_ids_) {
auto dialog_type = dialog_id.get_type();
if (dialog_type == DialogType::User) {
auto user_id = dialog_id.get_user_id();
if (td->contacts_manager_->have_min_user(user_id)) {
recent_choosers.push_back(td_api::make_object<td_api::messageSenderUser>(
td->contacts_manager_->get_user_id_object(user_id, "get_message_reaction_object")));
} else {
LOG(ERROR) << "Skip unknown reacted " << user_id;
}
} else {
LOG(ERROR) << "Skip unknown reacted " << user_id;
if (!td->messages_manager_->have_dialog(dialog_id) &&
(td->messages_manager_->have_dialog_info(dialog_id) ||
(dialog_type == DialogType::Channel &&
td->contacts_manager_->have_min_channel(dialog_id.get_channel_id())))) {
LOG(INFO) << "Force creation of " << dialog_id;
td->messages_manager_->force_create_dialog(dialog_id, "get_message_reaction_object", true);
}
if (td->messages_manager_->have_dialog(dialog_id)) {
recent_choosers.push_back(td_api::make_object<td_api::messageSenderChat>(dialog_id.get()));
} else {
LOG(ERROR) << "Skip unknown reacted " << dialog_id;
}
}
}
return td_api::make_object<td_api::messageReaction>(reaction_, choose_count_, is_chosen_, std::move(recent_choosers));
@ -32,13 +51,13 @@ td_api::object_ptr<td_api::messageReaction> 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.recent_chooser_user_ids_ == rhs.recent_chooser_user_ids_;
lhs.recent_chooser_dialog_ids_ == rhs.recent_chooser_dialog_ids_;
}
StringBuilder &operator<<(StringBuilder &string_builder, const MessageReaction &reaction) {
string_builder << '[' << reaction.reaction_ << (reaction.is_chosen_ ? " X " : " x ") << reaction.choose_count_;
if (!reaction.recent_chooser_user_ids_.empty()) {
string_builder << " by " << reaction.recent_chooser_user_ids_;
if (!reaction.recent_chooser_dialog_ids_.empty()) {
string_builder << " by " << reaction.recent_chooser_dialog_ids_;
}
return string_builder << ']';
}
@ -54,6 +73,7 @@ unique_ptr<MessageReactions> MessageReactions::get_message_reactions(
result->is_min_ = reactions->min_;
std::unordered_set<string> reaction_strings;
std::unordered_set<DialogId, DialogIdHash> recent_choosers;
for (auto &reaction_count : reactions->results_) {
if (reaction_count->count_ <= 0 || reaction_count->count_ >= MessageReaction::MAX_CHOOSE_COUNT) {
LOG(ERROR) << "Receive reaction " << reaction_count->reaction_ << " with invalid count "
@ -66,32 +86,51 @@ unique_ptr<MessageReactions> MessageReactions::get_message_reactions(
continue;
}
vector<UserId> recent_chooser_user_ids;
vector<DialogId> recent_chooser_dialog_ids;
vector<std::pair<ChannelId, MinChannel>> recent_chooser_min_channels;
for (auto &user_reaction : reactions->recent_reactons_) {
if (user_reaction->reaction_ == reaction_count->reaction_) {
UserId user_id(user_reaction->user_id_);
if (!user_id.is_valid()) {
LOG(ERROR) << "Receive invalid " << user_id;
DialogId dialog_id(UserId(user_reaction->user_id_));
if (!dialog_id.is_valid()) {
LOG(ERROR) << "Receive invalid " << dialog_id << " as a recent chooser";
continue;
}
if (td::contains(recent_chooser_user_ids, user_id)) {
LOG(ERROR) << "Receive duplicate " << user_id;
if (!recent_choosers.insert(dialog_id).second) {
LOG(ERROR) << "Receive duplicate " << dialog_id << " as a recent chooser";
continue;
}
if (!td->contacts_manager_->have_min_user(user_id)) {
LOG(ERROR) << "Have no info about " << user_id;
continue;
if (!td->messages_manager_->have_dialog_info(dialog_id)) {
auto dialog_type = dialog_id.get_type();
if (dialog_type == DialogType::User) {
auto user_id = dialog_id.get_user_id();
if (!td->contacts_manager_->have_min_user(user_id)) {
LOG(ERROR) << "Have no info about " << user_id;
continue;
}
} else if (dialog_type == DialogType::Channel) {
auto channel_id = dialog_id.get_channel_id();
auto min_channel = td->contacts_manager_->get_min_channel(channel_id);
if (min_channel == nullptr) {
LOG(ERROR) << "Have no info about reacted " << channel_id;
continue;
}
recent_chooser_min_channels.emplace_back(channel_id, *min_channel);
} else {
LOG(ERROR) << "Have no info about reacted " << dialog_id;
continue;
}
}
recent_chooser_user_ids.push_back(user_id);
if (recent_chooser_user_ids.size() == MessageReaction::MAX_RECENT_CHOOSERS) {
recent_chooser_dialog_ids.push_back(dialog_id);
if (recent_chooser_dialog_ids.size() == MessageReaction::MAX_RECENT_CHOOSERS) {
break;
}
}
}
result->reactions_.emplace_back(std::move(reaction_count->reaction_), reaction_count->count_,
reaction_count->chosen_, std::move(recent_chooser_user_ids));
reaction_count->chosen_, std::move(recent_chooser_dialog_ids),
std::move(recent_chooser_min_channels));
}
return result;
}

View File

@ -6,13 +6,17 @@
//
#pragma once
#include "td/telegram/ChannelId.h"
#include "td/telegram/DialogId.h"
#include "td/telegram/MinChannel.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.h"
#include "td/utils/common.h"
#include "td/utils/StringBuilder.h"
#include <utility>
namespace td {
class Td;
@ -21,7 +25,8 @@ class MessageReaction {
string reaction_;
int32 choose_count_ = 0;
bool is_chosen_ = false;
vector<UserId> recent_chooser_user_ids_;
vector<DialogId> recent_chooser_dialog_ids_;
vector<std::pair<ChannelId, MinChannel>> recent_chooser_min_channels_;
friend bool operator==(const MessageReaction &lhs, const MessageReaction &rhs);
@ -33,11 +38,13 @@ class MessageReaction {
MessageReaction() = default;
MessageReaction(string &&reaction, int32 choose_count, bool is_chosen, vector<UserId> &&recent_chooser_user_ids)
MessageReaction(string &&reaction, int32 choose_count, bool is_chosen, vector<DialogId> &&recent_chooser_dialog_ids,
vector<std::pair<ChannelId, MinChannel>> &&recent_chooser_min_channels)
: reaction_(std::move(reaction))
, choose_count_(choose_count)
, is_chosen_(is_chosen)
, recent_chooser_user_ids_(std::move(recent_chooser_user_ids)) {
, recent_chooser_dialog_ids_(std::move(recent_chooser_dialog_ids))
, recent_chooser_min_channels_(std::move(recent_chooser_min_channels)) {
}
bool is_empty() const {
@ -56,8 +63,12 @@ class MessageReaction {
is_chosen_ = is_chosen;
}
const vector<UserId> &get_recent_chooser_user_ids() const {
return recent_chooser_user_ids_;
const vector<DialogId> &get_recent_chooser_dialog_ids() const {
return recent_chooser_dialog_ids_;
}
const vector<std::pair<ChannelId, MinChannel>> &get_recent_chooser_min_channels() const {
return recent_chooser_min_channels_;
}
td_api::object_ptr<td_api::messageReaction> get_message_reaction_object(Td *td) const;

View File

@ -16,29 +16,39 @@ namespace td {
template <class StorerT>
void MessageReaction::store(StorerT &storer) const {
CHECK(!is_empty());
bool has_recent_chooser_user_ids = !recent_chooser_user_ids_.empty();
bool has_recent_chooser_dialog_ids = !recent_chooser_dialog_ids_.empty();
bool has_recent_chooser_min_channels = !recent_chooser_min_channels_.empty();
BEGIN_STORE_FLAGS();
STORE_FLAG(is_chosen_);
STORE_FLAG(has_recent_chooser_user_ids);
STORE_FLAG(has_recent_chooser_dialog_ids);
STORE_FLAG(has_recent_chooser_min_channels);
END_STORE_FLAGS();
td::store(reaction_, storer);
td::store(choose_count_, storer);
if (has_recent_chooser_user_ids) {
td::store(recent_chooser_user_ids_, storer);
if (has_recent_chooser_dialog_ids) {
td::store(recent_chooser_dialog_ids_, storer);
}
if (has_recent_chooser_min_channels) {
td::store(recent_chooser_min_channels_, storer);
}
}
template <class ParserT>
void MessageReaction::parse(ParserT &parser) {
bool has_recent_chooser_user_ids;
bool has_recent_chooser_dialog_ids;
bool has_recent_chooser_min_channels;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(is_chosen_);
PARSE_FLAG(has_recent_chooser_user_ids);
PARSE_FLAG(has_recent_chooser_dialog_ids);
PARSE_FLAG(has_recent_chooser_min_channels);
END_PARSE_FLAGS();
td::parse(reaction_, parser);
td::parse(choose_count_, parser);
if (has_recent_chooser_user_ids) {
td::parse(recent_chooser_user_ids_, parser);
if (has_recent_chooser_dialog_ids) {
td::parse(recent_chooser_dialog_ids_, parser);
}
if (has_recent_chooser_min_channels) {
td::parse(recent_chooser_min_channels_, parser);
}
CHECK(!is_empty());
}

View File

@ -24421,7 +24421,7 @@ void MessagesManager::add_message_dependencies(Dependencies &dependencies, const
add_dialog_and_dependencies(dependencies, m->forward_info->from_dialog_id);
}
for (const auto &replier_min_channel : m->reply_info.replier_min_channels) {
LOG(INFO) << "Add min " << replier_min_channel.first;
LOG(INFO) << "Add min replied " << replier_min_channel.first;
td_->contacts_manager_->add_min_channel(replier_min_channel.first, replier_min_channel.second);
}
for (auto recent_replier_dialog_id : m->reply_info.recent_replier_dialog_ids) {
@ -24431,8 +24431,16 @@ void MessagesManager::add_message_dependencies(Dependencies &dependencies, const
}
if (m->reactions != nullptr) {
for (const auto &reaction : m->reactions->reactions_) {
const auto &user_ids = reaction.get_recent_chooser_user_ids();
dependencies.user_ids.insert(user_ids.begin(), user_ids.end());
for (const auto &recent_chooser_min_channel : reaction.get_recent_chooser_min_channels()) {
LOG(INFO) << "Add min reacted " << recent_chooser_min_channel.first;
td_->contacts_manager_->add_min_channel(recent_chooser_min_channel.first, recent_chooser_min_channel.second);
}
const auto &dialog_ids = reaction.get_recent_chooser_dialog_ids();
for (auto dialog_id : dialog_ids) {
// don't load the dialog itself
// it will be created in get_message_reaction_object if needed
add_dialog_dependencies(dependencies, dialog_id);
}
}
}
add_message_content_dependencies(dependencies, m->content.get());