Support receiving typings inside a message thread.

GitOrigin-RevId: ccedc84e6066d37835e560929c69c3f2cb010dcf
This commit is contained in:
levlam 2020-09-18 20:15:12 +03:00
parent bda5a3c5bd
commit 5b07557f3d
5 changed files with 40 additions and 25 deletions

View File

@ -3209,8 +3209,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 //@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; 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 @user_id Identifier of a user performing an action @action The action description //@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 user_id:int32 action:ChatAction = Update; updateUserChatAction chat_id:int53 message_thread_id:int53 user_id:int32 action:ChatAction = Update;
//@description The user went online or offline @user_id User identifier @status New status of the user //@description The user went online or offline @user_id User identifier @status New status of the user
updateUserStatus user_id:int32 status:UserStatus = Update; updateUserStatus user_id:int32 status:UserStatus = Update;
@ -3903,7 +3903,7 @@ getInlineGameHighScores inline_message_id:string user_id:int32 = GameHighScores;
deleteChatReplyMarkup chat_id:int53 message_id:int53 = Ok; deleteChatReplyMarkup chat_id:int53 message_id:int53 = Ok;
//@description Sends a notification about user activity in a chat @chat_id Chat identifier @message_thread_id If not 0, a message thread identifier of the action @action The action description //@description Sends a notification about user activity in a chat @chat_id Chat identifier @message_thread_id If not 0, a message thread identifier in which the action was performed @action The action description
sendChatAction chat_id:int53 message_thread_id:int53 action:ChatAction = Ok; sendChatAction chat_id:int53 message_thread_id:int53 action:ChatAction = Ok;

Binary file not shown.

View File

@ -6638,7 +6638,7 @@ bool MessagesManager::need_cancel_user_dialog_action(int32 action_id, MessageCon
} }
} }
void MessagesManager::on_user_dialog_action(DialogId dialog_id, UserId user_id, void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_id,
tl_object_ptr<td_api::ChatAction> &&action, int32 date, tl_object_ptr<td_api::ChatAction> &&action, int32 date,
MessageContentType message_content_type) { MessageContentType message_content_type) {
if (td_->auth_manager_->is_bot() || !user_id.is_valid() || is_broadcast_channel(dialog_id)) { if (td_->auth_manager_->is_bot() || !user_id.is_valid() || is_broadcast_channel(dialog_id)) {
@ -6669,6 +6669,7 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, UserId user_id,
} }
LOG(DEBUG) << "Cancel action of " << user_id << " in " << dialog_id; LOG(DEBUG) << "Cancel action of " << user_id << " in " << dialog_id;
top_thread_message_id = it->top_thread_message_id;
active_actions.erase(it); active_actions.erase(it);
if (active_actions.empty()) { if (active_actions.empty()) {
active_dialog_actions_.erase(dialog_id); active_dialog_actions_.erase(dialog_id);
@ -6686,10 +6687,12 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, UserId user_id,
auto &active_actions = active_dialog_actions_[dialog_id]; auto &active_actions = active_dialog_actions_[dialog_id];
auto it = std::find_if(active_actions.begin(), active_actions.end(), auto it = std::find_if(active_actions.begin(), active_actions.end(),
[user_id](const ActiveDialogAction &action) { return action.user_id == user_id; }); [user_id](const ActiveDialogAction &action) { return action.user_id == user_id; });
MessageId prev_top_thread_message_id;
int32 prev_action_id = 0; int32 prev_action_id = 0;
int32 prev_progress = 0; int32 prev_progress = 0;
if (it != active_actions.end()) { if (it != active_actions.end()) {
LOG(DEBUG) << "Re-add action of " << user_id << " in " << dialog_id; LOG(DEBUG) << "Re-add action of " << user_id << " in " << dialog_id;
prev_top_thread_message_id = it->top_thread_message_id;
prev_action_id = it->action_id; prev_action_id = it->action_id;
prev_progress = it->progress; prev_progress = it->progress;
active_actions.erase(it); active_actions.erase(it);
@ -6714,10 +6717,18 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, UserId user_id,
return 0; return 0;
} }
}(); }();
active_actions.emplace_back(user_id, action_id, Time::now()); active_actions.emplace_back(top_thread_message_id, user_id, action_id, Time::now());
if (action_id == prev_action_id && progress <= prev_progress) { if (top_thread_message_id == prev_top_thread_message_id && action_id == prev_action_id &&
progress <= prev_progress) {
return; return;
} }
if (top_thread_message_id != prev_top_thread_message_id) {
send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateUserChatAction>(
dialog_id.get(), prev_top_thread_message_id.get(),
td_->contacts_manager_->get_user_id_object(user_id, "on_user_dialog_action"),
make_tl_object<td_api::chatActionCancel>()));
}
if (active_actions.size() == 1u) { if (active_actions.size() == 1u) {
LOG(DEBUG) << "Set action timeout in " << dialog_id; LOG(DEBUG) << "Set action timeout in " << dialog_id;
active_dialog_action_timeout_.set_timeout_in(dialog_id.get(), DIALOG_ACTION_TIMEOUT); active_dialog_action_timeout_.set_timeout_in(dialog_id.get(), DIALOG_ACTION_TIMEOUT);
@ -6727,8 +6738,8 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, UserId user_id,
LOG(DEBUG) << "Send action of " << user_id << " in " << dialog_id << ": " << to_string(action); LOG(DEBUG) << "Send action of " << user_id << " in " << dialog_id << ": " << to_string(action);
send_closure(G()->td(), &Td::send_update, send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateUserChatAction>( make_tl_object<td_api::updateUserChatAction>(
dialog_id.get(), td_->contacts_manager_->get_user_id_object(user_id, "on_user_dialog_action"), dialog_id.get(), top_thread_message_id.get(),
std::move(action))); td_->contacts_manager_->get_user_id_object(user_id, "on_user_dialog_action"), std::move(action)));
} }
void MessagesManager::cancel_user_dialog_action(DialogId dialog_id, const Message *m) { void MessagesManager::cancel_user_dialog_action(DialogId dialog_id, const Message *m) {
@ -6738,7 +6749,7 @@ void MessagesManager::cancel_user_dialog_action(DialogId dialog_id, const Messag
return; return;
} }
on_user_dialog_action(dialog_id, m->sender_user_id, nullptr, m->date, m->content->get_type()); on_user_dialog_action(dialog_id, MessageId(), m->sender_user_id, nullptr, m->date, m->content->get_type());
} }
void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_ptr<telegram_api::Update> &&update, void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_ptr<telegram_api::Update> &&update,
@ -28068,7 +28079,8 @@ void MessagesManager::on_active_dialog_action_timeout(DialogId dialog_id) {
auto now = Time::now(); auto now = Time::now();
while (actions_it->second[0].start_time + DIALOG_ACTION_TIMEOUT < now + 0.1) { while (actions_it->second[0].start_time + DIALOG_ACTION_TIMEOUT < now + 0.1) {
on_user_dialog_action(dialog_id, actions_it->second[0].user_id, nullptr, 0); on_user_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id, actions_it->second[0].user_id,
nullptr, 0);
actions_it = active_dialog_actions_.find(dialog_id); actions_it = active_dialog_actions_.find(dialog_id);
if (actions_it == active_dialog_actions_.end()) { if (actions_it == active_dialog_actions_.end()) {
@ -28087,7 +28099,8 @@ void MessagesManager::clear_active_dialog_actions(DialogId dialog_id) {
auto actions_it = active_dialog_actions_.find(dialog_id); auto actions_it = active_dialog_actions_.find(dialog_id);
while (actions_it != active_dialog_actions_.end()) { while (actions_it != active_dialog_actions_.end()) {
CHECK(!actions_it->second.empty()); CHECK(!actions_it->second.empty());
on_user_dialog_action(dialog_id, actions_it->second[0].user_id, nullptr, 0); on_user_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id, actions_it->second[0].user_id,
nullptr, 0);
actions_it = active_dialog_actions_.find(dialog_id); actions_it = active_dialog_actions_.find(dialog_id);
} }
} }

View File

@ -364,7 +364,8 @@ class MessagesManager : public Actor {
void on_update_delete_scheduled_messages(DialogId dialog_id, vector<ScheduledServerMessageId> &&server_message_ids); void on_update_delete_scheduled_messages(DialogId dialog_id, vector<ScheduledServerMessageId> &&server_message_ids);
void on_user_dialog_action(DialogId dialog_id, UserId user_id, tl_object_ptr<td_api::ChatAction> &&action, int32 date, void on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_id,
tl_object_ptr<td_api::ChatAction> &&action, int32 date,
MessageContentType message_content_type = MessageContentType::None); MessageContentType message_content_type = MessageContentType::None);
void read_history_inbox(DialogId dialog_id, MessageId max_message_id, int32 unread_count, const char *source); void read_history_inbox(DialogId dialog_id, MessageId max_message_id, int32 unread_count, const char *source);
@ -3017,13 +3018,14 @@ class MessagesManager : public Actor {
std::unordered_map<FullMessageId, int32, FullMessageIdHash> replied_by_yet_unsent_messages_; std::unordered_map<FullMessageId, int32, FullMessageIdHash> replied_by_yet_unsent_messages_;
struct ActiveDialogAction { struct ActiveDialogAction {
MessageId top_thread_message_id;
UserId user_id; UserId user_id;
int32 action_id; int32 action_id;
int32 progress; int32 progress;
double start_time; double start_time;
ActiveDialogAction(UserId user_id, int32 action_id, double start_time) ActiveDialogAction(MessageId top_thread_message_id, UserId user_id, int32 action_id, double start_time)
: user_id(user_id), action_id(action_id), start_time(start_time) { : top_thread_message_id(top_thread_message_id), user_id(user_id), action_id(action_id), start_time(start_time) {
} }
}; };

View File

@ -1883,8 +1883,9 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateUserTyping> upd
LOG(DEBUG) << "Ignore user typing in unknown " << dialog_id; LOG(DEBUG) << "Ignore user typing in unknown " << dialog_id;
return; return;
} }
td_->messages_manager_->on_user_dialog_action( td_->messages_manager_->on_user_dialog_action(dialog_id, MessageId(), user_id,
dialog_id, user_id, convert_send_message_action(std::move(update->action_)), get_short_update_date()); convert_send_message_action(std::move(update->action_)),
get_short_update_date());
} }
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChatUserTyping> update, bool /*force_apply*/) { void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChatUserTyping> update, bool /*force_apply*/) {
@ -1898,8 +1899,9 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChatUserTyping>
LOG(DEBUG) << "Ignore user chat typing in unknown " << dialog_id; LOG(DEBUG) << "Ignore user chat typing in unknown " << dialog_id;
return; return;
} }
td_->messages_manager_->on_user_dialog_action( td_->messages_manager_->on_user_dialog_action(dialog_id, MessageId(), user_id,
dialog_id, user_id, convert_send_message_action(std::move(update->action_)), get_short_update_date()); convert_send_message_action(std::move(update->action_)),
get_short_update_date());
} }
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChannelUserTyping> update, bool /*force_apply*/) { void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChannelUserTyping> update, bool /*force_apply*/) {
@ -1921,11 +1923,9 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChannelUserTypi
return; return;
} }
} }
if (top_reply_message_id.is_valid()) { td_->messages_manager_->on_user_dialog_action(dialog_id, top_reply_message_id, user_id,
return; convert_send_message_action(std::move(update->action_)),
} get_short_update_date());
td_->messages_manager_->on_user_dialog_action(
dialog_id, user_id, convert_send_message_action(std::move(update->action_)), get_short_update_date());
} }
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateEncryptedChatTyping> update, bool /*force_apply*/) { void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateEncryptedChatTyping> update, bool /*force_apply*/) {
@ -1943,8 +1943,8 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateEncryptedChatTy
return; return;
} }
td_->messages_manager_->on_user_dialog_action(dialog_id, user_id, make_tl_object<td_api::chatActionTyping>(), td_->messages_manager_->on_user_dialog_action(dialog_id, MessageId(), user_id,
get_short_update_date()); make_tl_object<td_api::chatActionTyping>(), get_short_update_date());
} }
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateUserStatus> update, bool /*force_apply*/) { void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateUserStatus> update, bool /*force_apply*/) {