Add MessageReactis::add_reaction/remove_reaction.

This commit is contained in:
levlam 2022-09-09 17:43:21 +03:00
parent e0699944b3
commit 28d3d1ab37
3 changed files with 67 additions and 60 deletions

View File

@ -414,7 +414,7 @@ void MessageReaction::update_recent_chooser_dialog_ids(const MessageReaction &ol
recent_chooser_min_channels_ = old_reaction.recent_chooser_min_channels_;
}
void MessageReaction::set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool can_get_added_reactions) {
void MessageReaction::set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool have_recent_choosers) {
if (is_chosen_ == is_chosen) {
return;
}
@ -423,7 +423,7 @@ void MessageReaction::set_is_chosen(bool is_chosen, DialogId chooser_dialog_id,
if (chooser_dialog_id.is_valid()) {
choose_count_ += is_chosen_ ? 1 : -1;
if (can_get_added_reactions) {
if (have_recent_choosers) {
remove_recent_chooser_dialog_id(chooser_dialog_id);
if (is_chosen_) {
add_recent_chooser_dialog_id(chooser_dialog_id);
@ -601,6 +601,58 @@ void MessageReactions::update_from(const MessageReactions &old_reactions) {
}
}
bool MessageReactions::add_reaction(const string &reaction, bool is_big, DialogId chooser_dialog_id,
bool have_recent_choosers) {
bool is_found = false;
for (auto it = reactions_.begin(); it != reactions_.end();) {
auto &message_reaction = *it;
if (message_reaction.is_chosen()) {
if (message_reaction.get_reaction() == reaction && !is_big) {
return false;
}
message_reaction.set_is_chosen(false, chooser_dialog_id, have_recent_choosers);
}
if (message_reaction.get_reaction() == reaction) {
message_reaction.set_is_chosen(true, chooser_dialog_id, have_recent_choosers);
is_found = true;
}
if (message_reaction.is_empty()) {
it = reactions_.erase(it);
} else {
++it;
}
}
if (!is_found) {
return true;
}
vector<DialogId> recent_chooser_dialog_ids;
if (have_recent_choosers) {
recent_chooser_dialog_ids.push_back(chooser_dialog_id);
}
reactions_.emplace_back(reaction, 1, true, std::move(recent_chooser_dialog_ids), Auto());
return true;
}
bool MessageReactions::remove_reaction(const string &reaction, DialogId chooser_dialog_id, bool have_recent_choosers) {
for (auto it = reactions_.begin(); it != reactions_.end(); ++it) {
auto &message_reaction = *it;
if (message_reaction.get_reaction() == reaction) {
if (message_reaction.is_chosen()) {
message_reaction.set_is_chosen(false, chooser_dialog_id, have_recent_choosers);
if (message_reaction.is_empty()) {
it = reactions_.erase(it);
}
return true;
}
break;
}
}
return false;
}
void MessageReactions::sort_reactions(const FlatHashMap<string, size_t> &active_reaction_pos) {
std::sort(reactions_.begin(), reactions_.end(),
[&active_reaction_pos](const MessageReaction &lhs, const MessageReaction &rhs) {

View File

@ -63,7 +63,7 @@ class MessageReaction {
return is_chosen_;
}
void set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool can_get_added_reactions);
void set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool have_recent_choosers);
int32 get_choose_count() const {
return choose_count_;
@ -152,6 +152,10 @@ struct MessageReactions {
void update_from(const MessageReactions &old_reactions);
bool add_reaction(const string &reaction, bool is_big, DialogId chooser_dialog_id, bool have_recent_choosers);
bool remove_reaction(const string &reaction, DialogId chooser_dialog_id, bool have_recent_choosers);
void sort_reactions(const FlatHashMap<string, size_t> &active_reaction_pos);
void fix_chosen_reaction(DialogId my_dialog_id);

View File

@ -24526,7 +24526,7 @@ void MessagesManager::add_message_reaction(FullMessageId full_message_id, string
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");
Message *m = get_message_force(d, full_message_id.get_message_id(), "add_message_reaction");
if (m == nullptr) {
return promise.set_error(Status::Error(400, "Message not found"));
}
@ -24535,41 +24535,15 @@ void MessagesManager::add_message_reaction(FullMessageId full_message_id, string
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 &&
!is_discussion_message(dialog_id, m);
bool have_recent_choosers = !is_broadcast_channel(dialog_id) && !is_discussion_message(dialog_id, m);
if (m->reactions == nullptr) {
m->reactions = make_unique<MessageReactions>();
m->reactions->can_get_added_reactions_ = can_get_added_reactions;
m->reactions->can_get_added_reactions_ = have_recent_choosers && dialog_id.get_type() != DialogType::User;
m->available_reactions_generation = d->available_reactions_generation;
}
bool is_found = false;
for (auto it = m->reactions->reactions_.begin(); it != m->reactions->reactions_.end();) {
auto &message_reaction = *it;
if (message_reaction.is_chosen()) {
if (message_reaction.get_reaction() == reaction && !is_big) {
return promise.set_value(Unit());
}
message_reaction.set_is_chosen(false, get_my_dialog_id(), can_get_added_reactions);
}
if (message_reaction.get_reaction() == reaction) {
message_reaction.set_is_chosen(true, get_my_dialog_id(), can_get_added_reactions);
is_found = true;
}
if (message_reaction.is_empty()) {
it = m->reactions->reactions_.erase(it);
} else {
++it;
}
}
if (!is_found) {
vector<DialogId> recent_chooser_dialog_ids;
if (!is_broadcast_channel(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());
if (!m->reactions->add_reaction(reaction, is_big, get_my_dialog_id(), have_recent_choosers)) {
return promise.set_value(Unit());
}
set_message_reactions(d, m, is_big, add_to_recent, std::move(promise));
@ -24582,36 +24556,13 @@ void MessagesManager::remove_message_reaction(FullMessageId full_message_id, str
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");
Message *m = get_message_force(d, full_message_id.get_message_id(), "remove_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) {
bool have_recent_choosers = !is_broadcast_channel(dialog_id) && !is_discussion_message(dialog_id, m);
if (m->reactions == nullptr || !m->reactions->remove_reaction(reaction, get_my_dialog_id(), have_recent_choosers)) {
return promise.set_value(Unit());
}