Automatically send ChatAction while files are uploaded.
GitOrigin-RevId: 45c27ab71ede8c0f82265b34b752e03ffc1c1c8c
This commit is contained in:
parent
8b2df8c233
commit
c489e3b91d
@ -2762,13 +2762,16 @@ class SetTypingQuery : public Td::ResultHandler {
|
||||
explicit SetTypingQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(DialogId dialog_id, tl_object_ptr<telegram_api::SendMessageAction> &&action) {
|
||||
NetQueryRef send(DialogId dialog_id, tl_object_ptr<telegram_api::SendMessageAction> &&action) {
|
||||
dialog_id_ = dialog_id;
|
||||
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
|
||||
CHECK(input_peer != nullptr);
|
||||
|
||||
send_query(G()->net_query_creator().create(
|
||||
create_storer(telegram_api::messages_setTyping(std::move(input_peer), std::move(action)))));
|
||||
auto net_query = G()->net_query_creator().create(
|
||||
create_storer(telegram_api::messages_setTyping(std::move(input_peer), std::move(action))));
|
||||
auto result = net_query.get_weak();
|
||||
send_query(std::move(net_query));
|
||||
return result;
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
@ -4494,6 +4497,9 @@ MessagesManager::MessagesManager(Td *td, ActorShared<> parent) : td_(td), parent
|
||||
dialog_unmute_timeout_.set_callback(on_dialog_unmute_timeout_callback);
|
||||
dialog_unmute_timeout_.set_callback_data(static_cast<void *>(this));
|
||||
|
||||
pending_send_dialog_action_timeout_.set_callback(on_pending_send_dialog_action_timeout_callback);
|
||||
pending_send_dialog_action_timeout_.set_callback_data(static_cast<void *>(this));
|
||||
|
||||
sequence_dispatcher_ = create_actor<MultiSequenceDispatcher>("multi sequence dispatcher");
|
||||
|
||||
if (G()->parameters().use_message_db) {
|
||||
@ -4617,6 +4623,16 @@ void MessagesManager::on_dialog_unmute_timeout_callback(void *messages_manager_p
|
||||
DialogId(dialog_id_int));
|
||||
}
|
||||
|
||||
void MessagesManager::on_pending_send_dialog_action_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) {
|
||||
if (G()->close_flag()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto messages_manager = static_cast<MessagesManager *>(messages_manager_ptr);
|
||||
send_closure_later(messages_manager->actor_id(messages_manager), &MessagesManager::on_send_dialog_action_timeout,
|
||||
DialogId(dialog_id_int));
|
||||
}
|
||||
|
||||
BufferSlice MessagesManager::get_dialog_database_value(const Dialog *d) {
|
||||
// can't use log_event_store, because it tries to parse stored Dialog
|
||||
LogEventStorerCalcLength storer_calc_length;
|
||||
@ -19150,6 +19166,7 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
// TODO cancel previous query
|
||||
send_closure(G()->secret_chats_manager(), &SecretChatsManager::send_message_action, dialog_id.get_secret_chat_id(),
|
||||
std::move(send_action));
|
||||
promise.set_value(Unit());
|
||||
@ -19211,8 +19228,88 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// TODO auto send Uploading actions, resend action every 4 seconds, flood control on actions. ActionsManager?
|
||||
td_->create_handler<SetTypingQuery>(std::move(promise))->send(dialog_id, std::move(send_action));
|
||||
auto &query_ref = set_typing_query_[dialog_id];
|
||||
if (!query_ref.empty()) {
|
||||
LOG(INFO) << "Cancel previous set typing query";
|
||||
cancel_query(query_ref);
|
||||
}
|
||||
query_ref = td_->create_handler<SetTypingQuery>(std::move(promise))->send(dialog_id, std::move(send_action));
|
||||
}
|
||||
|
||||
void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) {
|
||||
LOG(INFO) << "Receive send_dialog_action timeout in " << dialog_id;
|
||||
Dialog *d = get_dialog(dialog_id);
|
||||
CHECK(d != nullptr);
|
||||
|
||||
if (can_send_message(dialog_id).is_error()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto queue_id = get_sequence_dispatcher_id(dialog_id, MessagePhoto::ID);
|
||||
CHECK(queue_id & 1);
|
||||
|
||||
auto queue_it = yet_unsent_media_queues_.find(queue_id);
|
||||
if (queue_it == yet_unsent_media_queues_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
pending_send_dialog_action_timeout_.add_timeout_in(dialog_id.get(), 4.0);
|
||||
|
||||
CHECK(!queue_it->second.empty());
|
||||
MessageId message_id(queue_it->second.begin()->first);
|
||||
const Message *m = get_message(d, message_id);
|
||||
if (m == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (m->forward_info != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto file_id = get_message_content_file_id(m->content.get());
|
||||
if (!file_id.is_valid()) {
|
||||
LOG(ERROR) << "Have no file in "
|
||||
<< to_string(get_message_content_object(m->content.get(), m->date, m->is_content_secret));
|
||||
return;
|
||||
}
|
||||
auto file_view = td_->file_manager_->get_file_view(file_id);
|
||||
if (!file_view.is_uploading()) {
|
||||
return;
|
||||
}
|
||||
int64 total_size = file_view.expected_size();
|
||||
int64 uploaded_size = file_view.remote_size();
|
||||
int32 progress = 0;
|
||||
if (total_size > 0 && uploaded_size > 0) {
|
||||
if (uploaded_size > total_size) {
|
||||
uploaded_size = total_size; // just in case
|
||||
}
|
||||
progress = static_cast<int32>(100 * uploaded_size / total_size);
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::ChatAction> action;
|
||||
switch (m->content->get_id()) {
|
||||
case MessageAnimation::ID:
|
||||
case MessageAudio::ID:
|
||||
case MessageDocument::ID:
|
||||
action = td_api::make_object<td_api::chatActionUploadingDocument>(progress);
|
||||
break;
|
||||
case MessagePhoto::ID:
|
||||
action = td_api::make_object<td_api::chatActionUploadingPhoto>(progress);
|
||||
break;
|
||||
case MessageVideo::ID:
|
||||
action = td_api::make_object<td_api::chatActionUploadingVideo>(progress);
|
||||
break;
|
||||
case MessageVideoNote::ID:
|
||||
action = td_api::make_object<td_api::chatActionUploadingVideoNote>(progress);
|
||||
break;
|
||||
case MessageVoiceNote::ID:
|
||||
action = td_api::make_object<td_api::chatActionUploadingVoiceNote>(progress);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
CHECK(action != nullptr);
|
||||
LOG(INFO) << "Send action in " << dialog_id << ": " << to_string(action);
|
||||
send_dialog_action(dialog_id, std::move(action), Auto());
|
||||
}
|
||||
|
||||
tl_object_ptr<telegram_api::InputChatPhoto> MessagesManager::get_input_chat_photo(FileId file_id) const {
|
||||
@ -21313,6 +21410,9 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
|
||||
if (queue_id & 1) {
|
||||
LOG(INFO) << "Add " << message_id << " from " << source << " to queue " << queue_id;
|
||||
yet_unsent_media_queues_[queue_id][message_id.get()]; // reserve place for promise
|
||||
if (!td_->auth_manager_->is_bot() && !is_broadcast_channel(dialog_id)) {
|
||||
pending_send_dialog_action_timeout_.add_timeout_in(dialog_id.get(), 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2152,6 +2152,8 @@ class MessagesManager : public Actor {
|
||||
|
||||
void on_dialog_unmute(DialogId dialog_id);
|
||||
|
||||
void on_send_dialog_action_timeout(DialogId dialog_id);
|
||||
|
||||
Dialog *get_dialog_by_message_id(MessageId message_id);
|
||||
|
||||
MessageId get_message_id_by_random_id(Dialog *d, int64 random_id);
|
||||
@ -2413,6 +2415,8 @@ class MessagesManager : public Actor {
|
||||
|
||||
static void on_dialog_unmute_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int);
|
||||
|
||||
static void on_pending_send_dialog_action_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int);
|
||||
|
||||
void load_secret_thumbnail(FileId thumbnail_file_id);
|
||||
|
||||
static tl_object_ptr<telegram_api::channelAdminLogEventsFilter> get_channel_admin_log_events_filter(
|
||||
@ -2661,6 +2665,7 @@ class MessagesManager : public Actor {
|
||||
MultiTimeout pending_updated_dialog_timeout_;
|
||||
MultiTimeout pending_unload_dialog_timeout_;
|
||||
MultiTimeout dialog_unmute_timeout_;
|
||||
MultiTimeout pending_send_dialog_action_timeout_;
|
||||
|
||||
Hints dialogs_hints_; // search dialogs by title and username
|
||||
|
||||
@ -2697,6 +2702,8 @@ class MessagesManager : public Actor {
|
||||
|
||||
std::unordered_map<uint64, std::map<int64, Promise<Message *>>> yet_unsent_media_queues_;
|
||||
|
||||
std::unordered_map<DialogId, NetQueryRef, DialogIdHash> set_typing_query_;
|
||||
|
||||
Td *td_;
|
||||
ActorShared<> parent_;
|
||||
};
|
||||
|
Reference in New Issue
Block a user