From 711b0cfd4f2aa163858b94e97db25d6be4adcfcb Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 1 Oct 2020 19:28:10 +0300 Subject: [PATCH] Introduce DialogAction class. GitOrigin-RevId: f94011c1b70cdc17115bfbb981c6e000110adfbf --- CMakeLists.txt | 2 + td/telegram/DialogAction.cpp | 376 ++++++++++++++++++++++++++++ td/telegram/DialogAction.h | 73 ++++++ td/telegram/DialogAdministrator.cpp | 2 +- td/telegram/MessagesManager.cpp | 325 +++--------------------- td/telegram/MessagesManager.h | 23 +- td/telegram/Td.cpp | 3 +- td/telegram/UpdatesManager.cpp | 61 +---- td/telegram/UpdatesManager.h | 3 - 9 files changed, 500 insertions(+), 368 deletions(-) create mode 100644 td/telegram/DialogAction.cpp create mode 100644 td/telegram/DialogAction.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3287a7501..dd278bc3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -400,6 +400,7 @@ set(TDLIB_SOURCE td/telegram/Dependencies.cpp td/telegram/DeviceTokenManager.cpp td/telegram/DhCache.cpp + td/telegram/DialogAction.cpp td/telegram/DialogAdministrator.cpp td/telegram/DialogDb.cpp td/telegram/DialogFilter.cpp @@ -559,6 +560,7 @@ set(TDLIB_SOURCE td/telegram/DeviceTokenManager.h td/telegram/DhCache.h td/telegram/DhConfig.h + td/telegram/DialogAction.h td/telegram/DialogAdministrator.h td/telegram/DialogDate.h td/telegram/DialogDb.h diff --git a/td/telegram/DialogAction.cpp b/td/telegram/DialogAction.cpp new file mode 100644 index 000000000..6ec236332 --- /dev/null +++ b/td/telegram/DialogAction.cpp @@ -0,0 +1,376 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/DialogAction.h" + +namespace td { + +void DialogAction::init(Type type) { + type_ = type; + progress_ = 0; +} + +void DialogAction::init(Type type, int32 progress) { + if (progress < 0 || progress > 100) { + progress = 0; + } + type_ = type; + progress_ = progress; +} + +DialogAction::DialogAction(Type type, int32 progress) { + init(type, progress); +} + +DialogAction::DialogAction(tl_object_ptr &&action) { + if (action == nullptr) { + return; + } + + switch (action->get_id()) { + case td_api::chatActionCancel::ID: + init(Type::Cancel); + break; + case td_api::chatActionTyping::ID: + init(Type::Typing); + break; + case td_api::chatActionRecordingVideo::ID: + init(Type::RecordingVideo); + break; + case td_api::chatActionUploadingVideo::ID: { + auto uploading_action = move_tl_object_as(action); + init(Type::UploadingVideo, uploading_action->progress_); + break; + } + case td_api::chatActionRecordingVoiceNote::ID: + init(Type::RecordingVoiceNote); + break; + case td_api::chatActionUploadingVoiceNote::ID: { + auto uploading_action = move_tl_object_as(action); + init(Type::UploadingVoiceNote, uploading_action->progress_); + break; + } + case td_api::chatActionUploadingPhoto::ID: { + auto uploading_action = move_tl_object_as(action); + init(Type::UploadingPhoto, uploading_action->progress_); + break; + } + case td_api::chatActionUploadingDocument::ID: { + auto uploading_action = move_tl_object_as(action); + init(Type::UploadingDocument, uploading_action->progress_); + break; + } + case td_api::chatActionChoosingLocation::ID: + init(Type::ChoosingLocation); + break; + case td_api::chatActionChoosingContact::ID: + init(Type::ChoosingContact); + break; + case td_api::chatActionStartPlayingGame::ID: + init(Type::StartPlayingGame); + break; + case td_api::chatActionRecordingVideoNote::ID: + init(Type::RecordingVideoNote); + break; + case td_api::chatActionUploadingVideoNote::ID: { + auto uploading_action = move_tl_object_as(action); + init(Type::UploadingVideoNote, uploading_action->progress_); + break; + } + default: + UNREACHABLE(); + break; + } +} + +DialogAction::DialogAction(tl_object_ptr &&action) { + switch (action->get_id()) { + case telegram_api::sendMessageCancelAction::ID: + init(Type::Cancel); + break; + case telegram_api::sendMessageTypingAction::ID: + init(Type::Typing); + break; + case telegram_api::sendMessageRecordVideoAction::ID: + init(Type::RecordingVideo); + break; + case telegram_api::sendMessageUploadVideoAction::ID: { + auto upload_video_action = move_tl_object_as(action); + init(Type::UploadingVideo, upload_video_action->progress_); + break; + } + case telegram_api::sendMessageRecordAudioAction::ID: + init(Type::RecordingVoiceNote); + break; + case telegram_api::sendMessageUploadAudioAction::ID: { + auto upload_audio_action = move_tl_object_as(action); + init(Type::UploadingVoiceNote, upload_audio_action->progress_); + break; + } + case telegram_api::sendMessageUploadPhotoAction::ID: { + auto upload_photo_action = move_tl_object_as(action); + init(Type::UploadingPhoto, upload_photo_action->progress_); + break; + } + case telegram_api::sendMessageUploadDocumentAction::ID: { + auto upload_document_action = move_tl_object_as(action); + init(Type::UploadingDocument, upload_document_action->progress_); + break; + } + case telegram_api::sendMessageGeoLocationAction::ID: + init(Type::ChoosingLocation); + break; + case telegram_api::sendMessageChooseContactAction::ID: + init(Type::ChoosingContact); + break; + case telegram_api::sendMessageGamePlayAction::ID: + init(Type::StartPlayingGame); + break; + case telegram_api::sendMessageRecordRoundAction::ID: + init(Type::RecordingVideoNote); + break; + case telegram_api::sendMessageUploadRoundAction::ID: { + auto upload_round_action = move_tl_object_as(action); + init(Type::UploadingVideoNote, upload_round_action->progress_); + break; + } + default: + UNREACHABLE(); + break; + } +} + +tl_object_ptr DialogAction::get_input_send_message_action() const { + switch (type_) { + case Type::Cancel: + return make_tl_object(); + case Type::Typing: + return make_tl_object(); + case Type::RecordingVideo: + return make_tl_object(); + case Type::UploadingVideo: + return make_tl_object(progress_); + case Type::RecordingVoiceNote: + return make_tl_object(); + case Type::UploadingVoiceNote: + return make_tl_object(progress_); + case Type::UploadingPhoto: + return make_tl_object(progress_); + case Type::UploadingDocument: + return make_tl_object(progress_); + case Type::ChoosingLocation: + return make_tl_object(); + case Type::ChoosingContact: + return make_tl_object(); + case Type::RecordingVideoNote: + return make_tl_object(); + case Type::UploadingVideoNote: + return make_tl_object(progress_); + case Type::StartPlayingGame: + return make_tl_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +tl_object_ptr DialogAction::get_secret_input_send_message_action() const { + switch (type_) { + case Type::Cancel: + return make_tl_object(); + case Type::Typing: + return make_tl_object(); + case Type::RecordingVideo: + return make_tl_object(); + case Type::UploadingVideo: + return make_tl_object(); + case Type::RecordingVoiceNote: + return make_tl_object(); + case Type::UploadingVoiceNote: + return make_tl_object(); + case Type::UploadingPhoto: + return make_tl_object(); + case Type::UploadingDocument: + return make_tl_object(); + case Type::ChoosingLocation: + return make_tl_object(); + case Type::ChoosingContact: + return make_tl_object(); + case Type::RecordingVideoNote: + return make_tl_object(); + case Type::UploadingVideoNote: + return make_tl_object(); + case Type::StartPlayingGame: + return make_tl_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +tl_object_ptr DialogAction::get_chat_action_object() const { + switch (type_) { + case Type::Cancel: + return td_api::make_object(); + case Type::Typing: + return td_api::make_object(); + case Type::RecordingVideo: + return td_api::make_object(); + case Type::UploadingVideo: + return td_api::make_object(progress_); + case Type::RecordingVoiceNote: + return td_api::make_object(); + case Type::UploadingVoiceNote: + return td_api::make_object(progress_); + case Type::UploadingPhoto: + return td_api::make_object(progress_); + case Type::UploadingDocument: + return td_api::make_object(progress_); + case Type::ChoosingLocation: + return td_api::make_object(); + case Type::ChoosingContact: + return td_api::make_object(); + case Type::StartPlayingGame: + return td_api::make_object(); + case Type::RecordingVideoNote: + return td_api::make_object(); + case Type::UploadingVideoNote: + return td_api::make_object(progress_); + default: + UNREACHABLE(); + return td_api::make_object(); + } +} + +bool DialogAction::is_cancelled_by_message_of_type(MessageContentType message_content_type) const { + if (message_content_type == MessageContentType::None) { + return true; + } + + if (type_ == Type::Typing) { + return message_content_type == MessageContentType::Text || message_content_type == MessageContentType::Game || + can_have_message_content_caption(message_content_type); + } + + switch (message_content_type) { + case MessageContentType::Animation: + case MessageContentType::Audio: + case MessageContentType::Document: + return type_ == Type::UploadingDocument; + case MessageContentType::ExpiredPhoto: + case MessageContentType::Photo: + return type_ == Type::UploadingPhoto; + case MessageContentType::ExpiredVideo: + case MessageContentType::Video: + return type_ == Type::RecordingVideo || type_ == Type::UploadingVideo; + case MessageContentType::VideoNote: + return type_ == Type::RecordingVideoNote || type_ == Type::UploadingVideoNote; + case MessageContentType::VoiceNote: + return type_ == Type::RecordingVoiceNote || type_ == Type::UploadingVoiceNote; + case MessageContentType::Contact: + return type_ == Type::ChoosingContact; + case MessageContentType::LiveLocation: + case MessageContentType::Location: + case MessageContentType::Venue: + return type_ == Type::ChoosingLocation; + case MessageContentType::Game: + case MessageContentType::Invoice: + case MessageContentType::Sticker: + case MessageContentType::Text: + case MessageContentType::Unsupported: + case MessageContentType::ChatCreate: + case MessageContentType::ChatChangeTitle: + case MessageContentType::ChatChangePhoto: + case MessageContentType::ChatDeletePhoto: + case MessageContentType::ChatDeleteHistory: + case MessageContentType::ChatAddUsers: + case MessageContentType::ChatJoinedByLink: + case MessageContentType::ChatDeleteUser: + case MessageContentType::ChatMigrateTo: + case MessageContentType::ChannelCreate: + case MessageContentType::ChannelMigrateFrom: + case MessageContentType::PinMessage: + case MessageContentType::GameScore: + case MessageContentType::ScreenshotTaken: + case MessageContentType::ChatSetTtl: + case MessageContentType::Call: + case MessageContentType::PaymentSuccessful: + case MessageContentType::ContactRegistered: + case MessageContentType::CustomServiceAction: + case MessageContentType::WebsiteConnected: + case MessageContentType::PassportDataSent: + case MessageContentType::PassportDataReceived: + case MessageContentType::Poll: + case MessageContentType::Dice: + return false; + default: + UNREACHABLE(); + return false; + } +} + +DialogAction DialogAction::get_uploading_action(MessageContentType message_content_type, int32 progress) { + switch (message_content_type) { + case MessageContentType::Animation: + case MessageContentType::Audio: + case MessageContentType::Document: + return DialogAction(Type::UploadingDocument, progress); + case MessageContentType::Photo: + return DialogAction(Type::UploadingPhoto, progress); + case MessageContentType::Video: + return DialogAction(Type::UploadingVideo, progress); + case MessageContentType::VideoNote: + return DialogAction(Type::UploadingVideoNote, progress); + case MessageContentType::VoiceNote: + return DialogAction(Type::UploadingVoiceNote, progress); + default: + return DialogAction(); + } +} + +StringBuilder &operator<<(StringBuilder &string_builder, const DialogAction &action) { + string_builder << "ChatAction"; + const char *type = [action_type = action.type_] { + switch (action_type) { + case DialogAction::Type::Cancel: + return "Cancel"; + case DialogAction::Type::Typing: + return "Typing"; + case DialogAction::Type::RecordingVideo: + return "RecordingVideo"; + case DialogAction::Type::UploadingVideo: + return "UploadingVideo"; + case DialogAction::Type::RecordingVoiceNote: + return "RecordingVoiceNote"; + case DialogAction::Type::UploadingVoiceNote: + return "UploadingVoiceNote"; + case DialogAction::Type::UploadingPhoto: + return "UploadingPhoto"; + case DialogAction::Type::UploadingDocument: + return "UploadingDocument"; + case DialogAction::Type::ChoosingLocation: + return "ChoosingLocation"; + case DialogAction::Type::ChoosingContact: + return "ChoosingContact"; + case DialogAction::Type::StartPlayingGame: + return "StartPlayingGame"; + case DialogAction::Type::RecordingVideoNote: + return "RecordingVideoNote"; + case DialogAction::Type::UploadingVideoNote: + return "UploadingVideoNote"; + default: + UNREACHABLE(); + return "Cancel"; + } + }(); + string_builder << type << "Action"; + if (action.progress_ != 0) { + string_builder << '(' << action.progress_ << "%)"; + } + return string_builder; +} + +} // namespace td diff --git a/td/telegram/DialogAction.h b/td/telegram/DialogAction.h new file mode 100644 index 000000000..f8a553af4 --- /dev/null +++ b/td/telegram/DialogAction.h @@ -0,0 +1,73 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageContentType.h" +#include "td/telegram/secret_api.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +class DialogAction { + public: + enum class Type : int32 { + Cancel, + Typing, + RecordingVideo, + UploadingVideo, + RecordingVoiceNote, + UploadingVoiceNote, + UploadingPhoto, + UploadingDocument, + ChoosingLocation, + ChoosingContact, + StartPlayingGame, + RecordingVideoNote, + UploadingVideoNote + }; + Type type_ = Type::Cancel; + int32 progress_ = 0; + + DialogAction() = default; + + DialogAction(Type type, int32 progress); + + explicit DialogAction(tl_object_ptr &&action); + + explicit DialogAction(tl_object_ptr &&action); + + tl_object_ptr get_input_send_message_action() const; + + tl_object_ptr get_secret_input_send_message_action() const; + + td_api::object_ptr get_chat_action_object() const; + + bool is_cancelled_by_message_of_type(MessageContentType message_content_type) const; + + static DialogAction get_uploading_action(MessageContentType message_content_type, int32 progress); + + private: + void init(Type type); + void init(Type type, int32 progress); +}; + +inline bool operator==(const DialogAction &lhs, const DialogAction &rhs) { + return lhs.type_ == rhs.type_ && lhs.progress_ == rhs.progress_; +} + +inline bool operator!=(const DialogAction &lhs, const DialogAction &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const DialogAction &action); + +} // namespace td diff --git a/td/telegram/DialogAdministrator.cpp b/td/telegram/DialogAdministrator.cpp index 76dcccbf3..9bb4a8de0 100644 --- a/td/telegram/DialogAdministrator.cpp +++ b/td/telegram/DialogAdministrator.cpp @@ -19,7 +19,7 @@ td_api::object_ptr DialogAdministrator::get_chat_admi } StringBuilder &operator<<(StringBuilder &string_builder, const DialogAdministrator &administrator) { - return string_builder << "DialogAdministrator[" << administrator.user_id_ << ", title = " << administrator.rank_ + return string_builder << "ChatAdministrator[" << administrator.user_id_ << ", title = " << administrator.rank_ << ", is_owner = " << administrator.is_creator_ << "]"; } diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 6a054763c..bf7c86a5c 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -6825,87 +6825,17 @@ void MessagesManager::on_update_delete_scheduled_messages(DialogId dialog_id, send_update_chat_has_scheduled_messages(d, true); } -bool MessagesManager::need_cancel_user_dialog_action(int32 action_id, MessageContentType message_content_type) { - if (message_content_type == MessageContentType::None) { - return true; - } - - if (action_id == td_api::chatActionTyping::ID) { - return message_content_type == MessageContentType::Text || message_content_type == MessageContentType::Game || - can_have_message_content_caption(message_content_type); - } - - switch (message_content_type) { - case MessageContentType::Animation: - case MessageContentType::Audio: - case MessageContentType::Document: - return action_id == td_api::chatActionUploadingDocument::ID; - case MessageContentType::ExpiredPhoto: - case MessageContentType::Photo: - return action_id == td_api::chatActionUploadingPhoto::ID; - case MessageContentType::ExpiredVideo: - case MessageContentType::Video: - return action_id == td_api::chatActionRecordingVideo::ID || action_id == td_api::chatActionUploadingVideo::ID; - case MessageContentType::VideoNote: - return action_id == td_api::chatActionRecordingVideoNote::ID || - action_id == td_api::chatActionUploadingVideoNote::ID; - case MessageContentType::VoiceNote: - return action_id == td_api::chatActionRecordingVoiceNote::ID || - action_id == td_api::chatActionUploadingVoiceNote::ID; - case MessageContentType::Contact: - return action_id == td_api::chatActionChoosingContact::ID; - case MessageContentType::LiveLocation: - case MessageContentType::Location: - case MessageContentType::Venue: - return action_id == td_api::chatActionChoosingLocation::ID; - case MessageContentType::Game: - case MessageContentType::Invoice: - case MessageContentType::Sticker: - case MessageContentType::Text: - case MessageContentType::Unsupported: - case MessageContentType::ChatCreate: - case MessageContentType::ChatChangeTitle: - case MessageContentType::ChatChangePhoto: - case MessageContentType::ChatDeletePhoto: - case MessageContentType::ChatDeleteHistory: - case MessageContentType::ChatAddUsers: - case MessageContentType::ChatJoinedByLink: - case MessageContentType::ChatDeleteUser: - case MessageContentType::ChatMigrateTo: - case MessageContentType::ChannelCreate: - case MessageContentType::ChannelMigrateFrom: - case MessageContentType::PinMessage: - case MessageContentType::GameScore: - case MessageContentType::ScreenshotTaken: - case MessageContentType::ChatSetTtl: - case MessageContentType::Call: - case MessageContentType::PaymentSuccessful: - case MessageContentType::ContactRegistered: - case MessageContentType::CustomServiceAction: - case MessageContentType::WebsiteConnected: - case MessageContentType::PassportDataSent: - case MessageContentType::PassportDataReceived: - case MessageContentType::Poll: - case MessageContentType::Dice: - return false; - default: - UNREACHABLE(); - return false; - } -} - void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_id, - tl_object_ptr &&action, int32 date, - MessageContentType message_content_type) { + DialogAction action, int32 date, MessageContentType message_content_type) { if (td_->auth_manager_->is_bot() || !user_id.is_valid() || is_broadcast_channel(dialog_id)) { return; } - if (action != nullptr || message_content_type != MessageContentType::None) { + 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); } - bool is_canceled = action == nullptr || action->get_id() == td_api::chatActionCancel::ID; if (is_canceled) { auto actions_it = active_dialog_actions_.find(dialog_id); if (actions_it == active_dialog_actions_.end()) { @@ -6920,7 +6850,7 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th } if (!td_->contacts_manager_->is_user_bot(user_id) && - !need_cancel_user_dialog_action(it->action_id, message_content_type)) { + !it->action.is_cancelled_by_message_of_type(message_content_type)) { return; } @@ -6932,9 +6862,6 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th LOG(DEBUG) << "Cancel action timeout in " << dialog_id; active_dialog_action_timeout_.cancel_timeout(dialog_id.get()); } - if (action == nullptr) { - action = make_tl_object(); - } } 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; @@ -6944,43 +6871,22 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th auto it = std::find_if(active_actions.begin(), active_actions.end(), [user_id](const ActiveDialogAction &action) { return action.user_id == user_id; }); MessageId prev_top_thread_message_id; - int32 prev_action_id = 0; - int32 prev_progress = 0; + DialogAction prev_action; if (it != active_actions.end()) { 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_progress = it->progress; + prev_action = it->action; active_actions.erase(it); } else { LOG(DEBUG) << "Add action of " << user_id << " in " << dialog_id; } - auto action_id = action->get_id(); - auto progress = [&] { - switch (action_id) { - case td_api::chatActionUploadingVideo::ID: - return static_cast(*action).progress_; - case td_api::chatActionUploadingVoiceNote::ID: - return static_cast(*action).progress_; - case td_api::chatActionUploadingPhoto::ID: - return static_cast(*action).progress_; - case td_api::chatActionUploadingDocument::ID: - return static_cast(*action).progress_; - case td_api::chatActionUploadingVideoNote::ID: - return static_cast(*action).progress_; - default: - return 0; - } - }(); - active_actions.emplace_back(top_thread_message_id, user_id, action_id, Time::now()); - if (top_thread_message_id == prev_top_thread_message_id && action_id == prev_action_id && - progress <= prev_progress) { + active_actions.emplace_back(top_thread_message_id, user_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, - td_api::make_object()); + send_update_user_chat_action(dialog_id, prev_top_thread_message_id, user_id, DialogAction()); } if (active_actions.size() == 1u) { LOG(DEBUG) << "Set action timeout in " << dialog_id; @@ -6989,9 +6895,9 @@ 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, copy_chat_action_object(action)); + send_update_user_chat_action(dialog_id, MessageId(), user_id, action); } - send_update_user_chat_action(dialog_id, top_thread_message_id, user_id, std::move(action)); + send_update_user_chat_action(dialog_id, top_thread_message_id, user_id, action); } void MessagesManager::cancel_user_dialog_action(DialogId dialog_id, const Message *m) { @@ -7001,7 +6907,7 @@ void MessagesManager::cancel_user_dialog_action(DialogId dialog_id, const Messag return; } - on_user_dialog_action(dialog_id, MessageId(), m->sender_user_id, nullptr, m->date, m->content->get_type()); + on_user_dialog_action(dialog_id, MessageId(), m->sender_user_id, DialogAction(), m->date, m->content->get_type()); } void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_ptr &&update, @@ -7746,7 +7652,7 @@ void MessagesManager::repair_dialog_action_bar(Dialog *d, const char *source) { d->know_action_bar = false; if (have_input_peer(dialog_id, AccessRights::Read)) { create_actor( - "RepairDialogActionBarActor", 1.0, + "RepairChatActionBarActor", 1.0, PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, source](Result result) { send_closure(actor_id, &MessagesManager::reget_dialog_action_bar, dialog_id, source); })) @@ -27276,18 +27182,18 @@ void MessagesManager::send_update_chat_has_scheduled_messages(Dialog *d, bool fr } void MessagesManager::send_update_user_chat_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_id, - td_api::object_ptr action) { + DialogAction action) { if (td_->auth_manager_->is_bot()) { return; } - LOG(DEBUG) << "Send action of " << user_id << " in thread of " << top_thread_message_id << " in " << dialog_id << ": " - << to_string(action); - send_closure( - G()->td(), &Td::send_update, - make_tl_object( - dialog_id.get(), top_thread_message_id.get(), - td_->contacts_manager_->get_user_id_object(user_id, "send_update_user_chat_action"), std::move(action))); + LOG(DEBUG) << "Send " << action << " of " << user_id << " in thread of " << top_thread_message_id << " in " + << dialog_id; + send_closure(G()->td(), &Td::send_update, + make_tl_object( + dialog_id.get(), top_thread_message_id.get(), + td_->contacts_manager_->get_user_id_object(user_id, "send_update_user_chat_action"), + action.get_chat_action_object())); } void MessagesManager::on_send_message_get_quick_ack(int64 random_id) { @@ -28921,58 +28827,8 @@ bool MessagesManager::is_dialog_action_unneeded(DialogId dialog_id) const { return false; } -tl_object_ptr MessagesManager::copy_chat_action_object( - const tl_object_ptr &action) { - CHECK(action != nullptr); - switch (action->get_id()) { - case td_api::chatActionCancel::ID: - return make_tl_object(); - case td_api::chatActionTyping::ID: - return make_tl_object(); - case td_api::chatActionRecordingVideo::ID: - return make_tl_object(); - case td_api::chatActionUploadingVideo::ID: { - auto progress = static_cast(*action).progress_; - return make_tl_object(progress); - } - case td_api::chatActionRecordingVoiceNote::ID: - return make_tl_object(); - case td_api::chatActionUploadingVoiceNote::ID: { - auto progress = static_cast(*action).progress_; - return make_tl_object(progress); - } - case td_api::chatActionUploadingPhoto::ID: { - auto progress = static_cast(*action).progress_; - return make_tl_object(progress); - } - case td_api::chatActionUploadingDocument::ID: { - auto progress = static_cast(*action).progress_; - return make_tl_object(progress); - } - case td_api::chatActionChoosingLocation::ID: - return make_tl_object(); - case td_api::chatActionChoosingContact::ID: - return make_tl_object(); - case td_api::chatActionStartPlayingGame::ID: - return make_tl_object(); - case td_api::chatActionRecordingVideoNote::ID: - return make_tl_object(); - case td_api::chatActionUploadingVideoNote::ID: { - auto progress = static_cast(*action).progress_; - return make_tl_object(progress); - } - default: - UNREACHABLE(); - return nullptr; - } -} - -void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, - const tl_object_ptr &action, Promise &&promise) { - if (action == nullptr) { - return promise.set_error(Status::Error(5, "Action must be non-empty")); - } - +void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogAction action, + Promise &&promise) { if (!have_dialog_force(dialog_id)) { return promise.set_error(Status::Error(5, "Chat not found")); } @@ -28994,117 +28850,19 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_threa } if (dialog_id.get_type() == DialogType::SecretChat) { - tl_object_ptr send_action; - switch (action->get_id()) { - case td_api::chatActionCancel::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionTyping::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionRecordingVideo::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionUploadingVideo::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionRecordingVoiceNote::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionUploadingVoiceNote::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionUploadingPhoto::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionUploadingDocument::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionChoosingLocation::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionChoosingContact::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionRecordingVideoNote::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionUploadingVideoNote::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionStartPlayingGame::ID: - return promise.set_error(Status::Error(5, "Games are unsupported in secret chats")); - default: - UNREACHABLE(); - } send_closure(G()->secret_chats_manager(), &SecretChatsManager::send_message_action, dialog_id.get_secret_chat_id(), - std::move(send_action)); + action.get_secret_input_send_message_action()); promise.set_value(Unit()); return; } - tl_object_ptr send_action; - switch (action->get_id()) { - case td_api::chatActionCancel::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionTyping::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionRecordingVideo::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionUploadingVideo::ID: { - auto progress = static_cast(*action).progress_; - send_action = make_tl_object(progress); - break; - } - case td_api::chatActionRecordingVoiceNote::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionUploadingVoiceNote::ID: { - auto progress = static_cast(*action).progress_; - send_action = make_tl_object(progress); - break; - } - case td_api::chatActionUploadingPhoto::ID: { - auto progress = static_cast(*action).progress_; - send_action = make_tl_object(progress); - break; - } - case td_api::chatActionUploadingDocument::ID: { - auto progress = static_cast(*action).progress_; - send_action = make_tl_object(progress); - break; - } - case td_api::chatActionChoosingLocation::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionChoosingContact::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionStartPlayingGame::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionRecordingVideoNote::ID: - send_action = make_tl_object(); - break; - case td_api::chatActionUploadingVideoNote::ID: { - auto progress = static_cast(*action).progress_; - send_action = make_tl_object(progress); - break; - } - default: - UNREACHABLE(); - } - auto &query_ref = set_typing_query_[dialog_id]; if (!query_ref.empty() && !td_->auth_manager_->is_bot()) { LOG(INFO) << "Cancel previous set typing query"; cancel_query(query_ref); } query_ref = td_->create_handler(std::move(promise)) - ->send(dialog_id, top_thread_message_id, std::move(send_action)); + ->send(dialog_id, top_thread_message_id, action.get_input_send_message_action()); } void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) { @@ -29156,31 +28914,12 @@ void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) { progress = static_cast(100 * uploaded_size / total_size); } - td_api::object_ptr action; - switch (m->content->get_type()) { - case MessageContentType::Animation: - case MessageContentType::Audio: - case MessageContentType::Document: - action = td_api::make_object(progress); - break; - case MessageContentType::Photo: - action = td_api::make_object(progress); - break; - case MessageContentType::Video: - action = td_api::make_object(progress); - break; - case MessageContentType::VideoNote: - action = td_api::make_object(progress); - break; - case MessageContentType::VoiceNote: - action = td_api::make_object(progress); - break; - default: - return; + DialogAction action = DialogAction::get_uploading_action(m->content->get_type(), progress); + if (action == DialogAction()) { + return; } - CHECK(action != nullptr); - LOG(INFO) << "Send action in " << dialog_id << ": " << to_string(action); - send_dialog_action(dialog_id, m->top_thread_message_id, std::move(action), Auto()); + LOG(INFO) << "Send " << action << " in " << dialog_id; + send_dialog_action(dialog_id, m->top_thread_message_id, std::move(action), Promise()); } void MessagesManager::on_active_dialog_action_timeout(DialogId dialog_id) { @@ -29194,7 +28933,7 @@ void MessagesManager::on_active_dialog_action_timeout(DialogId dialog_id) { auto now = Time::now(); while (actions_it->second[0].start_time + DIALOG_ACTION_TIMEOUT < now + 0.1) { on_user_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id, actions_it->second[0].user_id, - nullptr, 0); + DialogAction(), 0); actions_it = active_dialog_actions_.find(dialog_id); if (actions_it == active_dialog_actions_.end()) { @@ -29214,7 +28953,7 @@ void MessagesManager::clear_active_dialog_actions(DialogId 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, actions_it->second[0].user_id, - nullptr, 0); + DialogAction(), 0); actions_it = active_dialog_actions_.find(dialog_id); } } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index c52af6520..be1252544 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -9,6 +9,7 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/ChannelId.h" #include "td/telegram/Dependencies.h" +#include "td/telegram/DialogAction.h" #include "td/telegram/DialogAdministrator.h" #include "td/telegram/DialogDate.h" #include "td/telegram/DialogDb.h" @@ -367,9 +368,8 @@ class MessagesManager : public Actor { void on_update_delete_scheduled_messages(DialogId dialog_id, vector &&server_message_ids); - void on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_id, - tl_object_ptr &&action, int32 date, - MessageContentType message_content_type = MessageContentType::None); + void on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_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); @@ -478,8 +478,8 @@ class MessagesManager : public Actor { tl_object_ptr get_game_high_scores_object(int64 random_id); - void send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, - const tl_object_ptr &action, Promise &&promise); + void send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogAction action, + Promise &&promise); vector get_dialog_lists_to_add_dialog(DialogId dialog_id); @@ -2218,7 +2218,7 @@ class MessagesManager : 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, - td_api::object_ptr action); + DialogAction action); void repair_dialog_action_bar(Dialog *d, const char *source); @@ -2355,8 +2355,6 @@ class MessagesManager : public Actor { bool update_dialog_silent_send_message(Dialog *d, bool silent_send_message); - static tl_object_ptr copy_chat_action_object(const tl_object_ptr &action); - bool is_dialog_action_unneeded(DialogId dialog_id) const; void on_send_dialog_action_timeout(DialogId dialog_id); @@ -2365,8 +2363,6 @@ class MessagesManager : public Actor { void clear_active_dialog_actions(DialogId dialog_id); - static bool need_cancel_user_dialog_action(int32 action_id, MessageContentType message_content_type); - void cancel_user_dialog_action(DialogId dialog_id, const Message *m); Dialog *get_dialog_by_message_id(MessageId message_id); @@ -3104,12 +3100,11 @@ class MessagesManager : public Actor { struct ActiveDialogAction { MessageId top_thread_message_id; UserId user_id; - int32 action_id; - int32 progress; + DialogAction action; double start_time; - ActiveDialogAction(MessageId top_thread_message_id, UserId user_id, int32 action_id, double start_time) - : top_thread_message_id(top_thread_message_id), user_id(user_id), action_id(action_id), start_time(start_time) { + ActiveDialogAction(MessageId top_thread_message_id, UserId user_id, DialogAction action, double start_time) + : top_thread_message_id(top_thread_message_id), user_id(user_id), action(action), start_time(start_time) { } }; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 9b58b5952..8f85cc535 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -24,6 +24,7 @@ #include "td/telegram/ContactsManager.h" #include "td/telegram/CountryInfoManager.h" #include "td/telegram/DeviceTokenManager.h" +#include "td/telegram/DialogAction.h" #include "td/telegram/DialogAdministrator.h" #include "td/telegram/DialogFilter.h" #include "td/telegram/DialogFilterId.h" @@ -5825,7 +5826,7 @@ void Td::on_request(uint64 id, const td_api::deleteChatReplyMarkup &request) { void Td::on_request(uint64 id, td_api::sendChatAction &request) { CREATE_OK_REQUEST_PROMISE(); messages_manager_->send_dialog_action(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(request.action_), std::move(promise)); + DialogAction(std::move(request.action_)), std::move(promise)); } void Td::on_request(uint64 id, td_api::sendChatScreenshotTakenNotification &request) { diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index badccf3d7..5946e6adf 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -16,6 +16,7 @@ #include "td/telegram/ChatId.h" #include "td/telegram/ConfigManager.h" #include "td/telegram/ContactsManager.h" +#include "td/telegram/DialogAction.h" #include "td/telegram/DialogId.h" #include "td/telegram/FolderId.h" #include "td/telegram/Global.h" @@ -1829,55 +1830,6 @@ int32 UpdatesManager::get_short_update_date() const { return now; } -tl_object_ptr UpdatesManager::convert_send_message_action( - tl_object_ptr action) { - auto fix_progress = [](int32 progress) { - return progress <= 0 || progress > 100 ? 0 : progress; - }; - - switch (action->get_id()) { - case telegram_api::sendMessageCancelAction::ID: - return make_tl_object(); - case telegram_api::sendMessageTypingAction::ID: - return make_tl_object(); - case telegram_api::sendMessageRecordVideoAction::ID: - return make_tl_object(); - case telegram_api::sendMessageUploadVideoAction::ID: { - auto upload_video_action = move_tl_object_as(action); - return make_tl_object(fix_progress(upload_video_action->progress_)); - } - case telegram_api::sendMessageRecordAudioAction::ID: - return make_tl_object(); - case telegram_api::sendMessageUploadAudioAction::ID: { - auto upload_audio_action = move_tl_object_as(action); - return make_tl_object(fix_progress(upload_audio_action->progress_)); - } - case telegram_api::sendMessageUploadPhotoAction::ID: { - auto upload_photo_action = move_tl_object_as(action); - return make_tl_object(fix_progress(upload_photo_action->progress_)); - } - case telegram_api::sendMessageUploadDocumentAction::ID: { - auto upload_document_action = move_tl_object_as(action); - return make_tl_object(fix_progress(upload_document_action->progress_)); - } - case telegram_api::sendMessageGeoLocationAction::ID: - return make_tl_object(); - case telegram_api::sendMessageChooseContactAction::ID: - return make_tl_object(); - case telegram_api::sendMessageGamePlayAction::ID: - return make_tl_object(); - case telegram_api::sendMessageRecordRoundAction::ID: - return make_tl_object(); - case telegram_api::sendMessageUploadRoundAction::ID: { - auto upload_round_action = move_tl_object_as(action); - return make_tl_object(fix_progress(upload_round_action->progress_)); - } - default: - UNREACHABLE(); - return make_tl_object(); - } -} - void UpdatesManager::on_update(tl_object_ptr update, bool /*force_apply*/) { UserId user_id(update->user_id_); if (!td_->contacts_manager_->have_min_user(user_id)) { @@ -1890,8 +1842,7 @@ void UpdatesManager::on_update(tl_object_ptr upd return; } td_->messages_manager_->on_user_dialog_action(dialog_id, MessageId(), user_id, - convert_send_message_action(std::move(update->action_)), - get_short_update_date()); + DialogAction(std::move(update->action_)), get_short_update_date()); } void UpdatesManager::on_update(tl_object_ptr update, bool /*force_apply*/) { @@ -1906,8 +1857,7 @@ void UpdatesManager::on_update(tl_object_ptr return; } td_->messages_manager_->on_user_dialog_action(dialog_id, MessageId(), user_id, - convert_send_message_action(std::move(update->action_)), - get_short_update_date()); + DialogAction(std::move(update->action_)), get_short_update_date()); } void UpdatesManager::on_update(tl_object_ptr update, bool /*force_apply*/) { @@ -1930,8 +1880,7 @@ void UpdatesManager::on_update(tl_object_ptrmessages_manager_->on_user_dialog_action(dialog_id, top_thread_message_id, user_id, - convert_send_message_action(std::move(update->action_)), - get_short_update_date()); + DialogAction(std::move(update->action_)), get_short_update_date()); } void UpdatesManager::on_update(tl_object_ptr update, bool /*force_apply*/) { @@ -1950,7 +1899,7 @@ void UpdatesManager::on_update(tl_object_ptrmessages_manager_->on_user_dialog_action(dialog_id, MessageId(), user_id, - make_tl_object(), get_short_update_date()); + DialogAction(DialogAction::Type::Typing, 0), get_short_update_date()); } void UpdatesManager::on_update(tl_object_ptr update, bool /*force_apply*/) { diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index d60b73ba1..c81ce6c8b 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -136,9 +136,6 @@ class UpdatesManager : public Actor { int32 get_short_update_date() const; - static tl_object_ptr convert_send_message_action( - tl_object_ptr action); - void process_get_difference_updates(vector> &&new_messages, vector> &&new_encrypted_messages, vector> &&other_updates);