Introduce DialogAction class.

GitOrigin-RevId: f94011c1b70cdc17115bfbb981c6e000110adfbf
This commit is contained in:
levlam 2020-10-01 19:28:10 +03:00
parent c6cdfb377c
commit 711b0cfd4f
9 changed files with 500 additions and 368 deletions

View File

@ -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

View File

@ -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<td_api::ChatAction> &&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<td_api::chatActionUploadingVideo>(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<td_api::chatActionUploadingVoiceNote>(action);
init(Type::UploadingVoiceNote, uploading_action->progress_);
break;
}
case td_api::chatActionUploadingPhoto::ID: {
auto uploading_action = move_tl_object_as<td_api::chatActionUploadingPhoto>(action);
init(Type::UploadingPhoto, uploading_action->progress_);
break;
}
case td_api::chatActionUploadingDocument::ID: {
auto uploading_action = move_tl_object_as<td_api::chatActionUploadingDocument>(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<td_api::chatActionUploadingVideoNote>(action);
init(Type::UploadingVideoNote, uploading_action->progress_);
break;
}
default:
UNREACHABLE();
break;
}
}
DialogAction::DialogAction(tl_object_ptr<telegram_api::SendMessageAction> &&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<telegram_api::sendMessageUploadVideoAction>(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<telegram_api::sendMessageUploadAudioAction>(action);
init(Type::UploadingVoiceNote, upload_audio_action->progress_);
break;
}
case telegram_api::sendMessageUploadPhotoAction::ID: {
auto upload_photo_action = move_tl_object_as<telegram_api::sendMessageUploadPhotoAction>(action);
init(Type::UploadingPhoto, upload_photo_action->progress_);
break;
}
case telegram_api::sendMessageUploadDocumentAction::ID: {
auto upload_document_action = move_tl_object_as<telegram_api::sendMessageUploadDocumentAction>(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<telegram_api::sendMessageUploadRoundAction>(action);
init(Type::UploadingVideoNote, upload_round_action->progress_);
break;
}
default:
UNREACHABLE();
break;
}
}
tl_object_ptr<telegram_api::SendMessageAction> DialogAction::get_input_send_message_action() const {
switch (type_) {
case Type::Cancel:
return make_tl_object<telegram_api::sendMessageCancelAction>();
case Type::Typing:
return make_tl_object<telegram_api::sendMessageTypingAction>();
case Type::RecordingVideo:
return make_tl_object<telegram_api::sendMessageRecordVideoAction>();
case Type::UploadingVideo:
return make_tl_object<telegram_api::sendMessageUploadVideoAction>(progress_);
case Type::RecordingVoiceNote:
return make_tl_object<telegram_api::sendMessageRecordAudioAction>();
case Type::UploadingVoiceNote:
return make_tl_object<telegram_api::sendMessageUploadAudioAction>(progress_);
case Type::UploadingPhoto:
return make_tl_object<telegram_api::sendMessageUploadPhotoAction>(progress_);
case Type::UploadingDocument:
return make_tl_object<telegram_api::sendMessageUploadDocumentAction>(progress_);
case Type::ChoosingLocation:
return make_tl_object<telegram_api::sendMessageGeoLocationAction>();
case Type::ChoosingContact:
return make_tl_object<telegram_api::sendMessageChooseContactAction>();
case Type::RecordingVideoNote:
return make_tl_object<telegram_api::sendMessageRecordRoundAction>();
case Type::UploadingVideoNote:
return make_tl_object<telegram_api::sendMessageUploadRoundAction>(progress_);
case Type::StartPlayingGame:
return make_tl_object<telegram_api::sendMessageTypingAction>();
default:
UNREACHABLE();
return nullptr;
}
}
tl_object_ptr<secret_api::SendMessageAction> DialogAction::get_secret_input_send_message_action() const {
switch (type_) {
case Type::Cancel:
return make_tl_object<secret_api::sendMessageCancelAction>();
case Type::Typing:
return make_tl_object<secret_api::sendMessageTypingAction>();
case Type::RecordingVideo:
return make_tl_object<secret_api::sendMessageRecordVideoAction>();
case Type::UploadingVideo:
return make_tl_object<secret_api::sendMessageUploadVideoAction>();
case Type::RecordingVoiceNote:
return make_tl_object<secret_api::sendMessageRecordAudioAction>();
case Type::UploadingVoiceNote:
return make_tl_object<secret_api::sendMessageUploadAudioAction>();
case Type::UploadingPhoto:
return make_tl_object<secret_api::sendMessageUploadPhotoAction>();
case Type::UploadingDocument:
return make_tl_object<secret_api::sendMessageUploadDocumentAction>();
case Type::ChoosingLocation:
return make_tl_object<secret_api::sendMessageGeoLocationAction>();
case Type::ChoosingContact:
return make_tl_object<secret_api::sendMessageChooseContactAction>();
case Type::RecordingVideoNote:
return make_tl_object<secret_api::sendMessageRecordRoundAction>();
case Type::UploadingVideoNote:
return make_tl_object<secret_api::sendMessageUploadRoundAction>();
case Type::StartPlayingGame:
return make_tl_object<secret_api::sendMessageTypingAction>();
default:
UNREACHABLE();
return nullptr;
}
}
tl_object_ptr<td_api::ChatAction> DialogAction::get_chat_action_object() const {
switch (type_) {
case Type::Cancel:
return td_api::make_object<td_api::chatActionCancel>();
case Type::Typing:
return td_api::make_object<td_api::chatActionTyping>();
case Type::RecordingVideo:
return td_api::make_object<td_api::chatActionRecordingVideo>();
case Type::UploadingVideo:
return td_api::make_object<td_api::chatActionUploadingVideo>(progress_);
case Type::RecordingVoiceNote:
return td_api::make_object<td_api::chatActionRecordingVoiceNote>();
case Type::UploadingVoiceNote:
return td_api::make_object<td_api::chatActionUploadingVoiceNote>(progress_);
case Type::UploadingPhoto:
return td_api::make_object<td_api::chatActionUploadingPhoto>(progress_);
case Type::UploadingDocument:
return td_api::make_object<td_api::chatActionUploadingDocument>(progress_);
case Type::ChoosingLocation:
return td_api::make_object<td_api::chatActionChoosingLocation>();
case Type::ChoosingContact:
return td_api::make_object<td_api::chatActionChoosingContact>();
case Type::StartPlayingGame:
return td_api::make_object<td_api::chatActionStartPlayingGame>();
case Type::RecordingVideoNote:
return td_api::make_object<td_api::chatActionRecordingVideoNote>();
case Type::UploadingVideoNote:
return td_api::make_object<td_api::chatActionUploadingVideoNote>(progress_);
default:
UNREACHABLE();
return td_api::make_object<td_api::chatActionCancel>();
}
}
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

View File

@ -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<td_api::ChatAction> &&action);
explicit DialogAction(tl_object_ptr<telegram_api::SendMessageAction> &&action);
tl_object_ptr<telegram_api::SendMessageAction> get_input_send_message_action() const;
tl_object_ptr<secret_api::SendMessageAction> get_secret_input_send_message_action() const;
td_api::object_ptr<td_api::ChatAction> 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

View File

@ -19,7 +19,7 @@ td_api::object_ptr<td_api::chatAdministrator> 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_ << "]";
}

View File

@ -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<td_api::ChatAction> &&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<td_api::chatActionCancel>();
}
} 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<td_api::chatActionUploadingVideo &>(*action).progress_;
case td_api::chatActionUploadingVoiceNote::ID:
return static_cast<td_api::chatActionUploadingVoiceNote &>(*action).progress_;
case td_api::chatActionUploadingPhoto::ID:
return static_cast<td_api::chatActionUploadingPhoto &>(*action).progress_;
case td_api::chatActionUploadingDocument::ID:
return static_cast<td_api::chatActionUploadingDocument &>(*action).progress_;
case td_api::chatActionUploadingVideoNote::ID:
return static_cast<td_api::chatActionUploadingVideoNote &>(*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<td_api::chatActionCancel>());
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<telegram_api::Update> &&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<SleepActor>(
"RepairDialogActionBarActor", 1.0,
"RepairChatActionBarActor", 1.0,
PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, source](Result<Unit> 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<td_api::ChatAction> 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<td_api::updateUserChatAction>(
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<td_api::updateUserChatAction>(
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<td_api::ChatAction> MessagesManager::copy_chat_action_object(
const tl_object_ptr<td_api::ChatAction> &action) {
CHECK(action != nullptr);
switch (action->get_id()) {
case td_api::chatActionCancel::ID:
return make_tl_object<td_api::chatActionCancel>();
case td_api::chatActionTyping::ID:
return make_tl_object<td_api::chatActionTyping>();
case td_api::chatActionRecordingVideo::ID:
return make_tl_object<td_api::chatActionRecordingVideo>();
case td_api::chatActionUploadingVideo::ID: {
auto progress = static_cast<const td_api::chatActionUploadingVideo &>(*action).progress_;
return make_tl_object<td_api::chatActionUploadingVideo>(progress);
}
case td_api::chatActionRecordingVoiceNote::ID:
return make_tl_object<td_api::chatActionRecordingVoiceNote>();
case td_api::chatActionUploadingVoiceNote::ID: {
auto progress = static_cast<const td_api::chatActionUploadingVoiceNote &>(*action).progress_;
return make_tl_object<td_api::chatActionUploadingVoiceNote>(progress);
}
case td_api::chatActionUploadingPhoto::ID: {
auto progress = static_cast<const td_api::chatActionUploadingPhoto &>(*action).progress_;
return make_tl_object<td_api::chatActionUploadingPhoto>(progress);
}
case td_api::chatActionUploadingDocument::ID: {
auto progress = static_cast<const td_api::chatActionUploadingDocument &>(*action).progress_;
return make_tl_object<td_api::chatActionUploadingDocument>(progress);
}
case td_api::chatActionChoosingLocation::ID:
return make_tl_object<td_api::chatActionChoosingLocation>();
case td_api::chatActionChoosingContact::ID:
return make_tl_object<td_api::chatActionChoosingContact>();
case td_api::chatActionStartPlayingGame::ID:
return make_tl_object<td_api::chatActionStartPlayingGame>();
case td_api::chatActionRecordingVideoNote::ID:
return make_tl_object<td_api::chatActionRecordingVideoNote>();
case td_api::chatActionUploadingVideoNote::ID: {
auto progress = static_cast<const td_api::chatActionUploadingVideoNote &>(*action).progress_;
return make_tl_object<td_api::chatActionUploadingVideoNote>(progress);
}
default:
UNREACHABLE();
return nullptr;
}
}
void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id,
const tl_object_ptr<td_api::ChatAction> &action, Promise<Unit> &&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<Unit> &&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<secret_api::SendMessageAction> send_action;
switch (action->get_id()) {
case td_api::chatActionCancel::ID:
send_action = make_tl_object<secret_api::sendMessageCancelAction>();
break;
case td_api::chatActionTyping::ID:
send_action = make_tl_object<secret_api::sendMessageTypingAction>();
break;
case td_api::chatActionRecordingVideo::ID:
send_action = make_tl_object<secret_api::sendMessageRecordVideoAction>();
break;
case td_api::chatActionUploadingVideo::ID:
send_action = make_tl_object<secret_api::sendMessageUploadVideoAction>();
break;
case td_api::chatActionRecordingVoiceNote::ID:
send_action = make_tl_object<secret_api::sendMessageRecordAudioAction>();
break;
case td_api::chatActionUploadingVoiceNote::ID:
send_action = make_tl_object<secret_api::sendMessageUploadAudioAction>();
break;
case td_api::chatActionUploadingPhoto::ID:
send_action = make_tl_object<secret_api::sendMessageUploadPhotoAction>();
break;
case td_api::chatActionUploadingDocument::ID:
send_action = make_tl_object<secret_api::sendMessageUploadDocumentAction>();
break;
case td_api::chatActionChoosingLocation::ID:
send_action = make_tl_object<secret_api::sendMessageGeoLocationAction>();
break;
case td_api::chatActionChoosingContact::ID:
send_action = make_tl_object<secret_api::sendMessageChooseContactAction>();
break;
case td_api::chatActionRecordingVideoNote::ID:
send_action = make_tl_object<secret_api::sendMessageRecordRoundAction>();
break;
case td_api::chatActionUploadingVideoNote::ID:
send_action = make_tl_object<secret_api::sendMessageUploadRoundAction>();
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<telegram_api::SendMessageAction> send_action;
switch (action->get_id()) {
case td_api::chatActionCancel::ID:
send_action = make_tl_object<telegram_api::sendMessageCancelAction>();
break;
case td_api::chatActionTyping::ID:
send_action = make_tl_object<telegram_api::sendMessageTypingAction>();
break;
case td_api::chatActionRecordingVideo::ID:
send_action = make_tl_object<telegram_api::sendMessageRecordVideoAction>();
break;
case td_api::chatActionUploadingVideo::ID: {
auto progress = static_cast<const td_api::chatActionUploadingVideo &>(*action).progress_;
send_action = make_tl_object<telegram_api::sendMessageUploadVideoAction>(progress);
break;
}
case td_api::chatActionRecordingVoiceNote::ID:
send_action = make_tl_object<telegram_api::sendMessageRecordAudioAction>();
break;
case td_api::chatActionUploadingVoiceNote::ID: {
auto progress = static_cast<const td_api::chatActionUploadingVoiceNote &>(*action).progress_;
send_action = make_tl_object<telegram_api::sendMessageUploadAudioAction>(progress);
break;
}
case td_api::chatActionUploadingPhoto::ID: {
auto progress = static_cast<const td_api::chatActionUploadingPhoto &>(*action).progress_;
send_action = make_tl_object<telegram_api::sendMessageUploadPhotoAction>(progress);
break;
}
case td_api::chatActionUploadingDocument::ID: {
auto progress = static_cast<const td_api::chatActionUploadingDocument &>(*action).progress_;
send_action = make_tl_object<telegram_api::sendMessageUploadDocumentAction>(progress);
break;
}
case td_api::chatActionChoosingLocation::ID:
send_action = make_tl_object<telegram_api::sendMessageGeoLocationAction>();
break;
case td_api::chatActionChoosingContact::ID:
send_action = make_tl_object<telegram_api::sendMessageChooseContactAction>();
break;
case td_api::chatActionStartPlayingGame::ID:
send_action = make_tl_object<telegram_api::sendMessageGamePlayAction>();
break;
case td_api::chatActionRecordingVideoNote::ID:
send_action = make_tl_object<telegram_api::sendMessageRecordRoundAction>();
break;
case td_api::chatActionUploadingVideoNote::ID: {
auto progress = static_cast<const td_api::chatActionUploadingVideoNote &>(*action).progress_;
send_action = make_tl_object<telegram_api::sendMessageUploadRoundAction>(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<SetTypingQuery>(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<int32>(100 * uploaded_size / total_size);
}
td_api::object_ptr<td_api::ChatAction> action;
switch (m->content->get_type()) {
case MessageContentType::Animation:
case MessageContentType::Audio:
case MessageContentType::Document:
action = td_api::make_object<td_api::chatActionUploadingDocument>(progress);
break;
case MessageContentType::Photo:
action = td_api::make_object<td_api::chatActionUploadingPhoto>(progress);
break;
case MessageContentType::Video:
action = td_api::make_object<td_api::chatActionUploadingVideo>(progress);
break;
case MessageContentType::VideoNote:
action = td_api::make_object<td_api::chatActionUploadingVideoNote>(progress);
break;
case MessageContentType::VoiceNote:
action = td_api::make_object<td_api::chatActionUploadingVoiceNote>(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<Unit>());
}
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);
}
}

View File

@ -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<ScheduledServerMessageId> &&server_message_ids);
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);
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<td_api::gameHighScores> get_game_high_scores_object(int64 random_id);
void send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id,
const tl_object_ptr<td_api::ChatAction> &action, Promise<Unit> &&promise);
void send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogAction action,
Promise<Unit> &&promise);
vector<DialogListId> 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<td_api::ChatAction> 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<td_api::ChatAction> copy_chat_action_object(const tl_object_ptr<td_api::ChatAction> &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) {
}
};

View File

@ -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) {

View File

@ -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<td_api::ChatAction> UpdatesManager::convert_send_message_action(
tl_object_ptr<telegram_api::SendMessageAction> 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<td_api::chatActionCancel>();
case telegram_api::sendMessageTypingAction::ID:
return make_tl_object<td_api::chatActionTyping>();
case telegram_api::sendMessageRecordVideoAction::ID:
return make_tl_object<td_api::chatActionRecordingVideo>();
case telegram_api::sendMessageUploadVideoAction::ID: {
auto upload_video_action = move_tl_object_as<telegram_api::sendMessageUploadVideoAction>(action);
return make_tl_object<td_api::chatActionUploadingVideo>(fix_progress(upload_video_action->progress_));
}
case telegram_api::sendMessageRecordAudioAction::ID:
return make_tl_object<td_api::chatActionRecordingVoiceNote>();
case telegram_api::sendMessageUploadAudioAction::ID: {
auto upload_audio_action = move_tl_object_as<telegram_api::sendMessageUploadAudioAction>(action);
return make_tl_object<td_api::chatActionUploadingVoiceNote>(fix_progress(upload_audio_action->progress_));
}
case telegram_api::sendMessageUploadPhotoAction::ID: {
auto upload_photo_action = move_tl_object_as<telegram_api::sendMessageUploadPhotoAction>(action);
return make_tl_object<td_api::chatActionUploadingPhoto>(fix_progress(upload_photo_action->progress_));
}
case telegram_api::sendMessageUploadDocumentAction::ID: {
auto upload_document_action = move_tl_object_as<telegram_api::sendMessageUploadDocumentAction>(action);
return make_tl_object<td_api::chatActionUploadingDocument>(fix_progress(upload_document_action->progress_));
}
case telegram_api::sendMessageGeoLocationAction::ID:
return make_tl_object<td_api::chatActionChoosingLocation>();
case telegram_api::sendMessageChooseContactAction::ID:
return make_tl_object<td_api::chatActionChoosingContact>();
case telegram_api::sendMessageGamePlayAction::ID:
return make_tl_object<td_api::chatActionStartPlayingGame>();
case telegram_api::sendMessageRecordRoundAction::ID:
return make_tl_object<td_api::chatActionRecordingVideoNote>();
case telegram_api::sendMessageUploadRoundAction::ID: {
auto upload_round_action = move_tl_object_as<telegram_api::sendMessageUploadRoundAction>(action);
return make_tl_object<td_api::chatActionUploadingVideoNote>(fix_progress(upload_round_action->progress_));
}
default:
UNREACHABLE();
return make_tl_object<td_api::chatActionTyping>();
}
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateUserTyping> 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<telegram_api::updateUserTyping> 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<telegram_api::updateChatUserTyping> update, bool /*force_apply*/) {
@ -1906,8 +1857,7 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChatUserTyping>
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<telegram_api::updateChannelUserTyping> update, bool /*force_apply*/) {
@ -1930,8 +1880,7 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChannelUserTypi
}
}
td_->messages_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<telegram_api::updateEncryptedChatTyping> update, bool /*force_apply*/) {
@ -1950,7 +1899,7 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateEncryptedChatTy
}
td_->messages_manager_->on_user_dialog_action(dialog_id, MessageId(), user_id,
make_tl_object<td_api::chatActionTyping>(), get_short_update_date());
DialogAction(DialogAction::Type::Typing, 0), get_short_update_date());
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateUserStatus> update, bool /*force_apply*/) {

View File

@ -136,9 +136,6 @@ class UpdatesManager : public Actor {
int32 get_short_update_date() const;
static tl_object_ptr<td_api::ChatAction> convert_send_message_action(
tl_object_ptr<telegram_api::SendMessageAction> action);
void process_get_difference_updates(vector<tl_object_ptr<telegram_api::Message>> &&new_messages,
vector<tl_object_ptr<telegram_api::EncryptedMessage>> &&new_encrypted_messages,
vector<tl_object_ptr<telegram_api::Update>> &&other_updates);