diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e5900bff..65813837b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -310,6 +310,7 @@ set(TDLIB_SOURCE td/telegram/DialogInviteLink.cpp td/telegram/DialogLocation.cpp td/telegram/DialogParticipant.cpp + td/telegram/DialogParticipantFilter.cpp td/telegram/DialogSource.cpp td/telegram/Document.cpp td/telegram/DocumentsManager.cpp @@ -504,6 +505,7 @@ set(TDLIB_SOURCE td/telegram/DialogListId.h td/telegram/DialogLocation.h td/telegram/DialogParticipant.h + td/telegram/DialogParticipantFilter.h td/telegram/DialogSource.h td/telegram/Document.h td/telegram/DocumentsManager.h diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 40517cc70..50d1a0778 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -15215,7 +15215,7 @@ void ContactsManager::do_get_dialog_participant(DialogId dialog_id, DialogId par DialogParticipants ContactsManager::search_private_chat_participants(UserId my_user_id, UserId peer_user_id, const string &query, int32 limit, - DialogParticipantsFilter filter) const { + DialogParticipantFilter filter) const { vector dialog_ids; if (filter.is_dialog_participant_suitable(td_, DialogParticipant::private_member(my_user_id, peer_user_id))) { dialog_ids.push_back(DialogId(my_user_id)); @@ -15233,7 +15233,7 @@ DialogParticipants ContactsManager::search_private_chat_participants(UserId my_u } void ContactsManager::search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, - DialogParticipantsFilter filter, + DialogParticipantFilter filter, Promise &&promise) { LOG(INFO) << "Receive searchChatMembers request to search for \"" << query << "\" in " << dialog_id << " with filter " << filter; @@ -15311,7 +15311,7 @@ void ContactsManager::finish_get_chat_participant(ChatId chat_id, UserId user_id } void ContactsManager::search_chat_participants(ChatId chat_id, const string &query, int32 limit, - DialogParticipantsFilter filter, Promise &&promise) { + DialogParticipantFilter filter, Promise &&promise) { if (limit < 0) { return promise.set_error(Status::Error(400, "Parameter limit must be non-negative")); } @@ -15329,7 +15329,7 @@ void ContactsManager::search_chat_participants(ChatId chat_id, const string &que } void ContactsManager::do_search_chat_participants(ChatId chat_id, const string &query, int32 limit, - DialogParticipantsFilter filter, + DialogParticipantFilter filter, Promise &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 26afb6591..77fa43ea3 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -16,6 +16,7 @@ #include "td/telegram/DialogInviteLink.h" #include "td/telegram/DialogLocation.h" #include "td/telegram/DialogParticipant.h" +#include "td/telegram/DialogParticipantFilter.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileSourceId.h" #include "td/telegram/FolderId.h" @@ -540,7 +541,7 @@ class ContactsManager final : public Actor { void get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id, Promise> &&promise); - void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantsFilter filter, + void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantFilter filter, Promise &&promise); void get_dialog_administrators(DialogId dialog_id, Promise> &&promise); @@ -1470,7 +1471,7 @@ class ContactsManager final : public Actor { int32 limit) const; DialogParticipants search_private_chat_participants(UserId my_user_id, UserId peer_user_id, const string &query, - int32 limit, DialogParticipantsFilter filter) const; + int32 limit, DialogParticipantFilter filter) const; void do_get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id, Promise &&promise); @@ -1559,10 +1560,10 @@ class ContactsManager final : public Actor { void delete_chat_participant(ChatId chat_id, UserId user_id, bool revoke_messages, Promise &&promise); - void search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantsFilter filter, + void search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantFilter filter, Promise &&promise); - void do_search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantsFilter filter, + void do_search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantFilter filter, Promise &&promise); void on_get_channel_participants(ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit, diff --git a/td/telegram/DialogParticipant.cpp b/td/telegram/DialogParticipant.cpp index a76c1aeb1..3aa44e576 100644 --- a/td/telegram/DialogParticipant.cpp +++ b/td/telegram/DialogParticipant.cpp @@ -845,131 +845,4 @@ StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipan } } -StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantsFilter &filter) { - switch (filter.type_) { - case DialogParticipantsFilter::Type::Contacts: - return string_builder << "Contacts"; - case DialogParticipantsFilter::Type::Administrators: - return string_builder << "Administrators"; - case DialogParticipantsFilter::Type::Members: - return string_builder << "Members"; - case DialogParticipantsFilter::Type::Restricted: - return string_builder << "Restricted"; - case DialogParticipantsFilter::Type::Banned: - return string_builder << "Banned"; - case DialogParticipantsFilter::Type::Mention: - return string_builder << "Mention"; - case DialogParticipantsFilter::Type::Bots: - return string_builder << "Bots"; - default: - UNREACHABLE(); - return string_builder; - } -} - -DialogParticipantsFilter::DialogParticipantsFilter(const tl_object_ptr &filter) { - if (filter == nullptr) { - type_ = Type::Members; - return; - } - switch (filter->get_id()) { - case td_api::chatMembersFilterContacts::ID: - type_ = Type::Contacts; - break; - case td_api::chatMembersFilterAdministrators::ID: - type_ = Type::Administrators; - break; - case td_api::chatMembersFilterMembers::ID: - type_ = Type::Members; - break; - case td_api::chatMembersFilterRestricted::ID: - type_ = Type::Restricted; - break; - case td_api::chatMembersFilterBanned::ID: - type_ = Type::Banned; - break; - case td_api::chatMembersFilterMention::ID: { - auto mention_filter = static_cast(filter.get()); - top_thread_message_id_ = MessageId(mention_filter->message_thread_id_); - if (!top_thread_message_id_.is_valid() || !top_thread_message_id_.is_server()) { - top_thread_message_id_ = MessageId(); - } - type_ = Type::Mention; - break; - } - case td_api::chatMembersFilterBots::ID: - type_ = Type::Bots; - break; - default: - UNREACHABLE(); - type_ = Type::Members; - break; - } -} - -td_api::object_ptr DialogParticipantsFilter::get_supergroup_members_filter_object( - const string &query) const { - switch (type_) { - case Type::Contacts: - return td_api::make_object(); - case Type::Administrators: - return td_api::make_object(); - case Type::Members: - return td_api::make_object(query); - case Type::Restricted: - return td_api::make_object(query); - case Type::Banned: - return td_api::make_object(query); - case Type::Mention: - return td_api::make_object(query, top_thread_message_id_.get()); - case Type::Bots: - return td_api::make_object(); - default: - UNREACHABLE(); - return nullptr; - } -} - -bool DialogParticipantsFilter::has_query() const { - switch (type_) { - case Type::Members: - case Type::Restricted: - case Type::Banned: - case Type::Mention: - return true; - case Type::Contacts: - case Type::Administrators: - case Type::Bots: - return false; - default: - UNREACHABLE(); - return false; - } -} - -bool DialogParticipantsFilter::is_dialog_participant_suitable(const Td *td, - const DialogParticipant &participant) const { - switch (type_) { - case Type::Contacts: - return participant.dialog_id_.get_type() == DialogType::User && - td->contacts_manager_->is_user_contact(participant.dialog_id_.get_user_id()); - case Type::Administrators: - return participant.status_.is_administrator(); - case Type::Members: - return participant.status_.is_member(); - case Type::Restricted: - return participant.status_.is_restricted(); - case Type::Banned: - return participant.status_.is_banned(); - case Type::Mention: - return true; - case Type::Bots: - return participant.dialog_id_.get_type() == DialogType::User && - td->contacts_manager_->is_user_bot(participant.dialog_id_.get_user_id()); - default: - UNREACHABLE(); - return false; - } -} - } // namespace td diff --git a/td/telegram/DialogParticipant.h b/td/telegram/DialogParticipant.h index e03d55b0a..a31d36aed 100644 --- a/td/telegram/DialogParticipant.h +++ b/td/telegram/DialogParticipant.h @@ -579,25 +579,6 @@ class ChannelParticipantsFilter { StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantsFilter &filter); -class DialogParticipantsFilter { - enum class Type : int32 { Contacts, Administrators, Members, Restricted, Banned, Mention, Bots }; - Type type_; - MessageId top_thread_message_id_; - - friend StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantsFilter &filter); - - public: - explicit DialogParticipantsFilter(const tl_object_ptr &filter); - - td_api::object_ptr get_supergroup_members_filter_object(const string &query) const; - - bool has_query() const; - - bool is_dialog_participant_suitable(const Td *td, const DialogParticipant &participant) const; -}; - -StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantsFilter &filter); - DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr &status); AdministratorRights get_administrator_rights(tl_object_ptr &&admin_rights); diff --git a/td/telegram/DialogParticipantFilter.cpp b/td/telegram/DialogParticipantFilter.cpp new file mode 100644 index 000000000..8fbdddaa0 --- /dev/null +++ b/td/telegram/DialogParticipantFilter.cpp @@ -0,0 +1,141 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 +// +// 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/DialogParticipantFilter.h" + +#include "td/telegram/ContactsManager.h" +#include "td/telegram/DialogParticipant.h" +#include "td/telegram/Td.h" + +namespace td { + +StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantFilter &filter) { + switch (filter.type_) { + case DialogParticipantFilter::Type::Contacts: + return string_builder << "Contacts"; + case DialogParticipantFilter::Type::Administrators: + return string_builder << "Administrators"; + case DialogParticipantFilter::Type::Members: + return string_builder << "Members"; + case DialogParticipantFilter::Type::Restricted: + return string_builder << "Restricted"; + case DialogParticipantFilter::Type::Banned: + return string_builder << "Banned"; + case DialogParticipantFilter::Type::Mention: + return string_builder << "Mention"; + case DialogParticipantFilter::Type::Bots: + return string_builder << "Bots"; + default: + UNREACHABLE(); + return string_builder; + } +} + +DialogParticipantFilter::DialogParticipantFilter(const tl_object_ptr &filter) { + if (filter == nullptr) { + type_ = Type::Members; + return; + } + switch (filter->get_id()) { + case td_api::chatMembersFilterContacts::ID: + type_ = Type::Contacts; + break; + case td_api::chatMembersFilterAdministrators::ID: + type_ = Type::Administrators; + break; + case td_api::chatMembersFilterMembers::ID: + type_ = Type::Members; + break; + case td_api::chatMembersFilterRestricted::ID: + type_ = Type::Restricted; + break; + case td_api::chatMembersFilterBanned::ID: + type_ = Type::Banned; + break; + case td_api::chatMembersFilterMention::ID: { + auto mention_filter = static_cast(filter.get()); + top_thread_message_id_ = MessageId(mention_filter->message_thread_id_); + if (!top_thread_message_id_.is_valid() || !top_thread_message_id_.is_server()) { + top_thread_message_id_ = MessageId(); + } + type_ = Type::Mention; + break; + } + case td_api::chatMembersFilterBots::ID: + type_ = Type::Bots; + break; + default: + UNREACHABLE(); + type_ = Type::Members; + break; + } +} + +td_api::object_ptr DialogParticipantFilter::get_supergroup_members_filter_object( + const string &query) const { + switch (type_) { + case Type::Contacts: + return td_api::make_object(); + case Type::Administrators: + return td_api::make_object(); + case Type::Members: + return td_api::make_object(query); + case Type::Restricted: + return td_api::make_object(query); + case Type::Banned: + return td_api::make_object(query); + case Type::Mention: + return td_api::make_object(query, top_thread_message_id_.get()); + case Type::Bots: + return td_api::make_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +bool DialogParticipantFilter::has_query() const { + switch (type_) { + case Type::Members: + case Type::Restricted: + case Type::Banned: + case Type::Mention: + return true; + case Type::Contacts: + case Type::Administrators: + case Type::Bots: + return false; + default: + UNREACHABLE(); + return false; + } +} + +bool DialogParticipantFilter::is_dialog_participant_suitable(const Td *td, const DialogParticipant &participant) const { + switch (type_) { + case Type::Contacts: + return participant.dialog_id_.get_type() == DialogType::User && + td->contacts_manager_->is_user_contact(participant.dialog_id_.get_user_id()); + case Type::Administrators: + return participant.status_.is_administrator(); + case Type::Members: + return participant.status_.is_member(); + case Type::Restricted: + return participant.status_.is_restricted(); + case Type::Banned: + return participant.status_.is_banned(); + case Type::Mention: + return true; + case Type::Bots: + return participant.dialog_id_.get_type() == DialogType::User && + td->contacts_manager_->is_user_bot(participant.dialog_id_.get_user_id()); + default: + UNREACHABLE(); + return false; + } +} + +} // namespace td diff --git a/td/telegram/DialogParticipantFilter.h b/td/telegram/DialogParticipantFilter.h new file mode 100644 index 000000000..b330ab66f --- /dev/null +++ b/td/telegram/DialogParticipantFilter.h @@ -0,0 +1,42 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 +// +// 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/DialogId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +struct DialogParticipant; +class Td; + +class DialogParticipantFilter { + enum class Type : int32 { Contacts, Administrators, Members, Restricted, Banned, Mention, Bots }; + Type type_; + MessageId top_thread_message_id_; + + friend StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantFilter &filter); + + public: + explicit DialogParticipantFilter(const tl_object_ptr &filter); + + td_api::object_ptr get_supergroup_members_filter_object(const string &query) const; + + bool has_query() const; + + bool is_dialog_participant_suitable(const Td *td, const DialogParticipant &participant) const; +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantFilter &filter); + +} // namespace td diff --git a/td/telegram/GroupCallManager.cpp b/td/telegram/GroupCallManager.cpp index cf68604fb..5d01f311f 100644 --- a/td/telegram/GroupCallManager.cpp +++ b/td/telegram/GroupCallManager.cpp @@ -10,6 +10,7 @@ #include "td/telegram/AuthManager.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/DialogAction.h" +#include "td/telegram/DialogParticipantFilter.h" #include "td/telegram/Global.h" #include "td/telegram/MessageId.h" #include "td/telegram/MessageSender.h" @@ -2778,8 +2779,8 @@ void GroupCallManager::try_load_group_call_administrators(InputGroupCallId input std::move(result)); }); td_->contacts_manager_->search_dialog_participants( - dialog_id, string(), 100, - DialogParticipantsFilter(td_api::make_object()), std::move(promise)); + dialog_id, string(), 100, DialogParticipantFilter(td_api::make_object()), + std::move(promise)); } void GroupCallManager::finish_load_group_call_administrators(InputGroupCallId input_group_call_id, diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index d0067e29f..f0e2ae651 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -33,6 +33,7 @@ #include "td/telegram/DialogListId.h" #include "td/telegram/DialogLocation.h" #include "td/telegram/DialogParticipant.h" +#include "td/telegram/DialogParticipantFilter.h" #include "td/telegram/DialogSource.h" #include "td/telegram/DocumentsManager.h" #include "td/telegram/DownloadManager.h" @@ -6265,7 +6266,7 @@ void Td::on_request(uint64 id, td_api::searchChatMembers &request) { } }); contacts_manager_->search_dialog_participants(DialogId(request.chat_id_), request.query_, request.limit_, - DialogParticipantsFilter(request.filter_), std::move(query_promise)); + DialogParticipantFilter(request.filter_), std::move(query_promise)); } void Td::on_request(uint64 id, const td_api::getChatAdministrators &request) {