From 3846d56680c7a49c0c04db4500dee7fa69d06ea7 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 13 Sep 2019 20:25:17 +0300 Subject: [PATCH] Add td_api::getSuitableDiscussionChats. GitOrigin-RevId: 7ba20b857f9d34db4670af12907fe17053047515 --- td/generate/scheme/td_api.tl | 3 + td/generate/scheme/td_api.tlo | Bin 160300 -> 160368 bytes td/telegram/ContactsManager.cpp | 132 +++++++++++++++++++++++--------- td/telegram/ContactsManager.h | 11 +++ td/telegram/Td.cpp | 21 +++++ td/telegram/Td.h | 2 + td/telegram/cli.cpp | 2 + 7 files changed, 135 insertions(+), 36 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index a170ea5f..4724cea0 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3056,6 +3056,9 @@ checkChatUsername chat_id:int53 username:string = CheckChatUsernameResult; //@description Returns a list of public chats with username created by the user getCreatedPublicChats = Chats; +//@description Returns a list of basic group and supergroup chats, which can be used as a discussion group for a channel. Basic group chats need to be first upgraded to supergroups before they can be set as a discussion group +getSuitableDiscussionChats = Chats; + //@description Returns a list of common group chats with a given user. Chats are sorted by their type and creation date @user_id User identifier @offset_chat_id Chat identifier starting from which to return chats; use 0 for the first request @limit Maximum number of chats to be returned; up to 100 getGroupsInCommon user_id:int32 offset_chat_id:int53 limit:int32 = Chats; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index c47c8ab754fb16aaec92ba6ba73950c178fcbe18..b2653c4c0262f3e6f40fa76dcd96fc67637775f4 100644 GIT binary patch delta 62 zcmV-E0KxyPo;uU8-TUF-rHXJvF#b!l{AVr*qZX>((Bb8~5L UZbN8cbaR(S0s promise_; + + public: + explicit GetGroupsForDiscussionQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(create_storer(telegram_api::channels_getGroupsForDiscussion()))); + } + + void on_result(uint64 id, BufferSlice packet) override { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto chats_ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetGroupsForDiscussionQuery " << to_string(chats_ptr); + int32 constructor_id = chats_ptr->get_id(); + switch (constructor_id) { + case telegram_api::messages_chats::ID: { + auto chats = move_tl_object_as(chats_ptr); + td->contacts_manager_->on_get_dialogs_for_discussion(std::move(chats->chats_)); + break; + } + case telegram_api::messages_chatsSlice::ID: { + auto chats = move_tl_object_as(chats_ptr); + LOG(ERROR) << "Receive chatsSlice in result of GetCreatedPublicChannelsQuery"; + td->contacts_manager_->on_get_dialogs_for_discussion(std::move(chats->chats_)); + break; + } + default: + UNREACHABLE(); + } + + promise_.set_value(Unit()); + } + + void on_error(uint64 id, Status status) override { + promise_.set_error(std::move(status)); + } +}; + class GetUsersQuery : public Td::ResultHandler { Promise promise_; @@ -4808,6 +4852,41 @@ ChannelId ContactsManager::migrate_chat_to_megagroup(ChatId chat_id, Promise ContactsManager::get_channel_ids(vector> &&chats, + const char *source) { + vector channel_ids; + for (auto &chat : chats) { + auto channel_id = get_channel_id(chat); + if (!channel_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << channel_id << " from " << source << " in " << to_string(chat); + } else { + channel_ids.push_back(channel_id); + } + on_get_chat(std::move(chat), source); + } + return channel_ids; +} + +vector ContactsManager::get_dialog_ids(vector> &&chats, + const char *source) { + vector dialog_ids; + for (auto &chat : chats) { + auto channel_id = get_channel_id(chat); + if (!channel_id.is_valid()) { + auto chat_id = get_chat_id(chat); + if (!chat_id.is_valid()) { + LOG(ERROR) << "Receive invalid chat from " << source << " in " << to_string(chat); + } else { + dialog_ids.push_back(DialogId(chat_id)); + } + } else { + dialog_ids.push_back(DialogId(channel_id)); + } + on_get_chat(std::move(chat), source); + } + return dialog_ids; +} + vector ContactsManager::get_created_public_dialogs(Promise &&promise) { if (created_public_channels_inited_) { promise.set_value(Unit()); @@ -4824,44 +4903,25 @@ vector ContactsManager::get_created_public_dialogs(Promise &&pro void ContactsManager::on_get_created_public_channels(vector> &&chats) { created_public_channels_inited_ = true; - created_public_channels_.clear(); + created_public_channels_ = get_channel_ids(std::move(chats), "on_get_created_public_channels"); +} - for (auto &chat : chats) { - switch (chat->get_id()) { - case telegram_api::chatEmpty::ID: - LOG(ERROR) << "Receive chatEmpty as created public channel"; - break; - case telegram_api::chat::ID: - LOG(ERROR) << "Receive chat as created public channel"; - break; - case telegram_api::chatForbidden::ID: - LOG(ERROR) << "Receive chatForbidden as created public channel"; - break; - case telegram_api::channel::ID: { - auto c = static_cast(chat.get()); - ChannelId channel_id(c->id_); - if (!channel_id.is_valid()) { - LOG(ERROR) << "Receive invalid " << channel_id; - continue; - } - created_public_channels_.push_back(channel_id); - break; - } - case telegram_api::channelForbidden::ID: { - auto c = static_cast(chat.get()); - ChannelId channel_id(c->id_); - if (!channel_id.is_valid()) { - LOG(ERROR) << "Receive invalid " << channel_id; - continue; - } - created_public_channels_.push_back(channel_id); - break; - } - default: - UNREACHABLE(); - } - on_get_chat(std::move(chat), "on_get_created_public_channels"); +vector ContactsManager::get_dialogs_for_discussion(Promise &&promise) { + if (dialogs_for_discussion_inited_) { + promise.set_value(Unit()); + return transform(dialogs_for_discussion_, [&](DialogId dialog_id) { + td_->messages_manager_->force_create_dialog(dialog_id, "get_dialogs_for_discussion"); + return dialog_id; + }); } + + td_->create_handler(std::move(promise))->send(); + return {}; +} + +void ContactsManager::on_get_dialogs_for_discussion(vector> &&chats) { + dialogs_for_discussion_inited_ = true; + dialogs_for_discussion_ = get_dialog_ids(std::move(chats), "on_get_dialogs_for_discussion"); } void ContactsManager::on_imported_contacts(int64 random_id, vector imported_contact_user_ids, diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 5ce3b415..02b57f86 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -212,6 +212,8 @@ class ContactsManager : public Actor { void on_get_created_public_channels(vector> &&chats); + void on_get_dialogs_for_discussion(vector> &&chats); + UserId get_my_id() const; void set_my_online_status(bool is_online, bool send_update, bool is_local); @@ -338,6 +340,8 @@ class ContactsManager : public Actor { vector get_created_public_dialogs(Promise &&promise); + vector get_dialogs_for_discussion(Promise &&promise); + bool is_user_contact(UserId user_id) const; bool is_user_deleted(UserId user_id) const; @@ -1097,6 +1101,10 @@ class ContactsManager : public Actor { tl_object_ptr get_secret_chat_object_const(SecretChatId secret_chat_id, const SecretChat *secret_chat) const; + vector get_channel_ids(vector> &&chats, const char *source); + + vector get_dialog_ids(vector> &&chats, const char *source); + void delete_chat_participant(ChatId chat_id, UserId user_id, Promise &&promise); void change_channel_participant_status_impl(ChannelId channel_id, UserId user_id, DialogParticipantStatus status, @@ -1162,6 +1170,9 @@ class ContactsManager : public Actor { bool created_public_channels_inited_ = false; vector created_public_channels_; + bool dialogs_for_discussion_inited_ = false; + vector dialogs_for_discussion_; + std::unordered_map>, UserIdHash> load_user_from_database_queries_; std::unordered_set loaded_from_database_users_; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 3b7ffd17..0ecba8ac 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -1071,6 +1071,22 @@ class GetCreatedPublicChatsRequest : public RequestActor<> { } }; +class GetSuitableDiscussionChatsRequest : public RequestActor<> { + vector dialog_ids_; + + void do_run(Promise &&promise) override { + dialog_ids_ = td->contacts_manager_->get_dialogs_for_discussion(std::move(promise)); + } + + void do_send_result() override { + send_result(MessagesManager::get_chats_object(dialog_ids_)); + } + + public: + GetSuitableDiscussionChatsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + class GetMessageRequest : public RequestOnceActor { FullMessageId full_message_id_; @@ -5513,6 +5529,11 @@ void Td::on_request(uint64 id, const td_api::getCreatedPublicChats &request) { CREATE_NO_ARGS_REQUEST(GetCreatedPublicChatsRequest); } +void Td::on_request(uint64 id, const td_api::getSuitableDiscussionChats &request) { + CHECK_IS_USER(); + CREATE_NO_ARGS_REQUEST(GetSuitableDiscussionChatsRequest); +} + void Td::on_request(uint64 id, const td_api::addRecentlyFoundChat &request) { CHECK_IS_USER(); answer_ok_query(id, messages_manager_->add_recently_found_dialog(DialogId(request.chat_id_))); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index da9541fa..a385ae2d 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -526,6 +526,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, const td_api::getCreatedPublicChats &request); + void on_request(uint64 id, const td_api::getSuitableDiscussionChats &request); + void on_request(uint64 id, const td_api::openChat &request); void on_request(uint64 id, const td_api::closeChat &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index cf39f587..bd547814 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3258,6 +3258,8 @@ class CliClient final : public Actor { send_request(td_api::make_object(as_supergroup_id(args))); } else if (op == "gcpc") { send_request(td_api::make_object()); + } else if (op == "gsdc") { + send_request(td_api::make_object()); } else if (op == "cpc") { string user_id; string force;