Allow typings by chats and rename updateUserChatAction to updateChatAction.

This commit is contained in:
levlam 2021-11-23 14:29:49 +03:00
parent 2eb5f1195c
commit acc43bb0b5
5 changed files with 87 additions and 85 deletions

View File

@ -3800,8 +3800,8 @@ updateHavePendingNotifications have_delayed_notifications:Bool have_unreceived_n
//@from_cache True, if the messages are deleted only from the cache and can possibly be retrieved again in the future
updateDeleteMessages chat_id:int53 message_ids:vector<int53> is_permanent:Bool from_cache:Bool = Update;
//@description User activity in the chat has changed @chat_id Chat identifier @message_thread_id If not 0, a message thread identifier in which the action was performed @user_id Identifier of a user performing an action @action The action description
updateUserChatAction chat_id:int53 message_thread_id:int53 user_id:int53 action:ChatAction = Update;
//@description A message sender activity in the chat has changed @chat_id Chat identifier @message_thread_id If not 0, a message thread identifier in which the action was performed @sender_id Identifier of a message sender performing the action @action The action
updateChatAction chat_id:int53 message_thread_id:int53 sender_id:MessageSender action:ChatAction = Update;
//@description The user went online or offline @user_id User identifier @status New status of the user
updateUserStatus user_id:int53 status:UserStatus = Update;

View File

@ -7078,9 +7078,8 @@ void MessagesManager::on_update_delete_scheduled_messages(DialogId dialog_id,
send_update_chat_has_scheduled_messages(d, true);
}
void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id,
DialogId typing_dialog_id, DialogAction action, int32 date,
MessageContentType message_content_type) {
void MessagesManager::on_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id,
DialogAction action, int32 date, MessageContentType message_content_type) {
if (td_->auth_manager_->is_bot() || !typing_dialog_id.is_valid()) {
return;
}
@ -7095,7 +7094,7 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th
LOG(ERROR) << "Receive " << action << " in thread of " << top_thread_message_id << " in " << dialog_id;
return;
}
const Dialog *d = get_dialog_force(dialog_id, "on_user_dialog_action");
const Dialog *d = get_dialog_force(dialog_id, "on_dialog_action");
if (d != nullptr && d->active_group_call_id.is_valid()) {
auto group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, dialog_id);
td_->group_call_manager_->on_user_speaking_in_group_call(group_call_id, typing_dialog_id, date);
@ -7107,11 +7106,11 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th
return;
}
if (typing_dialog_id.get_type() != DialogType::User) {
auto typing_dialog_type = typing_dialog_id.get_type();
if (typing_dialog_type != DialogType::User && dialog_type != DialogType::Chat && dialog_type != DialogType::Channel) {
LOG(ERROR) << "Ignore " << action << " of " << typing_dialog_id << " in " << dialog_id;
return;
}
auto user_id = typing_dialog_id.get_user_id();
{
auto message_import_progress = action.get_importing_messages_action_progress();
@ -7124,11 +7123,13 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th
{
auto clicking_info = action.get_clicking_animated_emoji_action_info();
if (!clicking_info.data.empty()) {
auto message_id = MessageId(ServerMessageId(clicking_info.message_id));
CHECK(message_id.is_valid());
if (date > G()->unix_time() - 10) {
on_animated_emoji_message_clicked({dialog_id, message_id}, user_id, clicking_info.emoji,
std::move(clicking_info.data));
if (date > G()->unix_time() - 10 && dialog_type == DialogType::User && dialog_id == typing_dialog_id) {
FullMessageId full_message_id{dialog_id, MessageId(ServerMessageId(clicking_info.message_id))};
auto *m = get_message_force(full_message_id, "on_dialog_action");
if (m != nullptr) {
on_message_content_animated_emoji_clicked(m->content.get(), full_message_id, td_, clicking_info.emoji,
std::move(clicking_info.data));
}
}
return;
}
@ -7139,21 +7140,36 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th
return;
}
if (!td_->contacts_manager_->have_min_user(user_id)) {
LOG(DEBUG) << "Ignore " << action << " of unknown " << user_id;
return;
}
if (!have_dialog(dialog_id)) {
LOG(DEBUG) << "Ignore " << action << " in unknown " << dialog_id;
return;
}
if (typing_dialog_type == DialogType::User) {
if (!td_->contacts_manager_->have_min_user(typing_dialog_id.get_user_id())) {
LOG(DEBUG) << "Ignore " << action << " of unknown " << typing_dialog_id.get_user_id();
return;
}
} else {
if (!have_dialog_info_force(typing_dialog_id)) {
LOG(DEBUG) << "Ignore " << action << " of unknown " << typing_dialog_id;
return;
}
force_create_dialog(typing_dialog_id, "on_dialog_action", true);
if (!have_dialog(typing_dialog_id)) {
LOG(ERROR) << "Failed to create typing " << typing_dialog_id;
return;
}
}
bool is_canceled = action == DialogAction();
if (!is_canceled || message_content_type != MessageContentType::None) {
td_->contacts_manager_->on_update_user_local_was_online(user_id, date);
if ((!is_canceled || message_content_type != MessageContentType::None) && typing_dialog_type == DialogType::User) {
td_->contacts_manager_->on_update_user_local_was_online(typing_dialog_id.get_user_id(), date);
}
if (dialog_type == DialogType::User || dialog_type == DialogType::SecretChat) {
CHECK(typing_dialog_type == DialogType::User);
auto user_id = typing_dialog_id.get_user_id();
if (!td_->contacts_manager_->is_user_bot(user_id) && !td_->contacts_manager_->is_user_status_exact(user_id) &&
!get_dialog(dialog_id)->is_opened && !is_canceled) {
return;
@ -7167,18 +7183,20 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th
}
auto &active_actions = actions_it->second;
auto it = std::find_if(active_actions.begin(), active_actions.end(),
[user_id](const ActiveDialogAction &action) { return action.user_id == user_id; });
auto it = std::find_if(
active_actions.begin(), active_actions.end(),
[typing_dialog_id](const ActiveDialogAction &action) { return action.typing_dialog_id == typing_dialog_id; });
if (it == active_actions.end()) {
return;
}
if (!td_->contacts_manager_->is_user_bot(user_id) &&
if (!(typing_dialog_type == DialogType::User &&
td_->contacts_manager_->is_user_bot(typing_dialog_id.get_user_id())) &&
!it->action.is_canceled_by_message_of_type(message_content_type)) {
return;
}
LOG(DEBUG) << "Cancel action of " << user_id << " in " << dialog_id;
LOG(DEBUG) << "Cancel action of " << typing_dialog_id << " in " << dialog_id;
top_thread_message_id = it->top_thread_message_id;
active_actions.erase(it);
if (active_actions.empty()) {
@ -7188,29 +7206,30 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th
}
} else {
if (date < G()->unix_time_cached() - DIALOG_ACTION_TIMEOUT - 60) {
LOG(DEBUG) << "Ignore too old action of " << user_id << " in " << dialog_id << " sent at " << date;
LOG(DEBUG) << "Ignore too old action of " << typing_dialog_id << " in " << dialog_id << " sent at " << date;
return;
}
auto &active_actions = active_dialog_actions_[dialog_id];
auto it = std::find_if(active_actions.begin(), active_actions.end(),
[user_id](const ActiveDialogAction &action) { return action.user_id == user_id; });
auto it = std::find_if(
active_actions.begin(), active_actions.end(),
[typing_dialog_id](const ActiveDialogAction &action) { return action.typing_dialog_id == typing_dialog_id; });
MessageId prev_top_thread_message_id;
DialogAction prev_action;
if (it != active_actions.end()) {
LOG(DEBUG) << "Re-add action of " << user_id << " in " << dialog_id;
LOG(DEBUG) << "Re-add action of " << typing_dialog_id << " in " << dialog_id;
prev_top_thread_message_id = it->top_thread_message_id;
prev_action = it->action;
active_actions.erase(it);
} else {
LOG(DEBUG) << "Add action of " << user_id << " in " << dialog_id;
LOG(DEBUG) << "Add action of " << typing_dialog_id << " in " << dialog_id;
}
active_actions.emplace_back(top_thread_message_id, user_id, action, Time::now());
active_actions.emplace_back(top_thread_message_id, typing_dialog_id, action, Time::now());
if (top_thread_message_id == prev_top_thread_message_id && action == prev_action) {
return;
}
if (top_thread_message_id != prev_top_thread_message_id && prev_top_thread_message_id.is_valid()) {
send_update_user_chat_action(dialog_id, prev_top_thread_message_id, user_id, DialogAction());
send_update_chat_action(dialog_id, prev_top_thread_message_id, typing_dialog_id, DialogAction());
}
if (active_actions.size() == 1u) {
LOG(DEBUG) << "Set action timeout in " << dialog_id;
@ -7219,20 +7238,19 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th
}
if (top_thread_message_id.is_valid()) {
send_update_user_chat_action(dialog_id, MessageId(), user_id, action);
send_update_chat_action(dialog_id, MessageId(), typing_dialog_id, action);
}
send_update_user_chat_action(dialog_id, top_thread_message_id, user_id, action);
send_update_chat_action(dialog_id, top_thread_message_id, typing_dialog_id, action);
}
void MessagesManager::cancel_user_dialog_action(DialogId dialog_id, const Message *m) {
void MessagesManager::cancel_dialog_action(DialogId dialog_id, const Message *m) {
CHECK(m != nullptr);
if (td_->auth_manager_->is_bot() || m->forward_info != nullptr || m->had_forward_info ||
m->via_bot_user_id.is_valid() || m->hide_via_bot || m->is_channel_post || m->message_id.is_scheduled()) {
return;
}
on_user_dialog_action(dialog_id, MessageId(), DialogId(m->sender_user_id), DialogAction(), m->date,
m->content->get_type());
on_dialog_action(dialog_id, MessageId(), get_message_sender(m), DialogAction(), m->date, m->content->get_type());
}
void MessagesManager::add_postponed_channel_update(DialogId dialog_id, tl_object_ptr<telegram_api::Update> &&update,
@ -19918,20 +19936,6 @@ void MessagesManager::click_animated_emoji_message(FullMessageId full_message_id
get_message_content_animated_emoji_click_sticker(m->content.get(), full_message_id, td_, std::move(promise));
}
void MessagesManager::on_animated_emoji_message_clicked(FullMessageId full_message_id, UserId user_id, Slice emoji,
string data) {
CHECK(full_message_id.get_message_id().is_server());
auto *m = get_message_force(full_message_id, "on_animated_emoji_message_clicked");
if (m == nullptr) {
return;
}
if (full_message_id.get_dialog_id().get_type() != DialogType::User ||
full_message_id.get_dialog_id().get_user_id() != user_id) {
return;
}
on_message_content_animated_emoji_clicked(m->content.get(), full_message_id, td_, emoji, std::move(data));
}
void MessagesManager::open_dialog(Dialog *d) {
CHECK(!td_->auth_manager_->is_bot());
DialogId dialog_id = d->dialog_id;
@ -28947,7 +28951,7 @@ void MessagesManager::send_update_message_content_impl(DialogId dialog_id, const
void MessagesManager::send_update_message_edited(DialogId dialog_id, const Message *m) {
CHECK(m != nullptr);
cancel_user_dialog_action(dialog_id, m);
cancel_dialog_action(dialog_id, m);
auto edit_date = m->hide_edit_date ? 0 : m->edit_date;
send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateMessageEdited>(dialog_id.get(), m->message_id.get(), edit_date,
@ -29396,18 +29400,18 @@ void MessagesManager::send_update_chat_has_scheduled_messages(Dialog *d, bool fr
td_api::make_object<td_api::updateChatHasScheduledMessages>(d->dialog_id.get(), has_scheduled_messages));
}
void MessagesManager::send_update_user_chat_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_id,
const DialogAction &action) {
void MessagesManager::send_update_chat_action(DialogId dialog_id, MessageId top_thread_message_id,
DialogId typing_dialog_id, const DialogAction &action) {
if (td_->auth_manager_->is_bot()) {
return;
}
LOG(DEBUG) << "Send " << action << " of " << user_id << " in thread of " << top_thread_message_id << " in "
LOG(DEBUG) << "Send " << action << " of " << typing_dialog_id << " in thread of " << top_thread_message_id << " in "
<< dialog_id;
send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateUserChatAction>(
make_tl_object<td_api::updateChatAction>(
dialog_id.get(), top_thread_message_id.get(),
td_->contacts_manager_->get_user_id_object(user_id, "send_update_user_chat_action"),
get_message_sender_object(td_, typing_dialog_id, "send_update_chat_action"),
action.get_chat_action_object()));
}
@ -31533,12 +31537,12 @@ void MessagesManager::on_active_dialog_action_timeout(DialogId dialog_id) {
CHECK(!actions_it->second.empty());
auto now = Time::now();
UserId prev_user_id;
DialogId prev_typing_dialog_id;
while (actions_it->second[0].start_time + DIALOG_ACTION_TIMEOUT < now + 0.1) {
CHECK(actions_it->second[0].user_id != prev_user_id);
prev_user_id = actions_it->second[0].user_id;
on_user_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id,
DialogId(actions_it->second[0].user_id), DialogAction(), 0);
CHECK(actions_it->second[0].typing_dialog_id != prev_typing_dialog_id);
prev_typing_dialog_id = actions_it->second[0].typing_dialog_id;
on_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id, actions_it->second[0].typing_dialog_id,
DialogAction(), 0);
actions_it = active_dialog_actions_.find(dialog_id);
if (actions_it == active_dialog_actions_.end()) {
@ -31557,8 +31561,8 @@ void MessagesManager::clear_active_dialog_actions(DialogId dialog_id) {
auto actions_it = active_dialog_actions_.find(dialog_id);
while (actions_it != active_dialog_actions_.end()) {
CHECK(!actions_it->second.empty());
on_user_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id,
DialogId(actions_it->second[0].user_id), DialogAction(), 0);
on_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id, actions_it->second[0].typing_dialog_id,
DialogAction(), 0);
actions_it = active_dialog_actions_.find(dialog_id);
}
}
@ -33137,7 +33141,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
update_sent_message_contents(dialog_id, m);
update_used_hashtags(dialog_id, m);
update_top_dialogs(dialog_id, m);
cancel_user_dialog_action(dialog_id, m);
cancel_dialog_action(dialog_id, m);
update_has_outgoing_messages(dialog_id, m);
if (!td_->auth_manager_->is_bot() && d->messages == nullptr && !m->is_outgoing && dialog_id != get_my_dialog_id()) {

View File

@ -352,9 +352,9 @@ class MessagesManager final : public Actor {
void on_update_delete_scheduled_messages(DialogId dialog_id, vector<ScheduledServerMessageId> &&server_message_ids);
void on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id,
DialogAction action, int32 date,
MessageContentType message_content_type = MessageContentType::None);
void on_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id,
DialogAction action, int32 date,
MessageContentType message_content_type = MessageContentType::None);
void read_history_inbox(DialogId dialog_id, MessageId max_message_id, int32 unread_count, const char *source);
@ -2386,8 +2386,8 @@ class MessagesManager final : public Actor {
void send_update_chat_has_scheduled_messages(Dialog *d, bool from_deletion);
void send_update_user_chat_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_id,
const DialogAction &action);
void send_update_chat_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id,
const DialogAction &action);
void repair_dialog_action_bar(Dialog *d, const char *source);
@ -2552,7 +2552,7 @@ class MessagesManager final : public Actor {
void clear_active_dialog_actions(DialogId dialog_id);
void cancel_user_dialog_action(DialogId dialog_id, const Message *m);
void cancel_dialog_action(DialogId dialog_id, const Message *m);
Dialog *get_dialog_by_message_id(MessageId message_id);
@ -3037,8 +3037,6 @@ class MessagesManager final : public Actor {
void send_get_message_public_forwards_query(DcId dc_id, FullMessageId full_message_id, string offset, int32 limit,
Promise<td_api::object_ptr<td_api::foundMessages>> &&promise);
void on_animated_emoji_message_clicked(FullMessageId full_message_id, UserId user_id, Slice emoji, string data);
void add_sponsored_dialog(const Dialog *d, DialogSource source);
void save_sponsored_dialog();
@ -3377,13 +3375,14 @@ class MessagesManager final : public Actor {
struct ActiveDialogAction {
MessageId top_thread_message_id;
UserId user_id;
DialogId typing_dialog_id;
DialogAction action;
double start_time;
ActiveDialogAction(MessageId top_thread_message_id, UserId user_id, DialogAction action, double start_time)
ActiveDialogAction(MessageId top_thread_message_id, DialogId typing_dialog_id, DialogAction action,
double start_time)
: top_thread_message_id(top_thread_message_id)
, user_id(user_id)
, typing_dialog_id(typing_dialog_id)
, action(std::move(action))
, start_time(start_time) {
}

View File

@ -4229,7 +4229,7 @@ void Td::send_update(tl_object_ptr<td_api::Update> &&object) {
case td_api::updateUnreadMessageCount::ID / 2:
case td_api::updateUnreadChatCount::ID / 2:
case td_api::updateChatOnlineMemberCount::ID / 2:
case td_api::updateUserChatAction::ID / 2:
case td_api::updateChatAction::ID / 2:
case td_api::updateChatFilters::ID / 2:
case td_api::updateChatPosition::ID / 2:
LOG(ERROR) << "Sending update: " << oneline(to_string(object));

View File

@ -2850,15 +2850,14 @@ int32 UpdatesManager::get_update_qts(const telegram_api::Update *update) {
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateUserTyping> update, Promise<Unit> &&promise) {
DialogId dialog_id(UserId(update->user_id_));
td_->messages_manager_->on_user_dialog_action(dialog_id, MessageId(), dialog_id,
DialogAction(std::move(update->action_)), get_short_update_date());
td_->messages_manager_->on_dialog_action(dialog_id, MessageId(), dialog_id, DialogAction(std::move(update->action_)),
get_short_update_date());
promise.set_value(Unit());
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChatUserTyping> update, Promise<Unit> &&promise) {
td_->messages_manager_->on_user_dialog_action(DialogId(ChatId(update->chat_id_)), MessageId(),
DialogId(update->from_id_), DialogAction(std::move(update->action_)),
get_short_update_date());
td_->messages_manager_->on_dialog_action(DialogId(ChatId(update->chat_id_)), MessageId(), DialogId(update->from_id_),
DialogAction(std::move(update->action_)), get_short_update_date());
promise.set_value(Unit());
}
@ -2867,17 +2866,17 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChannelUserTypi
if ((update->flags_ & telegram_api::updateChannelUserTyping::TOP_MSG_ID_MASK) != 0) {
top_thread_message_id = MessageId(ServerMessageId(update->top_msg_id_));
}
td_->messages_manager_->on_user_dialog_action(DialogId(ChannelId(update->channel_id_)), top_thread_message_id,
DialogId(update->from_id_), DialogAction(std::move(update->action_)),
get_short_update_date());
td_->messages_manager_->on_dialog_action(DialogId(ChannelId(update->channel_id_)), top_thread_message_id,
DialogId(update->from_id_), DialogAction(std::move(update->action_)),
get_short_update_date());
promise.set_value(Unit());
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateEncryptedChatTyping> update, Promise<Unit> &&promise) {
SecretChatId secret_chat_id(update->chat_id_);
UserId user_id = td_->contacts_manager_->get_secret_chat_user_id(secret_chat_id);
td_->messages_manager_->on_user_dialog_action(DialogId(secret_chat_id), MessageId(), DialogId(user_id),
DialogAction::get_typing_action(), get_short_update_date());
td_->messages_manager_->on_dialog_action(DialogId(secret_chat_id), MessageId(), DialogId(user_id),
DialogAction::get_typing_action(), get_short_update_date());
promise.set_value(Unit());
}