diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 61e797d97..92ec661a4 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1786,11 +1786,11 @@ chatPosition list:ChatList order:int64 is_pinned:Bool source:ChatSource = ChatPo //@class ChatAvailableReactions @description Describes reactions available in the chat -//@description All reactions are available in the chat -chatAvailableReactionsAll = ChatAvailableReactions; +//@description All reactions are available in the chat @max_reaction_count The maximum allowed number of reactions per message; 1-11 +chatAvailableReactionsAll max_reaction_count:int32 = ChatAvailableReactions; -//@description Only specific reactions are available in the chat @reactions The list of reactions -chatAvailableReactionsSome reactions:vector = ChatAvailableReactions; +//@description Only specific reactions are available in the chat @reactions The list of reactions @max_reaction_count The maximum allowed number of reactions per message; 1-11 +chatAvailableReactionsSome reactions:vector max_reaction_count:int32 = ChatAvailableReactions; //@description Represents a tag used in Saved Messages or a Saved Messages topic diff --git a/td/telegram/ChatManager.cpp b/td/telegram/ChatManager.cpp index bf99b7400..89d7927fe 100644 --- a/td/telegram/ChatManager.cpp +++ b/td/telegram/ChatManager.cpp @@ -5269,8 +5269,8 @@ void ChatManager::on_get_chat_full(tl_object_ptr &&chat_ td_->messages_manager_->on_update_dialog_notify_settings(DialogId(chat_id), std::move(chat->notify_settings_), "on_get_chat_full"); - td_->messages_manager_->on_update_dialog_available_reactions(DialogId(chat_id), - std::move(chat->available_reactions_)); + td_->messages_manager_->on_update_dialog_available_reactions( + DialogId(chat_id), std::move(chat->available_reactions_), chat->reactions_limit_); td_->messages_manager_->on_update_dialog_theme_name(DialogId(chat_id), std::move(chat->theme_emoticon_)); @@ -5326,8 +5326,8 @@ void ChatManager::on_get_chat_full(tl_object_ptr &&chat_ td_->messages_manager_->on_update_dialog_background(DialogId(channel_id), std::move(channel->wallpaper_)); - td_->messages_manager_->on_update_dialog_available_reactions(DialogId(channel_id), - std::move(channel->available_reactions_)); + td_->messages_manager_->on_update_dialog_available_reactions( + DialogId(channel_id), std::move(channel->available_reactions_), channel->reactions_limit_); td_->messages_manager_->on_update_dialog_theme_name(DialogId(channel_id), std::move(channel->theme_emoticon_)); diff --git a/td/telegram/ChatReactions.cpp b/td/telegram/ChatReactions.cpp index c0648cadf..d9e20db50 100644 --- a/td/telegram/ChatReactions.cpp +++ b/td/telegram/ChatReactions.cpp @@ -6,11 +6,15 @@ // #include "td/telegram/ChatReactions.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/Td.h" + #include "td/utils/algorithm.h" namespace td { -ChatReactions::ChatReactions(telegram_api::object_ptr &&chat_reactions_ptr) { +ChatReactions::ChatReactions(telegram_api::object_ptr &&chat_reactions_ptr, + int32 reactions_limit) { if (chat_reactions_ptr == nullptr) { return; } @@ -31,6 +35,7 @@ ChatReactions::ChatReactions(telegram_api::object_ptr &&chat_reactions_ptr, @@ -39,13 +44,17 @@ ChatReactions::ChatReactions(td_api::object_ptr return; } switch (chat_reactions_ptr->get_id()) { - case td_api::chatAvailableReactionsAll::ID: + case td_api::chatAvailableReactionsAll::ID: { + auto chat_reactions = move_tl_object_as(chat_reactions_ptr); allow_all_regular_ = true; allow_all_custom_ = allow_all_custom; + reactions_limit_ = chat_reactions->max_reaction_count_; break; + } case td_api::chatAvailableReactionsSome::ID: { auto chat_reactions = move_tl_object_as(chat_reactions_ptr); reaction_types_ = ReactionType::get_reaction_types(chat_reactions->reactions_); + reactions_limit_ = chat_reactions->max_reaction_count_; break; } default: @@ -74,12 +83,16 @@ bool ChatReactions::is_allowed_reaction_type(const ReactionType &reaction_type) return td::contains(reaction_types_, reaction_type); } -td_api::object_ptr ChatReactions::get_chat_available_reactions_object() const { +td_api::object_ptr ChatReactions::get_chat_available_reactions_object(Td *td) const { + int32 reactions_uniq_max = static_cast(td->option_manager_->get_option_integer("reactions_uniq_max", 11)); + if (0 < reactions_limit_ && reactions_limit_ < reactions_uniq_max) { + reactions_uniq_max = reactions_limit_; + } if (allow_all_regular_) { - return td_api::make_object(); + return td_api::make_object(reactions_uniq_max); } return td_api::make_object( - ReactionType::get_reaction_types_object(reaction_types_)); + ReactionType::get_reaction_types_object(reaction_types_), reactions_uniq_max); } telegram_api::object_ptr ChatReactions::get_input_chat_reactions() const { @@ -99,10 +112,14 @@ telegram_api::object_ptr ChatReactions::get_input_c bool operator==(const ChatReactions &lhs, const ChatReactions &rhs) { // don't compare allow_all_custom_ - return lhs.reaction_types_ == rhs.reaction_types_ && lhs.allow_all_regular_ == rhs.allow_all_regular_; + return lhs.reaction_types_ == rhs.reaction_types_ && lhs.allow_all_regular_ == rhs.allow_all_regular_ && + lhs.reactions_limit_ == rhs.reactions_limit_; } StringBuilder &operator<<(StringBuilder &string_builder, const ChatReactions &reactions) { + if (reactions.reactions_limit_ != 0) { + string_builder << '[' << reactions.reactions_limit_ << "] "; + } if (reactions.allow_all_regular_) { if (reactions.allow_all_custom_) { return string_builder << "AllReactions"; diff --git a/td/telegram/ChatReactions.h b/td/telegram/ChatReactions.h index e46f2997c..fc69b09d0 100644 --- a/td/telegram/ChatReactions.h +++ b/td/telegram/ChatReactions.h @@ -16,17 +16,23 @@ namespace td { +class Td; + struct ChatReactions { vector reaction_types_; bool allow_all_regular_ = false; // implies empty reaction_types_ bool allow_all_custom_ = false; // implies allow_all_regular_ + int32 reactions_limit_ = 0; ChatReactions() = default; - explicit ChatReactions(vector &&reactions) : reaction_types_(std::move(reactions)) { + static ChatReactions legacy(vector &&reactions) { + ChatReactions result; + result.reaction_types_ = std::move(reactions); + return result; } - explicit ChatReactions(telegram_api::object_ptr &&chat_reactions_ptr); + ChatReactions(telegram_api::object_ptr &&chat_reactions_ptr, int32 reactions_limit); ChatReactions(td_api::object_ptr &&chat_reactions_ptr, bool allow_all_custom); @@ -41,7 +47,7 @@ struct ChatReactions { telegram_api::object_ptr get_input_chat_reactions() const; - td_api::object_ptr get_chat_available_reactions_object() const; + td_api::object_ptr get_chat_available_reactions_object(Td *td) const; bool empty() const { return reaction_types_.empty() && !allow_all_regular_; diff --git a/td/telegram/ChatReactions.hpp b/td/telegram/ChatReactions.hpp index 998e82d7a..0a3d40efd 100644 --- a/td/telegram/ChatReactions.hpp +++ b/td/telegram/ChatReactions.hpp @@ -17,27 +17,37 @@ namespace td { template void ChatReactions::store(StorerT &storer) const { bool has_reactions = !reaction_types_.empty(); + bool has_reactions_limit = reactions_limit_ != 0; BEGIN_STORE_FLAGS(); STORE_FLAG(allow_all_regular_); STORE_FLAG(allow_all_custom_); STORE_FLAG(has_reactions); + STORE_FLAG(has_reactions_limit); END_STORE_FLAGS(); if (has_reactions) { td::store(reaction_types_, storer); } + if (has_reactions_limit) { + td::store(reactions_limit_, storer); + } } template void ChatReactions::parse(ParserT &parser) { bool has_reactions; + bool has_reactions_limit; BEGIN_PARSE_FLAGS(); PARSE_FLAG(allow_all_regular_); PARSE_FLAG(allow_all_custom_); PARSE_FLAG(has_reactions); + PARSE_FLAG(has_reactions_limit); END_PARSE_FLAGS(); if (has_reactions) { td::parse(reaction_types_, parser); } + if (has_reactions_limit) { + td::parse(reactions_limit_, parser); + } } } // namespace td diff --git a/td/telegram/DialogEventLog.cpp b/td/telegram/DialogEventLog.cpp index f7d99c36c..a02ee1af3 100644 --- a/td/telegram/DialogEventLog.cpp +++ b/td/telegram/DialogEventLog.cpp @@ -367,11 +367,11 @@ static td_api::object_ptr get_chat_event_action_object( } case telegram_api::channelAdminLogEventActionChangeAvailableReactions::ID: { auto action = move_tl_object_as(action_ptr); - ChatReactions old_available_reactions(std::move(action->prev_value_)); - ChatReactions new_available_reactions(std::move(action->new_value_)); + ChatReactions old_available_reactions(std::move(action->prev_value_), 0); + ChatReactions new_available_reactions(std::move(action->new_value_), 0); return td_api::make_object( - old_available_reactions.get_chat_available_reactions_object(), - new_available_reactions.get_chat_available_reactions_object()); + old_available_reactions.get_chat_available_reactions_object(td), + new_available_reactions.get_chat_available_reactions_object(td)); } case telegram_api::channelAdminLogEventActionToggleForum::ID: { auto action = move_tl_object_as(action_ptr); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 825aa697a..9d2633df3 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -795,8 +795,12 @@ class SetChatAvailableReactionsQuery final : public Td::ResultHandler { return on_error(Status::Error(400, "Can't access the chat")); } int32 flags = 0; + if (available_reactions.reactions_limit_ != 0) { + flags |= telegram_api::messages_setChatAvailableReactions::REACTIONS_LIMIT_MASK; + } send_query(G()->net_query_creator().create(telegram_api::messages_setChatAvailableReactions( - flags, std::move(input_peer), available_reactions.get_input_chat_reactions(), 0))); + flags, std::move(input_peer), available_reactions.get_input_chat_reactions(), + available_reactions.reactions_limit_))); } void on_result(BufferSlice packet) final { @@ -5248,7 +5252,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { } else if (has_legacy_available_reactions) { vector legacy_available_reaction_types; parse(legacy_available_reaction_types, parser); - available_reactions = ChatReactions(std::move(legacy_available_reaction_types)); + available_reactions = ChatReactions::legacy(std::move(legacy_available_reaction_types)); } if (has_available_reactions_generation) { parse(available_reactions_generation, parser); @@ -7402,13 +7406,14 @@ void MessagesManager::on_update_dialog_notify_settings( } void MessagesManager::on_update_dialog_available_reactions( - DialogId dialog_id, telegram_api::object_ptr &&available_reactions) { + DialogId dialog_id, telegram_api::object_ptr &&available_reactions, + int32 reactions_limit) { Dialog *d = get_dialog_force(dialog_id, "on_update_dialog_available_reactions"); if (d == nullptr) { return; } - set_dialog_available_reactions(d, ChatReactions(std::move(available_reactions))); + set_dialog_available_reactions(d, ChatReactions(std::move(available_reactions), reactions_limit)); } void MessagesManager::set_dialog_available_reactions(Dialog *d, ChatReactions &&available_reactions) { @@ -19189,7 +19194,7 @@ td_api::object_ptr MessagesManager::get_chat_object(const Dialog * auto can_delete = can_delete_dialog(d); // TODO hide/show draft message when need_hide_dialog_draft_message changes auto draft_message = !need_hide_dialog_draft_message(d) ? get_draft_message_object(td_, d->draft_message) : nullptr; - auto available_reactions = get_dialog_active_reactions(d).get_chat_available_reactions_object(); + auto available_reactions = get_dialog_active_reactions(d).get_chat_available_reactions_object(td_); auto is_translatable = d->is_translatable && is_premium; auto block_list_id = BlockListId(d->is_blocked, d->is_blocked_for_stories); auto chat_lists = transform(get_dialog_list_ids(d), @@ -22283,6 +22288,9 @@ ChatReactions MessagesManager::get_message_available_reactions(const Dialog *d, } int64 reactions_uniq_max = td_->option_manager_->get_option_integer("reactions_uniq_max", 11); + if (0 < active_reactions.reactions_limit_ && active_reactions.reactions_limit_ < reactions_uniq_max) { + reactions_uniq_max = active_reactions.reactions_limit_; + } bool can_add_new_reactions = m->reactions == nullptr || static_cast(m->reactions->reactions_.size()) < reactions_uniq_max; @@ -28823,7 +28831,7 @@ void MessagesManager::send_update_chat_business_bot_manage_bar(Dialog *d) { void MessagesManager::send_update_chat_available_reactions(const Dialog *d) { CHECK(d != nullptr); LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_available_reactions"; - auto available_reactions = get_dialog_active_reactions(d).get_chat_available_reactions_object(); + auto available_reactions = get_dialog_active_reactions(d).get_chat_available_reactions_object(td_); send_closure(G()->td(), &Td::send_update, td_api::make_object( get_chat_id_object(d->dialog_id, "updateChatAvailableReactions"), std::move(available_reactions))); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index bd17f3a2c..c9437c3aa 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -843,8 +843,9 @@ class MessagesManager final : public Actor { tl_object_ptr &&peer_notify_settings, const char *source); - void on_update_dialog_available_reactions( - DialogId dialog_id, telegram_api::object_ptr &&available_reactions); + void on_update_dialog_available_reactions(DialogId dialog_id, + telegram_api::object_ptr &&available_reactions, + int32 reactions_limit); void hide_dialog_action_bar(DialogId dialog_id); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index cdea1bf29..180fff832 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -6039,14 +6039,16 @@ class CliClient final : public Actor { if (op == "scar") { ChatId chat_id; + int32 max_reaction_count; string available_reactions; - get_args(args, chat_id, available_reactions); + get_args(args, chat_id, max_reaction_count, available_reactions); td_api::object_ptr chat_available_reactions; if (available_reactions == "all") { - chat_available_reactions = td_api::make_object(); + chat_available_reactions = td_api::make_object(max_reaction_count); } else if (!available_reactions.empty()) { auto reactions = transform(autosplit_str(available_reactions), as_reaction_type); - chat_available_reactions = td_api::make_object(std::move(reactions)); + chat_available_reactions = + td_api::make_object(std::move(reactions), max_reaction_count); } send_request( td_api::make_object(chat_id, std::move(chat_available_reactions)));