Split setMessageReaction to addMessageReaction and removeMessageReaction.

This commit is contained in:
levlam 2022-09-09 15:56:45 +03:00
parent 4ae5b9a533
commit 6b2f6b4204
6 changed files with 105 additions and 31 deletions

View File

@ -5169,13 +5169,19 @@ editMessageSchedulingState chat_id:int53 message_id:int53 scheduling_state:Messa
//@message_id Identifier of the message //@message_id Identifier of the message
getMessageAvailableReactions chat_id:int53 message_id:int53 = AvailableReactions; getMessageAvailableReactions chat_id:int53 message_id:int53 = AvailableReactions;
//@description Changes chosen reaction for a message //@description Adds a reaction to a message. Use getMessageAvailableReactions to receive the list of available reactions for the message
//@chat_id Identifier of the chat to which the message belongs //@chat_id Identifier of the chat to which the message belongs
//@message_id Identifier of the message //@message_id Identifier of the message
//@reaction_type Type of the new chosen reaction; pass null or the currently chosen non-big reaction to remove the reaction //@reaction_type Type of the reaction to add
//@is_big Pass true if the reaction is added with a big animation //@is_big Pass true if the reaction is added with a big animation
//@update_recent_reactions Pass true if the reaction needs to be added to recent reactions //@update_recent_reactions Pass true if the reaction needs to be added to recent reactions
setMessageReaction chat_id:int53 message_id:int53 reaction_type:ReactionType is_big:Bool update_recent_reactions:Bool = Ok; addMessageReaction chat_id:int53 message_id:int53 reaction_type:ReactionType is_big:Bool update_recent_reactions:Bool = Ok;
//@description Removes a reaction from a message. A chosen reaction can always be removed
//@chat_id Identifier of the chat to which the message belongs
//@message_id Identifier of the message
//@reaction_type Type of the reaction to remove
removeMessageReaction chat_id:int53 message_id:int53 reaction_type:ReactionType = Ok;
//@description Returns reactions added for a message, along with their sender //@description Returns reactions added for a message, along with their sender
//@chat_id Identifier of the chat to which the message belongs //@chat_id Identifier of the chat to which the message belongs

View File

@ -24515,10 +24515,10 @@ ChatReactions MessagesManager::get_message_available_reactions(const Dialog *d,
return active_reactions; return active_reactions;
} }
void MessagesManager::set_message_reaction(FullMessageId full_message_id, string reaction, bool is_big, void MessagesManager::add_message_reaction(FullMessageId full_message_id, string reaction, bool is_big,
bool add_to_recent, Promise<Unit> &&promise) { bool add_to_recent, Promise<Unit> &&promise) {
auto dialog_id = full_message_id.get_dialog_id(); auto dialog_id = full_message_id.get_dialog_id();
Dialog *d = get_dialog_force(dialog_id, "set_message_reaction"); Dialog *d = get_dialog_force(dialog_id, "add_message_reaction");
if (d == nullptr) { if (d == nullptr) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
} }
@ -24528,17 +24528,13 @@ void MessagesManager::set_message_reaction(FullMessageId full_message_id, string
return promise.set_error(Status::Error(400, "Message not found")); return promise.set_error(Status::Error(400, "Message not found"));
} }
if (!reaction.empty() && !td::contains(get_message_available_reactions(d, m).reactions_, reaction)) { if (!td::contains(get_message_available_reactions(d, m).reactions_, reaction)) {
return promise.set_error(Status::Error(400, "The reaction isn't available for the message")); return promise.set_error(Status::Error(400, "The reaction isn't available for the message"));
} }
bool can_get_added_reactions = !is_broadcast_channel(dialog_id) && dialog_id.get_type() != DialogType::User && bool can_get_added_reactions = !is_broadcast_channel(dialog_id) && dialog_id.get_type() != DialogType::User &&
!is_discussion_message(dialog_id, m); !is_discussion_message(dialog_id, m);
if (m->reactions == nullptr) { if (m->reactions == nullptr) {
if (reaction.empty()) {
return promise.set_value(Unit());
}
m->reactions = make_unique<MessageReactions>(); m->reactions = make_unique<MessageReactions>();
m->reactions->can_get_added_reactions_ = can_get_added_reactions; m->reactions->can_get_added_reactions_ = can_get_added_reactions;
m->available_reactions_generation = d->available_reactions_generation; m->available_reactions_generation = d->available_reactions_generation;
@ -24549,8 +24545,7 @@ void MessagesManager::set_message_reaction(FullMessageId full_message_id, string
auto &message_reaction = *it; auto &message_reaction = *it;
if (message_reaction.is_chosen()) { if (message_reaction.is_chosen()) {
if (message_reaction.get_reaction() == reaction && !is_big) { if (message_reaction.get_reaction() == reaction && !is_big) {
// double set removes reaction, unless a big reaction is set return promise.set_value(Unit());
reaction = string();
} }
message_reaction.set_is_chosen(false, get_my_dialog_id(), can_get_added_reactions); message_reaction.set_is_chosen(false, get_my_dialog_id(), can_get_added_reactions);
} }
@ -24566,32 +24561,84 @@ void MessagesManager::set_message_reaction(FullMessageId full_message_id, string
} }
} }
pending_reactions_[full_message_id].query_count++; if (!is_found) {
if (!is_found && !reaction.empty()) {
vector<DialogId> recent_chooser_dialog_ids; vector<DialogId> recent_chooser_dialog_ids;
if (!is_broadcast_channel(dialog_id)) { if (!is_broadcast_channel(dialog_id)) {
recent_chooser_dialog_ids.push_back(get_my_dialog_id()); recent_chooser_dialog_ids.push_back(get_my_dialog_id());
} }
m->reactions->reactions_.emplace_back(reaction, 1, true, std::move(recent_chooser_dialog_ids), Auto()); m->reactions->reactions_.emplace_back(reaction, 1, true, std::move(recent_chooser_dialog_ids), Auto());
} }
set_message_reactions(d, m, reaction, is_big, add_to_recent, std::move(promise));
}
void MessagesManager::remove_message_reaction(FullMessageId full_message_id, string reaction, Promise<Unit> &&promise) {
auto dialog_id = full_message_id.get_dialog_id();
Dialog *d = get_dialog_force(dialog_id, "remove_message_reaction");
if (d == nullptr) {
return promise.set_error(Status::Error(400, "Chat not found"));
}
Message *m = get_message_force(d, full_message_id.get_message_id(), "set_message_reaction");
if (m == nullptr) {
return promise.set_error(Status::Error(400, "Message not found"));
}
bool can_get_added_reactions = !is_broadcast_channel(dialog_id) && dialog_id.get_type() != DialogType::User &&
!is_discussion_message(dialog_id, m);
if (m->reactions == nullptr) {
return promise.set_value(Unit());
}
bool is_found = false;
for (auto it = m->reactions->reactions_.begin(); it != m->reactions->reactions_.end();) {
auto &message_reaction = *it;
if (message_reaction.get_reaction() == reaction) {
if (message_reaction.is_chosen()) {
message_reaction.set_is_chosen(false, get_my_dialog_id(), can_get_added_reactions);
is_found = true;
} else {
return promise.set_value(Unit());
}
}
if (message_reaction.is_empty()) {
it = m->reactions->reactions_.erase(it);
} else {
++it;
}
}
if (!is_found) {
return promise.set_value(Unit());
}
set_message_reactions(d, m, reaction, false, false, std::move(promise));
}
void MessagesManager::set_message_reactions(Dialog *d, Message *m, string reaction, bool is_big, bool add_to_recent,
Promise<Unit> &&promise) {
CHECK(m->reactions != nullptr);
FullMessageId full_message_id{d->dialog_id, m->message_id};
pending_reactions_[full_message_id].query_count++;
m->reactions->sort_reactions(active_reaction_pos_); m->reactions->sort_reactions(active_reaction_pos_);
send_update_message_interaction_info(dialog_id, m); send_update_message_interaction_info(d->dialog_id, m);
on_message_changed(d, m, true, "set_message_reaction"); on_message_changed(d, m, true, "set_message_reactions");
// TODO invoke_after, cancel previous queries, log event // TODO cancel previous queries, log event
auto query_promise = PromiseCreator::lambda( auto query_promise = PromiseCreator::lambda(
[actor_id = actor_id(this), full_message_id, promise = std::move(promise)](Result<Unit> &&result) mutable { [actor_id = actor_id(this), full_message_id, promise = std::move(promise)](Result<Unit> &&result) mutable {
send_closure(actor_id, &MessagesManager::on_set_message_reaction, full_message_id, std::move(result), send_closure(actor_id, &MessagesManager::on_set_message_reactions, full_message_id, std::move(result),
std::move(promise)); std::move(promise));
}); });
::td::set_message_reaction(td_, full_message_id, std::move(reaction), is_big, add_to_recent, ::td::set_message_reaction(td_, full_message_id, std::move(reaction), is_big, add_to_recent,
std::move(query_promise)); std::move(query_promise));
} }
void MessagesManager::on_set_message_reaction(FullMessageId full_message_id, Result<Unit> result, void MessagesManager::on_set_message_reactions(FullMessageId full_message_id, Result<Unit> result,
Promise<Unit> promise) { Promise<Unit> promise) {
TRY_STATUS_PROMISE(promise, G()->close_status()); TRY_STATUS_PROMISE(promise, G()->close_status());
bool need_reload = result.is_error(); bool need_reload = result.is_error();

View File

@ -807,9 +807,11 @@ class MessagesManager final : public Actor {
Result<ChatReactions> get_message_available_reactions(FullMessageId full_message_id); Result<ChatReactions> get_message_available_reactions(FullMessageId full_message_id);
void set_message_reaction(FullMessageId full_message_id, string reaction, bool is_big, bool add_to_recent, void add_message_reaction(FullMessageId full_message_id, string reaction, bool is_big, bool add_to_recent,
Promise<Unit> &&promise); Promise<Unit> &&promise);
void remove_message_reaction(FullMessageId full_message_id, string reaction, Promise<Unit> &&promise);
void get_message_public_forwards(FullMessageId full_message_id, string offset, int32 limit, void get_message_public_forwards(FullMessageId full_message_id, string offset, int32 limit,
Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); Promise<td_api::object_ptr<td_api::foundMessages>> &&promise);
@ -2689,7 +2691,10 @@ class MessagesManager final : public Actor {
ChatReactions get_message_available_reactions(const Dialog *d, const Message *m); ChatReactions get_message_available_reactions(const Dialog *d, const Message *m);
void on_set_message_reaction(FullMessageId full_message_id, Result<Unit> result, Promise<Unit> promise); void set_message_reactions(Dialog *d, Message *m, string reaction, bool is_big, bool add_to_recent,
Promise<Unit> &&promise);
void on_set_message_reactions(FullMessageId full_message_id, Result<Unit> result, Promise<Unit> promise);
void set_dialog_available_reactions(Dialog *d, ChatReactions &&available_reactions); void set_dialog_available_reactions(Dialog *d, ChatReactions &&available_reactions);

View File

@ -5210,14 +5210,21 @@ void Td::on_request(uint64 id, const td_api::getMessageAvailableReactions &reque
} }
} }
void Td::on_request(uint64 id, td_api::setMessageReaction &request) { void Td::on_request(uint64 id, td_api::addMessageReaction &request) {
CHECK_IS_USER(); CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE(); CREATE_OK_REQUEST_PROMISE();
messages_manager_->set_message_reaction({DialogId(request.chat_id_), MessageId(request.message_id_)}, messages_manager_->add_message_reaction({DialogId(request.chat_id_), MessageId(request.message_id_)},
get_message_reaction_string(request.reaction_type_), request.is_big_, get_message_reaction_string(request.reaction_type_), request.is_big_,
request.update_recent_reactions_, std::move(promise)); request.update_recent_reactions_, std::move(promise));
} }
void Td::on_request(uint64 id, td_api::removeMessageReaction &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
messages_manager_->remove_message_reaction({DialogId(request.chat_id_), MessageId(request.message_id_)},
get_message_reaction_string(request.reaction_type_), std::move(promise));
}
void Td::on_request(uint64 id, td_api::getMessageAddedReactions &request) { void Td::on_request(uint64 id, td_api::getMessageAddedReactions &request) {
CHECK_IS_USER(); CHECK_IS_USER();
CLEAN_INPUT_STRING(request.offset_); CLEAN_INPUT_STRING(request.offset_);

View File

@ -658,7 +658,9 @@ class Td final : public Actor {
void on_request(uint64 id, const td_api::getMessageAvailableReactions &request); void on_request(uint64 id, const td_api::getMessageAvailableReactions &request);
void on_request(uint64 id, td_api::setMessageReaction &request); void on_request(uint64 id, td_api::addMessageReaction &request);
void on_request(uint64 id, td_api::removeMessageReaction &request);
void on_request(uint64 id, td_api::getMessageAddedReactions &request); void on_request(uint64 id, td_api::getMessageAddedReactions &request);

View File

@ -2241,14 +2241,21 @@ class CliClient final : public Actor {
MessageId message_id; MessageId message_id;
get_args(args, chat_id, 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));
} else if (op == "react" || op == "reactr") { } else if (op == "amr" || op == "react") {
ChatId chat_id; ChatId chat_id;
MessageId message_id; MessageId message_id;
string reaction; string reaction;
bool is_big; bool is_big;
get_args(args, chat_id, message_id, reaction, is_big); bool update_recent_reactions;
send_request(td_api::make_object<td_api::setMessageReaction>(chat_id, message_id, as_reaction_type(reaction), get_args(args, chat_id, message_id, reaction, is_big, update_recent_reactions);
is_big, op == "reactr")); send_request(td_api::make_object<td_api::addMessageReaction>(chat_id, message_id, as_reaction_type(reaction),
is_big, update_recent_reactions));
} else if (op == "rmr") {
ChatId chat_id;
MessageId message_id;
string reaction;
get_args(args, chat_id, message_id, reaction);
send_request(td_api::make_object<td_api::removeMessageReaction>(chat_id, message_id, as_reaction_type(reaction)));
} else if (op == "gmars") { } else if (op == "gmars") {
ChatId chat_id; ChatId chat_id;
MessageId message_id; MessageId message_id;
@ -4786,7 +4793,7 @@ class CliClient final : public Actor {
get_args(args, chat_id, file_id, reason, text); get_args(args, chat_id, file_id, reason, text);
send_request( send_request(
td_api::make_object<td_api::reportChatPhoto>(chat_id, file_id, get_chat_report_reason(reason), text)); td_api::make_object<td_api::reportChatPhoto>(chat_id, file_id, get_chat_report_reason(reason), text));
} else if (op == "rmr") { } else if (op == "reportmr") {
ChatId chat_id; ChatId chat_id;
MessageId message_id; MessageId message_id;
string sender_id; string sender_id;