Sort reactions returned in getMessageAvailableReactions.

This commit is contained in:
levlam 2022-09-13 19:19:35 +03:00
parent 5213561096
commit 30b961aebf
11 changed files with 145 additions and 26 deletions

View File

@ -2583,8 +2583,15 @@ addedReaction type:ReactionType sender_id:MessageSender = AddedReaction;
//@description Represents a list of reactions added to a message @total_count The total number of found reactions @reactions The list of added reactions @next_offset The offset for the next request. If empty, there are no more results
addedReactions total_count:int32 reactions:vector<addedReaction> next_offset:string = AddedReactions;
//@description Represents a list of reactions that can be added to a message @reactions List of available reactions @allow_custom_emoji True, if any other custom emoji reaction can be added
availableReactions reactions:vector<ReactionType> allow_custom_emoji:Bool = AvailableReactions;
//@description Represents an available reaction @type Type of the reaction @needs_premium True, if Telegram Premium is needed to send the reaction
availableReaction type:ReactionType needs_premium:Bool = AvailableReaction;
//@description Represents a list of reactions that can be added to a message
//@top_reactions List of reactions to be shown at the top
//@recent_reactions List of recently used reactions
//@popular_reactions List of popular reactions
//@allow_custom_emoji True, if any other custom emoji reaction could be added by Telegram Premium subscribers
availableReactions top_reactions:vector<availableReaction> recent_reactions:vector<availableReaction> popular_reactions:vector<availableReaction> allow_custom_emoji:Bool = AvailableReactions;
//@description Contains information about a emoji reaction
//@emoji Text representation of the reaction
@ -5175,7 +5182,8 @@ getCustomEmojiReactionAnimations = Files;
//@description Returns reactions, which can be added to a message. The list can change after updateActiveEmojiReactions, updateChatAvailableReactions for the chat, or updateMessageInteractionInfo for the message
//@chat_id Identifier of the chat to which the message belongs
//@message_id Identifier of the message
getMessageAvailableReactions chat_id:int53 message_id:int53 = AvailableReactions;
//@row_size Number of reaction per row, 5-25
getMessageAvailableReactions chat_id:int53 message_id:int53 row_size:int32 = AvailableReactions;
//@description Clears the list of recently used reactions
clearRecentReactions = Ok;

View File

@ -86,12 +86,6 @@ td_api::object_ptr<td_api::ChatAvailableReactions> ChatReactions::get_chat_avail
return td_api::make_object<td_api::chatAvailableReactionsSome>(transform(reactions_, get_reaction_type_object));
}
td_api::object_ptr<td_api::availableReactions> ChatReactions::get_available_reactions_object() const {
CHECK(!allow_all_);
return td_api::make_object<td_api::availableReactions>(transform(reactions_, get_reaction_type_object),
allow_custom_);
}
telegram_api::object_ptr<telegram_api::ChatReactions> ChatReactions::get_input_chat_reactions() const {
if (allow_all_) {
int32 flags = 0;

View File

@ -41,8 +41,6 @@ struct ChatReactions {
td_api::object_ptr<td_api::ChatAvailableReactions> get_chat_available_reactions_object() const;
td_api::object_ptr<td_api::availableReactions> get_available_reactions_object() const;
bool empty() const {
return reactions_.empty() && !allow_all_;
}

View File

@ -880,6 +880,14 @@ void report_message_reactions(Td *td, FullMessageId full_message_id, DialogId ch
td->create_handler<ReportReactionQuery>(std::move(promise))->send(dialog_id, message_id, chooser_dialog_id);
}
vector<string> get_recent_reactions(Td *td) {
return td->stickers_manager_->get_recent_reactions();
}
vector<string> get_top_reactions(Td *td) {
return td->stickers_manager_->get_top_reactions();
}
void add_recent_reaction(Td *td, const string &reaction) {
td->stickers_manager_->add_recent_reaction(reaction);
}

View File

@ -214,6 +214,10 @@ void send_update_default_reaction_type(const string &default_reaction);
void report_message_reactions(Td *td, FullMessageId full_message_id, DialogId chooser_dialog_id,
Promise<Unit> &&promise);
vector<string> get_recent_reactions(Td *td);
vector<string> get_top_reactions(Td *td);
void add_recent_reaction(Td *td, const string &reaction);
int64 get_reactions_hash(const vector<string> &reactions);

View File

@ -24469,7 +24469,12 @@ void MessagesManager::on_get_scheduled_messages_from_database(DialogId dialog_id
set_promises(promises);
}
Result<ChatReactions> MessagesManager::get_message_available_reactions(FullMessageId full_message_id) {
Result<td_api::object_ptr<td_api::availableReactions>> MessagesManager::get_message_available_reactions(
FullMessageId full_message_id, int32 row_size) {
if (row_size < 5 || row_size > 25) {
row_size = 8;
}
auto dialog_id = full_message_id.get_dialog_id();
Dialog *d = get_dialog_force(dialog_id, "get_message_available_reactions");
if (d == nullptr) {
@ -24480,10 +24485,97 @@ Result<ChatReactions> MessagesManager::get_message_available_reactions(FullMessa
if (m == nullptr) {
return Status::Error(400, "Message not found");
}
return get_message_available_reactions(d, m);
auto available_reactions = get_message_available_reactions(d, m, false);
bool is_premium = td_->option_manager_->get_option_boolean("is_premium");
bool show_premium = is_premium;
auto recent_reactions = get_recent_reactions(td_);
auto top_reactions = get_top_reactions(td_);
auto active_reactions = get_message_active_reactions(d, m);
LOG(INFO) << "Have available reactions " << available_reactions << " to be sorted by top reactions " << top_reactions
<< " and recent reactions " << recent_reactions;
if (active_reactions.allow_custom_ && active_reactions.allow_all_) {
for (auto &reaction : recent_reactions) {
if (is_custom_reaction(reaction)) {
show_premium = true;
}
}
for (auto &reaction : top_reactions) {
if (is_custom_reaction(reaction)) {
show_premium = true;
}
}
}
FlatHashSet<string> all_available_reactions;
for (const auto &reaction : available_reactions.reactions_) {
all_available_reactions.insert(reaction);
}
vector<td_api::object_ptr<td_api::availableReaction>> top_reaction_objects;
vector<td_api::object_ptr<td_api::availableReaction>> recent_reaction_objects;
vector<td_api::object_ptr<td_api::availableReaction>> popular_reaction_objects;
vector<td_api::object_ptr<td_api::availableReaction>> last_reaction_objects;
auto add_reactions = [&](vector<td_api::object_ptr<td_api::availableReaction>> &reaction_objects,
const vector<string> &reactions) {
for (auto &reaction : reactions) {
if (all_available_reactions.erase(reaction) != 0) {
// add available reaction
reaction_objects.push_back(
td_api::make_object<td_api::availableReaction>(get_reaction_type_object(reaction), false));
} else if (is_custom_reaction(reaction) && available_reactions.allow_custom_) {
// add implicitly available custom reaction
reaction_objects.push_back(
td_api::make_object<td_api::availableReaction>(get_reaction_type_object(reaction), !is_premium));
} else {
// skip the reaction
}
}
};
if (show_premium) {
if (top_reactions.size() > 2 * static_cast<size_t>(row_size)) {
top_reactions.resize(2 * static_cast<size_t>(row_size));
}
add_reactions(top_reaction_objects, top_reactions);
if (!recent_reactions.empty()) {
add_reactions(recent_reaction_objects, recent_reactions);
}
} else {
add_reactions(top_reaction_objects, top_reactions);
}
add_reactions(last_reaction_objects, active_reactions_);
add_reactions(last_reaction_objects, available_reactions.reactions_);
if (show_premium) {
if (recent_reactions.empty()) {
popular_reaction_objects = std::move(last_reaction_objects);
} else {
auto max_objects = 10 * static_cast<size_t>(row_size);
if (recent_reaction_objects.size() + last_reaction_objects.size() > max_objects) {
if (last_reaction_objects.size() < max_objects) {
recent_reaction_objects.resize(max_objects - last_reaction_objects.size());
} else {
recent_reaction_objects.clear();
}
}
append(recent_reaction_objects, std::move(last_reaction_objects));
}
} else {
append(top_reaction_objects, std::move(last_reaction_objects));
}
CHECK(all_available_reactions.empty());
return td_api::make_object<td_api::availableReactions>(
std::move(top_reaction_objects), std::move(recent_reaction_objects), std::move(popular_reaction_objects),
available_reactions.allow_custom_);
}
ChatReactions MessagesManager::get_message_available_reactions(const Dialog *d, const Message *m) {
ChatReactions MessagesManager::get_message_available_reactions(const Dialog *d, const Message *m,
bool dissalow_custom_for_non_premium) {
CHECK(d != nullptr);
CHECK(m != nullptr);
auto active_reactions = get_message_active_reactions(d, m);
@ -24517,14 +24609,13 @@ ChatReactions MessagesManager::get_message_available_reactions(const Dialog *d,
for (const auto &reaction : m->reactions->reactions_) {
// an already used reaction can be added if it is an active reaction
const string &reaction_str = reaction.get_reaction();
if (can_use_reactions && is_active_reaction(reaction_str, active_reaction_pos_)) {
if (!td::contains(active_reactions.reactions_, reaction_str)) {
active_reactions.reactions_.push_back(reaction_str);
}
if (can_use_reactions && is_active_reaction(reaction_str, active_reaction_pos_) &&
!td::contains(active_reactions.reactions_, reaction_str)) {
active_reactions.reactions_.push_back(reaction_str);
}
}
}
if (!td_->option_manager_->get_option_boolean("is_premium")) {
if (dissalow_custom_for_non_premium && !td_->option_manager_->get_option_boolean("is_premium")) {
active_reactions.allow_custom_ = false;
}
return active_reactions;
@ -24543,7 +24634,7 @@ void MessagesManager::add_message_reaction(FullMessageId full_message_id, string
return promise.set_error(Status::Error(400, "Message not found"));
}
if (!get_message_available_reactions(d, m).is_allowed_reaction(reaction)) {
if (!get_message_available_reactions(d, m, true).is_allowed_reaction(reaction)) {
return promise.set_error(Status::Error(400, "The reaction isn't available for the message"));
}

View File

@ -805,7 +805,8 @@ class MessagesManager final : public Actor {
vector<MessageId> get_dialog_scheduled_messages(DialogId dialog_id, bool force, bool ignore_result,
Promise<Unit> &&promise);
Result<ChatReactions> get_message_available_reactions(FullMessageId full_message_id);
Result<td_api::object_ptr<td_api::availableReactions>> get_message_available_reactions(FullMessageId full_message_id,
int32 row_size);
void add_message_reaction(FullMessageId full_message_id, string reaction, bool is_big, bool add_to_recent,
Promise<Unit> &&promise);
@ -2689,7 +2690,8 @@ class MessagesManager final : public Actor {
bool update_dialog_silent_send_message(Dialog *d, bool silent_send_message);
ChatReactions get_message_available_reactions(const Dialog *d, const Message *m);
ChatReactions get_message_available_reactions(const Dialog *d, const Message *m,
bool dissalow_custom_for_non_premium);
void set_message_reactions(Dialog *d, Message *m, bool is_big, bool add_to_recent, Promise<Unit> &&promise);

View File

@ -1573,6 +1573,16 @@ td_api::object_ptr<td_api::emojiReaction> StickersManager::get_emoji_reaction_ob
return nullptr;
}
vector<string> StickersManager::get_recent_reactions() {
load_recent_reactions();
return recent_reactions_.reactions_;
}
vector<string> StickersManager::get_top_reactions() {
load_top_reactions();
return top_reactions_.reactions_;
}
void StickersManager::add_recent_reaction(const string &reaction) {
load_recent_reactions();

View File

@ -173,6 +173,10 @@ class StickersManager final : public Actor {
td_api::object_ptr<td_api::emojiReaction> get_emoji_reaction_object(const string &emoji);
vector<string> get_recent_reactions();
vector<string> get_top_reactions();
void add_recent_reaction(const string &reaction);
void clear_recent_reactions(Promise<Unit> &&promise);

View File

@ -5212,12 +5212,12 @@ void Td::on_request(uint64 id, const td_api::getCustomEmojiReactionAnimations &r
void Td::on_request(uint64 id, const td_api::getMessageAvailableReactions &request) {
CHECK_IS_USER();
auto r_reactions =
messages_manager_->get_message_available_reactions({DialogId(request.chat_id_), MessageId(request.message_id_)});
auto r_reactions = messages_manager_->get_message_available_reactions(
{DialogId(request.chat_id_), MessageId(request.message_id_)}, request.row_size_);
if (r_reactions.is_error()) {
send_closure(actor_id(this), &Td::send_error, id, r_reactions.move_as_error());
} else {
send_closure(actor_id(this), &Td::send_result, id, r_reactions.ok().get_available_reactions_object());
send_closure(actor_id(this), &Td::send_result, id, r_reactions.move_as_ok());
}
}

View File

@ -2246,7 +2246,7 @@ class CliClient final : public Actor {
ChatId chat_id;
MessageId message_id;
get_args(args, chat_id, message_id);
send_request(td_api::make_object<td_api::getMessageAvailableReactions>(chat_id, message_id));
send_request(td_api::make_object<td_api::getMessageAvailableReactions>(chat_id, message_id, 8));
} else if (op == "crr") {
send_request(td_api::make_object<td_api::clearRecentReactions>());
} else if (op == "amr" || op == "react") {