Add MessageReactions.
This commit is contained in:
parent
aed0fc247d
commit
739d2b292d
@ -356,6 +356,7 @@ set(TDLIB_SOURCE
|
||||
td/telegram/MessageContentType.cpp
|
||||
td/telegram/MessageEntity.cpp
|
||||
td/telegram/MessageId.cpp
|
||||
td/telegram/MessageReaction.cpp
|
||||
td/telegram/MessageReplyInfo.cpp
|
||||
td/telegram/MessagesDb.cpp
|
||||
td/telegram/MessageSearchFilter.cpp
|
||||
@ -561,6 +562,7 @@ set(TDLIB_SOURCE
|
||||
td/telegram/MessageEntity.h
|
||||
td/telegram/MessageId.h
|
||||
td/telegram/MessageLinkInfo.h
|
||||
td/telegram/MessageReaction.h
|
||||
td/telegram/MessageReplyInfo.h
|
||||
td/telegram/MessageThreadInfo.h
|
||||
td/telegram/MessagesDb.h
|
||||
@ -677,6 +679,7 @@ set(TDLIB_SOURCE
|
||||
td/telegram/Game.hpp
|
||||
td/telegram/InputMessageText.hpp
|
||||
td/telegram/MessageEntity.hpp
|
||||
td/telegram/MessageReaction.hpp
|
||||
td/telegram/MessageReplyInfo.hpp
|
||||
td/telegram/MinChannel.hpp
|
||||
td/telegram/NotificationSettings.hpp
|
||||
|
@ -754,11 +754,19 @@ messageForwardInfo origin:MessageForwardOrigin date:int32 public_service_announc
|
||||
//@last_message_id Identifier of the last reply to the message
|
||||
messageReplyInfo reply_count:int32 recent_replier_ids:vector<MessageSender> last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 last_message_id:int53 = MessageReplyInfo;
|
||||
|
||||
//@description Contains information about a reaction to a message
|
||||
//@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;
|
||||
|
||||
//@description Contains information about interactions with a message
|
||||
//@view_count Number of times the message was viewed
|
||||
//@forward_count Number of times the message was forwarded
|
||||
//@reply_info Information about direct or indirect replies to the message; may be null. Currently, available only in channels with a discussion supergroup and discussion supergroups for messages, which are not replies itself
|
||||
messageInteractionInfo view_count:int32 forward_count:int32 reply_info:messageReplyInfo = MessageInteractionInfo;
|
||||
//@reactions The list of reactions chosen for the message
|
||||
messageInteractionInfo view_count:int32 forward_count:int32 reply_info:messageReplyInfo reactions:vector<messageReaction> = MessageInteractionInfo;
|
||||
|
||||
|
||||
//@class MessageSendingState @description Contains information about the sending state of the message
|
||||
|
@ -3085,7 +3085,7 @@ class GetBroadcastStatsQuery final : public Td::ResultHandler {
|
||||
for (auto &info : result->recent_message_interactions_) {
|
||||
td_->messages_manager_->on_update_message_interaction_info({DialogId(channel_id_), MessageId(info->message_id_)},
|
||||
info->view_count_, info->forward_count_, false,
|
||||
nullptr);
|
||||
nullptr, false, nullptr);
|
||||
}
|
||||
promise_.set_value(std::move(result));
|
||||
}
|
||||
|
143
td/telegram/MessageReaction.cpp
Normal file
143
td/telegram/MessageReaction.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include "td/telegram/MessageReaction.h"
|
||||
|
||||
#include "td/telegram/ContactsManager.h"
|
||||
#include "td/telegram/Td.h"
|
||||
|
||||
#include "td/utils/algorithm.h"
|
||||
#include "td/utils/logging.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
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"));
|
||||
} else {
|
||||
LOG(ERROR) << "Skip unknown reacted " << user_id;
|
||||
}
|
||||
}
|
||||
return td_api::make_object<td_api::messageReaction>(reaction_, choose_count_, is_chosen_, std::move(recent_choosers));
|
||||
}
|
||||
|
||||
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_;
|
||||
}
|
||||
|
||||
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_;
|
||||
}
|
||||
return string_builder << ']';
|
||||
}
|
||||
|
||||
unique_ptr<MessageReactions> MessageReactions::get_message_reactions(
|
||||
Td *td, tl_object_ptr<telegram_api::messageReactions> &&reactions, bool is_bot) {
|
||||
if (reactions == nullptr || is_bot) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto result = make_unique<MessageReactions>();
|
||||
result->can_see_all_choosers_ = reactions->can_see_list_;
|
||||
result->is_min_ = reactions->min_;
|
||||
|
||||
std::unordered_set<string> reaction_strings;
|
||||
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 "
|
||||
<< reaction_count->count_;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!reaction_strings.insert(reaction_count->reaction_).second) {
|
||||
LOG(ERROR) << "Receive duplicate reaction " << reaction_count->reaction_;
|
||||
continue;
|
||||
}
|
||||
|
||||
vector<UserId> recent_chooser_user_ids;
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
if (td::contains(recent_chooser_user_ids, user_id)) {
|
||||
LOG(ERROR) << "Receive duplicate " << user_id;
|
||||
continue;
|
||||
}
|
||||
if (!td->contacts_manager_->have_min_user(user_id)) {
|
||||
LOG(ERROR) << "Have no info about " << user_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
recent_chooser_user_ids.push_back(user_id);
|
||||
if (recent_chooser_user_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));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MessageReactions::update_from(const MessageReactions &old_reactions) {
|
||||
if (old_reactions.has_pending_reaction_) {
|
||||
// we will ignore all updates, received while there is a pending reaction, so there are no reasons to update
|
||||
return;
|
||||
}
|
||||
CHECK(!has_pending_reaction_);
|
||||
|
||||
if (is_min_ && !old_reactions.is_min_) {
|
||||
// chosen reaction was known, keep it
|
||||
is_min_ = false;
|
||||
for (const auto &old_reaction : old_reactions.reactions_) {
|
||||
if (old_reaction.is_chosen()) {
|
||||
for (auto &reaction : reactions_) {
|
||||
if (reaction.get_reaction() == old_reaction.get_reaction()) {
|
||||
reaction.set_is_chosen(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MessageReactions::need_update_message_reactions(const MessageReactions *old_reactions,
|
||||
const MessageReactions *new_reactions) {
|
||||
if (old_reactions == nullptr) {
|
||||
// add reactions
|
||||
return new_reactions != nullptr;
|
||||
}
|
||||
if (old_reactions->has_pending_reaction_) {
|
||||
// ignore all updates, received while there is a pending reaction
|
||||
return false;
|
||||
}
|
||||
if (new_reactions == nullptr) {
|
||||
// remove reactions when they are disabled
|
||||
return true;
|
||||
}
|
||||
|
||||
// has_pending_reaction_ and old_chosen_reaction_ don't affect visible state
|
||||
// compare all other fields
|
||||
return old_reactions->reactions_ != new_reactions->reactions_ || old_reactions->is_min_ != new_reactions->is_min_ ||
|
||||
old_reactions->can_see_all_choosers_ != new_reactions->can_see_all_choosers_ ||
|
||||
old_reactions->need_polling_ != new_reactions->need_polling_;
|
||||
}
|
||||
|
||||
} // namespace td
|
106
td/telegram/MessageReaction.h
Normal file
106
td/telegram/MessageReaction.h
Normal file
@ -0,0 +1,106 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#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"
|
||||
|
||||
namespace td {
|
||||
|
||||
class Td;
|
||||
|
||||
class MessageReaction {
|
||||
string reaction_;
|
||||
int32 choose_count_ = 0;
|
||||
bool is_chosen_ = false;
|
||||
vector<UserId> recent_chooser_user_ids_;
|
||||
|
||||
friend bool operator==(const MessageReaction &lhs, const MessageReaction &rhs);
|
||||
|
||||
friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageReaction &message_reaction);
|
||||
|
||||
public:
|
||||
static constexpr size_t MAX_RECENT_CHOOSERS = 3;
|
||||
static constexpr int32 MAX_CHOOSE_COUNT = 2147483640;
|
||||
|
||||
MessageReaction() = default;
|
||||
|
||||
MessageReaction(string &&reaction, int32 choose_count, bool is_chosen, vector<UserId> &&recent_chooser_user_ids)
|
||||
: reaction_(std::move(reaction))
|
||||
, choose_count_(choose_count)
|
||||
, is_chosen_(is_chosen)
|
||||
, recent_chooser_user_ids_(std::move(recent_chooser_user_ids)) {
|
||||
}
|
||||
|
||||
bool is_empty() const {
|
||||
return choose_count_ <= 0;
|
||||
}
|
||||
|
||||
const string &get_reaction() const {
|
||||
return reaction_;
|
||||
}
|
||||
|
||||
bool is_chosen() const {
|
||||
return is_chosen_;
|
||||
}
|
||||
|
||||
void set_is_chosen(bool is_chosen) {
|
||||
is_chosen_ = is_chosen;
|
||||
}
|
||||
|
||||
const vector<UserId> &get_recent_chooser_user_ids() const {
|
||||
return recent_chooser_user_ids_;
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::messageReaction> get_message_reaction_object(Td *td) const;
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const;
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser);
|
||||
};
|
||||
|
||||
bool operator==(const MessageReaction &lhs, const MessageReaction &rhs);
|
||||
|
||||
inline bool operator!=(const MessageReaction &lhs, const MessageReaction &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
StringBuilder &operator<<(StringBuilder &string_builder, const MessageReaction &message_reaction);
|
||||
|
||||
struct MessageReactions {
|
||||
vector<MessageReaction> reactions_;
|
||||
bool is_min_ = false;
|
||||
bool need_polling_ = true;
|
||||
bool can_see_all_choosers_ = false;
|
||||
bool has_pending_reaction_ = false;
|
||||
string old_chosen_reaction_;
|
||||
|
||||
MessageReactions() = default;
|
||||
|
||||
static unique_ptr<MessageReactions> get_message_reactions(Td *td,
|
||||
tl_object_ptr<telegram_api::messageReactions> &&reactions,
|
||||
bool is_bot);
|
||||
|
||||
void update_from(const MessageReactions &old_reactions);
|
||||
|
||||
static bool need_update_message_reactions(const MessageReactions *old_reactions,
|
||||
const MessageReactions *new_reactions);
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const;
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser);
|
||||
};
|
||||
|
||||
} // namespace td
|
86
td/telegram/MessageReaction.hpp
Normal file
86
td/telegram/MessageReaction.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/telegram/MessageReaction.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
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();
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(is_chosen_);
|
||||
STORE_FLAG(has_recent_chooser_user_ids);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void MessageReaction::parse(ParserT &parser) {
|
||||
bool has_recent_chooser_user_ids;
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(is_chosen_);
|
||||
PARSE_FLAG(has_recent_chooser_user_ids);
|
||||
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);
|
||||
}
|
||||
CHECK(!is_empty());
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void MessageReactions::store(StorerT &storer) const {
|
||||
bool has_reactions = !reactions_.empty();
|
||||
bool has_old_chosen_reaction = !old_chosen_reaction_.empty();
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(is_min_);
|
||||
STORE_FLAG(need_polling_);
|
||||
STORE_FLAG(can_see_all_choosers_);
|
||||
STORE_FLAG(has_pending_reaction_);
|
||||
STORE_FLAG(has_reactions);
|
||||
STORE_FLAG(has_old_chosen_reaction);
|
||||
END_STORE_FLAGS();
|
||||
if (has_reactions) {
|
||||
td::store(reactions_, storer);
|
||||
}
|
||||
if (has_old_chosen_reaction) {
|
||||
td::store(old_chosen_reaction_, storer);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void MessageReactions::parse(ParserT &parser) {
|
||||
bool has_reactions;
|
||||
bool has_old_chosen_reaction;
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(is_min_);
|
||||
PARSE_FLAG(need_polling_);
|
||||
PARSE_FLAG(can_see_all_choosers_);
|
||||
PARSE_FLAG(has_pending_reaction_);
|
||||
PARSE_FLAG(has_reactions);
|
||||
PARSE_FLAG(has_old_chosen_reaction);
|
||||
END_PARSE_FLAGS();
|
||||
if (has_reactions) {
|
||||
td::parse(reactions_, parser);
|
||||
}
|
||||
if (has_old_chosen_reaction) {
|
||||
td::parse(old_chosen_reaction_, parser);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace td
|
@ -33,6 +33,8 @@
|
||||
#include "td/telegram/MessageContent.h"
|
||||
#include "td/telegram/MessageEntity.h"
|
||||
#include "td/telegram/MessageEntity.hpp"
|
||||
#include "td/telegram/MessageReaction.h"
|
||||
#include "td/telegram/MessageReaction.hpp"
|
||||
#include "td/telegram/MessageReplyInfo.hpp"
|
||||
#include "td/telegram/MessagesDb.h"
|
||||
#include "td/telegram/MessageSender.h"
|
||||
@ -1919,7 +1921,7 @@ class GetMessagesViewsQuery final : public Td::ResultHandler {
|
||||
auto view_count = (flags & telegram_api::messageViews::VIEWS_MASK) != 0 ? info->views_ : 0;
|
||||
auto forward_count = (flags & telegram_api::messageViews::FORWARDS_MASK) != 0 ? info->forwards_ : 0;
|
||||
td_->messages_manager_->on_update_message_interaction_info(full_message_id, view_count, forward_count, true,
|
||||
std::move(info->replies_));
|
||||
std::move(info->replies_), false, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4891,6 +4893,7 @@ void MessagesManager::Message::store(StorerT &storer) const {
|
||||
bool has_max_reply_media_timestamp = max_reply_media_timestamp >= 0;
|
||||
bool are_message_media_timestamp_entities_found = true;
|
||||
bool has_flags3 = true;
|
||||
bool has_reactions = reactions != nullptr;
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(is_channel_post);
|
||||
STORE_FLAG(is_outgoing);
|
||||
@ -4961,6 +4964,7 @@ void MessagesManager::Message::store(StorerT &storer) const {
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(noforwards);
|
||||
STORE_FLAG(has_explicit_sender);
|
||||
STORE_FLAG(has_reactions);
|
||||
END_STORE_FLAGS();
|
||||
}
|
||||
|
||||
@ -5079,6 +5083,9 @@ void MessagesManager::Message::store(StorerT &storer) const {
|
||||
if (has_max_reply_media_timestamp) {
|
||||
store(max_reply_media_timestamp, storer);
|
||||
}
|
||||
if (has_reactions) {
|
||||
store(reactions, storer);
|
||||
}
|
||||
}
|
||||
|
||||
// do not forget to resolve message dependencies
|
||||
@ -5122,6 +5129,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
|
||||
bool has_ttl_period = false;
|
||||
bool has_max_reply_media_timestamp = false;
|
||||
bool has_flags3 = false;
|
||||
bool has_reactions = false;
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(is_channel_post);
|
||||
PARSE_FLAG(is_outgoing);
|
||||
@ -5192,6 +5200,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(noforwards);
|
||||
PARSE_FLAG(has_explicit_sender);
|
||||
PARSE_FLAG(has_reactions);
|
||||
END_PARSE_FLAGS();
|
||||
}
|
||||
|
||||
@ -5317,6 +5326,9 @@ void MessagesManager::Message::parse(ParserT &parser) {
|
||||
if (has_max_reply_media_timestamp) {
|
||||
parse(max_reply_media_timestamp, parser);
|
||||
}
|
||||
if (has_reactions) {
|
||||
parse(reactions, parser);
|
||||
}
|
||||
|
||||
CHECK(content != nullptr);
|
||||
is_content_secret |=
|
||||
@ -6787,7 +6799,7 @@ void MessagesManager::on_update_message_view_count(FullMessageId full_message_id
|
||||
LOG(ERROR) << "Receive " << view_count << " views in updateChannelMessageViews for " << full_message_id;
|
||||
return;
|
||||
}
|
||||
update_message_interaction_info(full_message_id, view_count, -1, false, nullptr);
|
||||
update_message_interaction_info(full_message_id, view_count, -1, false, nullptr, false, nullptr);
|
||||
}
|
||||
|
||||
void MessagesManager::on_update_message_forward_count(FullMessageId full_message_id, int32 forward_count) {
|
||||
@ -6795,17 +6807,20 @@ void MessagesManager::on_update_message_forward_count(FullMessageId full_message
|
||||
LOG(ERROR) << "Receive " << forward_count << " forwards in updateChannelMessageForwards for " << full_message_id;
|
||||
return;
|
||||
}
|
||||
update_message_interaction_info(full_message_id, -1, forward_count, false, nullptr);
|
||||
update_message_interaction_info(full_message_id, -1, forward_count, false, nullptr, false, nullptr);
|
||||
}
|
||||
|
||||
void MessagesManager::on_update_message_interaction_info(FullMessageId full_message_id, int32 view_count,
|
||||
int32 forward_count, bool has_reply_info,
|
||||
tl_object_ptr<telegram_api::messageReplies> &&reply_info) {
|
||||
tl_object_ptr<telegram_api::messageReplies> &&reply_info,
|
||||
bool has_reactions,
|
||||
tl_object_ptr<telegram_api::messageReactions> &&reactions) {
|
||||
if (view_count < 0 || forward_count < 0) {
|
||||
LOG(ERROR) << "Receive " << view_count << "/" << forward_count << " interaction counters for " << full_message_id;
|
||||
return;
|
||||
}
|
||||
update_message_interaction_info(full_message_id, view_count, forward_count, has_reply_info, std::move(reply_info));
|
||||
update_message_interaction_info(full_message_id, view_count, forward_count, has_reply_info, std::move(reply_info),
|
||||
has_reactions, std::move(reactions));
|
||||
}
|
||||
|
||||
void MessagesManager::on_pending_message_views_timeout(DialogId dialog_id) {
|
||||
@ -6835,7 +6850,9 @@ void MessagesManager::on_pending_message_views_timeout(DialogId dialog_id) {
|
||||
|
||||
void MessagesManager::update_message_interaction_info(FullMessageId full_message_id, int32 view_count,
|
||||
int32 forward_count, bool has_reply_info,
|
||||
tl_object_ptr<telegram_api::messageReplies> &&reply_info) {
|
||||
tl_object_ptr<telegram_api::messageReplies> &&reply_info,
|
||||
bool has_reactions,
|
||||
tl_object_ptr<telegram_api::messageReactions> &&reactions) {
|
||||
auto dialog_id = full_message_id.get_dialog_id();
|
||||
Dialog *d = get_dialog_force(dialog_id, "update_message_interaction_info");
|
||||
if (d == nullptr) {
|
||||
@ -6863,9 +6880,11 @@ void MessagesManager::update_message_interaction_info(FullMessageId full_message
|
||||
if (new_reply_info.is_empty() && !is_empty_reply_info) {
|
||||
has_reply_info = false;
|
||||
}
|
||||
auto new_reactions = MessageReactions::get_message_reactions(td_, std::move(reactions), td_->auth_manager_->is_bot());
|
||||
|
||||
if (update_message_interaction_info(dialog_id, m, view_count, forward_count, has_reply_info,
|
||||
std::move(new_reply_info), "update_message_interaction_info")) {
|
||||
std::move(new_reply_info), has_reactions, std::move(new_reactions),
|
||||
"update_message_interaction_info")) {
|
||||
on_message_changed(d, m, true, "update_message_interaction_info");
|
||||
}
|
||||
}
|
||||
@ -6916,6 +6935,11 @@ bool MessagesManager::is_visible_message_reply_info(DialogId dialog_id, const Me
|
||||
return is_active_message_reply_info(dialog_id, m->reply_info);
|
||||
}
|
||||
|
||||
bool MessagesManager::is_visible_message_reactions(DialogId dialog_id, const Message *m) const {
|
||||
// TODO hide message reactions if reactions are disabled in the chat
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessagesManager::on_message_reply_info_changed(DialogId dialog_id, const Message *m) const {
|
||||
if (td_->auth_manager_->is_bot()) {
|
||||
return;
|
||||
@ -6929,7 +6953,9 @@ void MessagesManager::on_message_reply_info_changed(DialogId dialog_id, const Me
|
||||
td_api::object_ptr<td_api::messageInteractionInfo> MessagesManager::get_message_interaction_info_object(
|
||||
DialogId dialog_id, const Message *m) const {
|
||||
bool is_visible_reply_info = is_visible_message_reply_info(dialog_id, m);
|
||||
if (m->view_count == 0 && m->forward_count == 0 && !is_visible_reply_info) {
|
||||
bool has_reactions =
|
||||
is_visible_message_reactions(dialog_id, m) && m->reactions != nullptr && !m->reactions->reactions_.empty();
|
||||
if (m->view_count == 0 && m->forward_count == 0 && !is_visible_reply_info && !has_reactions) {
|
||||
return nullptr;
|
||||
}
|
||||
if (m->message_id.is_scheduled() && (m->forward_info == nullptr || is_broadcast_channel(dialog_id))) {
|
||||
@ -6945,12 +6971,21 @@ td_api::object_ptr<td_api::messageInteractionInfo> MessagesManager::get_message_
|
||||
CHECK(reply_info != nullptr);
|
||||
}
|
||||
|
||||
return td_api::make_object<td_api::messageInteractionInfo>(m->view_count, m->forward_count, std::move(reply_info));
|
||||
vector<td_api::object_ptr<td_api::messageReaction>> reactions;
|
||||
if (has_reactions) {
|
||||
reactions = transform(m->reactions->reactions_, [td = td_](const MessageReaction &reaction) {
|
||||
return reaction.get_message_reaction_object(td);
|
||||
});
|
||||
}
|
||||
|
||||
return td_api::make_object<td_api::messageInteractionInfo>(m->view_count, m->forward_count, std::move(reply_info),
|
||||
std::move(reactions));
|
||||
}
|
||||
|
||||
bool MessagesManager::update_message_interaction_info(DialogId dialog_id, Message *m, int32 view_count,
|
||||
int32 forward_count, bool has_reply_info,
|
||||
MessageReplyInfo &&reply_info, const char *source) {
|
||||
MessageReplyInfo &&reply_info, bool has_reactions,
|
||||
unique_ptr<MessageReactions> &&reactions, const char *source) {
|
||||
CHECK(m != nullptr);
|
||||
m->interaction_info_update_date = G()->unix_time(); // doesn't force message saving
|
||||
if (m->message_id.is_valid_scheduled()) {
|
||||
@ -6968,7 +7003,13 @@ bool MessagesManager::update_message_interaction_info(DialogId dialog_id, Messag
|
||||
}
|
||||
}
|
||||
}
|
||||
if (view_count > m->view_count || forward_count > m->forward_count || need_update_reply_info) {
|
||||
if (has_reactions && reactions != nullptr && m->reactions != nullptr) {
|
||||
reactions->update_from(*m->reactions);
|
||||
}
|
||||
bool need_update_reactions =
|
||||
has_reactions && MessageReactions::need_update_message_reactions(m->reactions.get(), reactions.get());
|
||||
if (view_count > m->view_count || forward_count > m->forward_count || need_update_reply_info ||
|
||||
need_update_reactions) {
|
||||
LOG(DEBUG) << "Update interaction info of " << FullMessageId{dialog_id, m->message_id} << " from " << m->view_count
|
||||
<< '/' << m->forward_count << "/" << m->reply_info << " to " << view_count << '/' << forward_count << "/"
|
||||
<< reply_info;
|
||||
@ -6995,6 +7036,10 @@ bool MessagesManager::update_message_interaction_info(DialogId dialog_id, Messag
|
||||
}
|
||||
need_update |= is_visible_message_reply_info(dialog_id, m);
|
||||
}
|
||||
if (need_update_reactions) {
|
||||
m->reactions = std::move(reactions);
|
||||
need_update |= is_visible_message_reactions(dialog_id, m);
|
||||
}
|
||||
if (need_update) {
|
||||
send_update_message_interaction_info(dialog_id, m);
|
||||
}
|
||||
@ -13702,6 +13747,9 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message(
|
||||
if (message->flags_ & MESSAGE_FLAG_HAS_REPLY_INFO) {
|
||||
message_info.reply_info = std::move(message->replies_);
|
||||
}
|
||||
if (message->flags_ & MESSAGE_FLAG_HAS_REACTIONS) {
|
||||
message_info.reactions = std::move(message->reactions_);
|
||||
}
|
||||
if (message->flags_ & MESSAGE_FLAG_HAS_EDIT_DATE) {
|
||||
message_info.edit_date = message->edit_date_;
|
||||
}
|
||||
@ -13959,6 +14007,8 @@ std::pair<DialogId, unique_ptr<MessagesManager::Message>> MessagesManager::creat
|
||||
if (top_thread_message_id.is_valid() && dialog_type != DialogType::Channel) {
|
||||
top_thread_message_id = MessageId();
|
||||
}
|
||||
auto reactions =
|
||||
MessageReactions::get_message_reactions(td_, std::move(message_info.reactions), td_->auth_manager_->is_bot());
|
||||
|
||||
bool has_forward_info = message_info.forward_header != nullptr;
|
||||
|
||||
@ -14003,6 +14053,7 @@ std::pair<DialogId, unique_ptr<MessagesManager::Message>> MessagesManager::creat
|
||||
message->view_count = view_count;
|
||||
message->forward_count = forward_count;
|
||||
message->reply_info = std::move(reply_info);
|
||||
message->reactions = std::move(reactions);
|
||||
message->legacy_layer = (is_legacy ? MTPROTO_LAYER : 0);
|
||||
message->content = std::move(message_info.content);
|
||||
message->reply_markup = get_reply_markup(std::move(message_info.reply_markup), td_->auth_manager_->is_bot(), false,
|
||||
@ -24373,6 +24424,12 @@ void MessagesManager::add_message_dependencies(Dependencies &dependencies, const
|
||||
// it will be created in get_message_reply_info_object if needed
|
||||
add_dialog_dependencies(dependencies, recent_replier_dialog_id);
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
add_message_content_dependencies(dependencies, m->content.get());
|
||||
add_reply_markup_dependencies(dependencies, m->reply_markup.get());
|
||||
}
|
||||
@ -34731,7 +34788,8 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr
|
||||
need_send_update = true;
|
||||
}
|
||||
if (update_message_interaction_info(dialog_id, old_message, new_message->view_count, new_message->forward_count, true,
|
||||
std::move(new_message->reply_info), "update_message")) {
|
||||
std::move(new_message->reply_info), true, std::move(new_message->reactions),
|
||||
"update_message")) {
|
||||
need_send_update = true;
|
||||
}
|
||||
if (old_message->noforwards != new_message->noforwards) {
|
||||
|
@ -91,6 +91,7 @@ class DialogFilter;
|
||||
class DraftMessage;
|
||||
struct InputMessageContent;
|
||||
class MessageContent;
|
||||
struct MessageReactions;
|
||||
class MultiSequenceDispatcher;
|
||||
class Td;
|
||||
|
||||
@ -115,6 +116,7 @@ class MessagesManager final : public Actor {
|
||||
static constexpr int32 MESSAGE_FLAG_HAS_MEDIA_ALBUM_ID = 1 << 17;
|
||||
static constexpr int32 MESSAGE_FLAG_IS_FROM_SCHEDULED = 1 << 18;
|
||||
static constexpr int32 MESSAGE_FLAG_IS_LEGACY = 1 << 19;
|
||||
static constexpr int32 MESSAGE_FLAG_HAS_REACTIONS = 1 << 20;
|
||||
static constexpr int32 MESSAGE_FLAG_HIDE_EDIT_DATE = 1 << 21;
|
||||
static constexpr int32 MESSAGE_FLAG_IS_RESTRICTED = 1 << 22;
|
||||
static constexpr int32 MESSAGE_FLAG_HAS_REPLY_INFO = 1 << 23;
|
||||
@ -335,8 +337,9 @@ class MessagesManager final : public Actor {
|
||||
void on_update_message_forward_count(FullMessageId full_message_id, int32 forward_count);
|
||||
|
||||
void on_update_message_interaction_info(FullMessageId full_message_id, int32 view_count, int32 forward_count,
|
||||
bool has_reply_info,
|
||||
tl_object_ptr<telegram_api::messageReplies> &&reply_info);
|
||||
bool has_reply_info, tl_object_ptr<telegram_api::messageReplies> &&reply_info,
|
||||
bool has_reactions,
|
||||
tl_object_ptr<telegram_api::messageReactions> &&reactions);
|
||||
|
||||
void on_update_live_location_viewed(FullMessageId full_message_id);
|
||||
|
||||
@ -996,6 +999,7 @@ class MessagesManager final : public Actor {
|
||||
int32 view_count = 0;
|
||||
int32 forward_count = 0;
|
||||
tl_object_ptr<telegram_api::messageReplies> reply_info;
|
||||
tl_object_ptr<telegram_api::messageReactions> reactions;
|
||||
int32 flags = 0;
|
||||
int32 edit_date = 0;
|
||||
vector<RestrictionReason> restriction_reasons;
|
||||
@ -1128,6 +1132,7 @@ class MessagesManager final : public Actor {
|
||||
int32 view_count = 0;
|
||||
int32 forward_count = 0;
|
||||
MessageReplyInfo reply_info;
|
||||
unique_ptr<MessageReactions> reactions;
|
||||
unique_ptr<DraftMessage> thread_draft_message;
|
||||
int32 interaction_info_update_date = 0;
|
||||
|
||||
@ -2083,12 +2088,15 @@ class MessagesManager final : public Actor {
|
||||
void on_pending_message_views_timeout(DialogId dialog_id);
|
||||
|
||||
void update_message_interaction_info(FullMessageId full_message_id, int32 view_count, int32 forward_count,
|
||||
bool has_reply_info, tl_object_ptr<telegram_api::messageReplies> &&reply_info);
|
||||
bool has_reply_info, tl_object_ptr<telegram_api::messageReplies> &&reply_info,
|
||||
bool has_reactions, tl_object_ptr<telegram_api::messageReactions> &&reactions);
|
||||
|
||||
bool is_active_message_reply_info(DialogId dialog_id, const MessageReplyInfo &info) const;
|
||||
|
||||
bool is_visible_message_reply_info(DialogId dialog_id, const Message *m) const;
|
||||
|
||||
bool is_visible_message_reactions(DialogId dialog_id, const Message *m) const;
|
||||
|
||||
void on_message_reply_info_changed(DialogId dialog_id, const Message *m) const;
|
||||
|
||||
Result<FullMessageId> get_top_thread_full_message_id(DialogId dialog_id, const Message *m) const;
|
||||
@ -2097,7 +2105,8 @@ class MessagesManager final : public Actor {
|
||||
const Message *m) const;
|
||||
|
||||
bool update_message_interaction_info(DialogId dialog_id, Message *m, int32 view_count, int32 forward_count,
|
||||
bool has_reply_info, MessageReplyInfo &&reply_info, const char *source);
|
||||
bool has_reply_info, MessageReplyInfo &&reply_info, bool has_reactions,
|
||||
unique_ptr<MessageReactions> &&reactions, const char *source);
|
||||
|
||||
bool update_message_contains_unread_mention(Dialog *d, Message *m, bool contains_unread_mention, const char *source);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user