Add messageReactions.paid_reactors.

This commit is contained in:
levlam 2024-08-01 23:19:31 +03:00
parent 8044ed83b8
commit 049692dcb8
6 changed files with 70 additions and 14 deletions

View File

@ -1531,8 +1531,11 @@ messageReplyInfo reply_count:int32 recent_replier_ids:vector<MessageSender> last
//@recent_sender_ids Identifiers of at most 3 recent message senders, added the reaction; available in private, basic group and supergroup chats
messageReaction type:ReactionType total_count:int32 is_chosen:Bool used_sender_id:MessageSender recent_sender_ids:vector<MessageSender> = MessageReaction;
//@description Contains a list of reactions added to a message @reactions List of added reactions @are_tags True, if the reactions are tags and Telegram Premium users can filter messages by them
messageReactions reactions:vector<messageReaction> are_tags:Bool = MessageReactions;
//@description Contains a list of reactions added to a message
//@reactions List of added reactions
//@are_tags True, if the reactions are tags and Telegram Premium users can filter messages by them
//@paid_reactors Information about top users that added the paid reaction
messageReactions reactions:vector<messageReaction> are_tags:Bool paid_reactors:vector<paidReactor> = MessageReactions;
//@description Contains information about interactions with a message

View File

@ -502,7 +502,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const UnreadMessageReac
}
unique_ptr<MessageReactions> MessageReactions::get_message_reactions(
Td *td, tl_object_ptr<telegram_api::messageReactions> &&reactions, bool is_bot) {
Td *td, telegram_api::object_ptr<telegram_api::messageReactions> &&reactions, bool is_bot) {
if (reactions == nullptr || is_bot) {
return nullptr;
}
@ -610,6 +610,22 @@ unique_ptr<MessageReactions> MessageReactions::get_message_reactions(
result->chosen_reaction_order_ =
transform(chosen_reaction_order, [](const std::pair<int32, ReactionType> &order) { return order.second; });
}
bool was_me = false;
for (auto &top_reactor : reactions->top_reactors_) {
MessageReactor reactor(std::move(top_reactor));
if (!reactor.is_valid() || (reactions->min_ && reactor.is_me())) {
LOG(ERROR) << "Receive " << reactor;
continue;
}
if (reactor.is_me()) {
if (was_me) {
LOG(ERROR) << "Receive duplicate " << reactor;
continue;
}
was_me = true;
}
result->top_reactors_.push_back(std::move(reactor));
}
return result;
}
@ -650,6 +666,13 @@ void MessageReactions::update_from(const MessageReactions &old_reactions) {
if (chosen_reaction_order_.size() == 1) {
reset_to_empty(chosen_reaction_order_);
}
// self paid reaction was known, keep it
for (auto &reactor : old_reactions.top_reactors_) {
if (reactor.is_me()) {
top_reactors_.push_back(reactor);
}
}
}
for (const auto &old_reaction : old_reactions.reactions_) {
if (old_reaction.is_chosen() &&
@ -758,6 +781,9 @@ bool MessageReactions::do_remove_my_reaction(const ReactionType &reaction_type)
void MessageReactions::sort_reactions(const FlatHashMap<ReactionType, size_t, ReactionTypeHash> &active_reaction_pos) {
std::sort(reactions_.begin(), reactions_.end(),
[&active_reaction_pos](const MessageReaction &lhs, const MessageReaction &rhs) {
if (lhs.get_reaction_type().is_paid_reaction() != rhs.get_reaction_type().is_paid_reaction()) {
return lhs.get_reaction_type().is_paid_reaction();
}
if (lhs.get_choose_count() != rhs.get_choose_count()) {
return lhs.get_choose_count() > rhs.get_choose_count();
}
@ -786,7 +812,8 @@ void MessageReactions::fix_chosen_reaction() {
return;
}
for (auto &reaction : reactions_) {
if (reaction.is_chosen() && !reaction.get_my_recent_chooser_dialog_id().is_valid()) {
if (!reaction.get_reaction_type().is_paid_reaction() && reaction.is_chosen() &&
!reaction.get_my_recent_chooser_dialog_id().is_valid()) {
reaction.add_my_recent_chooser_dialog_id(my_dialog_id);
}
}
@ -794,7 +821,8 @@ void MessageReactions::fix_chosen_reaction() {
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() &&
if (!reaction.get_reaction_type().is_paid_reaction() && 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;
}
@ -808,7 +836,7 @@ vector<ReactionType> MessageReactions::get_chosen_reaction_types() const {
vector<ReactionType> reaction_order;
for (const auto &reaction : reactions_) {
if (reaction.is_chosen()) {
if (!reaction.get_reaction_type().is_paid_reaction() && reaction.is_chosen()) {
reaction_order.push_back(reaction.get_reaction_type());
}
}
@ -857,7 +885,9 @@ td_api::object_ptr<td_api::messageReactions> MessageReactions::get_message_react
auto reactions = transform(reactions_, [td, my_user_id, peer_user_id](const MessageReaction &reaction) {
return reaction.get_message_reaction_object(td, my_user_id, peer_user_id);
});
return td_api::make_object<td_api::messageReactions>(std::move(reactions), are_tags_);
auto reactors =
transform(top_reactors_, [td](const MessageReactor &reactor) { return reactor.get_paid_reactor_object(td); });
return td_api::make_object<td_api::messageReactions>(std::move(reactions), are_tags_, std::move(reactors));
}
void MessageReactions::add_min_channels(Td *td) const {
@ -876,6 +906,9 @@ void MessageReactions::add_dependencies(Dependencies &dependencies) const {
dependencies.add_message_sender_dependencies(dialog_id);
}
}
for (const auto &reactor : top_reactors_) {
reactor.add_dependencies(dependencies);
}
}
bool MessageReactions::need_update_message_reactions(const MessageReactions *old_reactions,
@ -893,7 +926,8 @@ bool MessageReactions::need_update_message_reactions(const MessageReactions *old
return old_reactions->reactions_ != new_reactions->reactions_ || old_reactions->is_min_ != new_reactions->is_min_ ||
old_reactions->can_get_added_reactions_ != new_reactions->can_get_added_reactions_ ||
old_reactions->need_polling_ != new_reactions->need_polling_ ||
old_reactions->are_tags_ != new_reactions->are_tags_;
old_reactions->are_tags_ != new_reactions->are_tags_ ||
old_reactions->top_reactors_ != new_reactions->top_reactors_;
}
bool MessageReactions::need_update_unread_reactions(const MessageReactions *old_reactions,
@ -911,7 +945,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageReactions
return string_builder << (reactions.is_min_ ? "Min" : "") << "MessageReactions{" << reactions.reactions_
<< " with unread " << reactions.unread_reactions_ << ", reaction order "
<< reactions.chosen_reaction_order_
<< " and can_get_added_reactions = " << reactions.can_get_added_reactions_ << '}';
<< " and can_get_added_reactions = " << reactions.can_get_added_reactions_
<< " with paid reactions by " << reactions.top_reactors_ << '}';
}
StringBuilder &operator<<(StringBuilder &string_builder, const unique_ptr<MessageReactions> &reactions) {

View File

@ -10,6 +10,7 @@
#include "td/telegram/DialogId.h"
#include "td/telegram/MessageFullId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/MessageReactor.h"
#include "td/telegram/MinChannel.h"
#include "td/telegram/ReactionType.h"
#include "td/telegram/td_api.h"
@ -153,6 +154,7 @@ struct MessageReactions {
vector<MessageReaction> reactions_;
vector<UnreadMessageReaction> unread_reactions_;
vector<ReactionType> chosen_reaction_order_;
vector<MessageReactor> top_reactors_;
bool is_min_ = false;
bool need_polling_ = true;
bool can_get_added_reactions_ = false;
@ -160,9 +162,8 @@ struct MessageReactions {
MessageReactions() = default;
static unique_ptr<MessageReactions> get_message_reactions(Td *td,
tl_object_ptr<telegram_api::messageReactions> &&reactions,
bool is_bot);
static unique_ptr<MessageReactions> get_message_reactions(
Td *td, telegram_api::object_ptr<telegram_api::messageReactions> &&reactions, bool is_bot);
MessageReaction *get_reaction(const ReactionType &reaction_type);

View File

@ -7,6 +7,8 @@
#pragma once
#include "td/telegram/MessageReaction.h"
#include "td/telegram/MessageReactor.hpp"
#include "td/telegram/MinChannel.hpp"
#include "td/telegram/ReactionType.hpp"
@ -100,6 +102,7 @@ void MessageReactions::store(StorerT &storer) const {
bool has_reactions = !reactions_.empty();
bool has_unread_reactions = !unread_reactions_.empty();
bool has_chosen_reaction_order = !chosen_reaction_order_.empty();
bool has_top_reactors = !top_reactors_.empty();
BEGIN_STORE_FLAGS();
STORE_FLAG(is_min_);
STORE_FLAG(need_polling_);
@ -108,6 +111,7 @@ void MessageReactions::store(StorerT &storer) const {
STORE_FLAG(has_reactions);
STORE_FLAG(has_chosen_reaction_order);
STORE_FLAG(are_tags_);
STORE_FLAG(has_top_reactors);
END_STORE_FLAGS();
if (has_reactions) {
td::store(reactions_, storer);
@ -118,6 +122,9 @@ void MessageReactions::store(StorerT &storer) const {
if (has_chosen_reaction_order) {
td::store(chosen_reaction_order_, storer);
}
if (has_top_reactors) {
td::store(top_reactors_, storer);
}
}
template <class ParserT>
@ -125,6 +132,7 @@ void MessageReactions::parse(ParserT &parser) {
bool has_reactions;
bool has_unread_reactions;
bool has_chosen_reaction_order;
bool has_top_reactors;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(is_min_);
PARSE_FLAG(need_polling_);
@ -133,6 +141,7 @@ void MessageReactions::parse(ParserT &parser) {
PARSE_FLAG(has_reactions);
PARSE_FLAG(has_chosen_reaction_order);
PARSE_FLAG(are_tags_);
PARSE_FLAG(has_top_reactors);
END_PARSE_FLAGS();
if (has_reactions) {
td::parse(reactions_, parser);
@ -143,6 +152,9 @@ void MessageReactions::parse(ParserT &parser) {
if (has_chosen_reaction_order) {
td::parse(chosen_reaction_order_, parser);
}
if (has_top_reactors) {
td::parse(top_reactors_, parser);
}
}
} // namespace td

View File

@ -35,7 +35,8 @@ bool operator==(const MessageReactor &lhs, const MessageReactor &rhs) {
}
StringBuilder &operator<<(StringBuilder &string_builder, const MessageReactor &reactor) {
return string_builder << "PaidReactor[" << reactor.dialog_id_ << " - " << reactor.count_ << ']';
return string_builder << "PaidReactor[" << reactor.dialog_id_ << " - " << reactor.count_
<< (reactor.is_me_ ? " by me" : "") << ']';
}
} // namespace td

View File

@ -36,7 +36,11 @@ class MessageReactor {
explicit MessageReactor(telegram_api::object_ptr<telegram_api::messageReactor> &&reactor);
bool is_valid() const {
return (dialog_id_.is_valid() || (!is_me_ && !is_anonymous_)) && count_ > 0;
return (dialog_id_.is_valid() || (!is_me_ && !is_anonymous_)) && count_ > 0 && (is_top_ || is_me_);
}
bool is_me() const {
return is_me_;
}
td_api::object_ptr<td_api::paidReactor> get_paid_reactor_object(Td *td) const;