diff --git a/CMakeLists.txt b/CMakeLists.txt index 65813837b..5fc7084df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -289,6 +289,7 @@ set(TDLIB_SOURCE td/telegram/CallDiscardReason.cpp td/telegram/CallManager.cpp td/telegram/CallbackQueriesManager.cpp + td/telegram/ChannelParticipantFilter.cpp td/telegram/ClientActor.cpp td/telegram/ConfigManager.cpp td/telegram/ConfigShared.cpp @@ -479,6 +480,7 @@ set(TDLIB_SOURCE td/telegram/CallbackQueriesManager.h td/telegram/ChainId.h td/telegram/ChannelId.h + td/telegram/ChannelParticipantFilter.h td/telegram/ChatId.h td/telegram/ClientActor.h td/telegram/ConfigManager.h diff --git a/td/telegram/ChannelParticipantFilter.cpp b/td/telegram/ChannelParticipantFilter.cpp new file mode 100644 index 000000000..39b035867 --- /dev/null +++ b/td/telegram/ChannelParticipantFilter.cpp @@ -0,0 +1,116 @@ +// +// 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/ChannelParticipantFilter.h" + +namespace td { + +tl_object_ptr ChannelParticipantFilter::get_input_channel_participants_filter() + const { + switch (type_) { + case Type::Recent: + return make_tl_object(); + case Type::Contacts: + return make_tl_object(query_); + case Type::Administrators: + return make_tl_object(); + case Type::Search: + return make_tl_object(query_); + case Type::Mention: { + int32 flags = 0; + if (!query_.empty()) { + flags |= telegram_api::channelParticipantsMentions::Q_MASK; + } + if (top_thread_message_id_.is_valid()) { + flags |= telegram_api::channelParticipantsMentions::TOP_MSG_ID_MASK; + } + return make_tl_object( + flags, query_, top_thread_message_id_.get_server_message_id().get()); + } + case Type::Restricted: + return make_tl_object(query_); + case Type::Banned: + return make_tl_object(query_); + case Type::Bots: + return make_tl_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +ChannelParticipantFilter::ChannelParticipantFilter(const tl_object_ptr &filter) { + if (filter == nullptr) { + type_ = Type::Recent; + return; + } + switch (filter->get_id()) { + case td_api::supergroupMembersFilterRecent::ID: + type_ = Type::Recent; + return; + case td_api::supergroupMembersFilterContacts::ID: + type_ = Type::Contacts; + query_ = static_cast(filter.get())->query_; + return; + case td_api::supergroupMembersFilterAdministrators::ID: + type_ = Type::Administrators; + return; + case td_api::supergroupMembersFilterSearch::ID: + type_ = Type::Search; + query_ = static_cast(filter.get())->query_; + return; + case td_api::supergroupMembersFilterMention::ID: { + auto mention_filter = static_cast(filter.get()); + type_ = Type::Mention; + query_ = mention_filter->query_; + 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(); + } + return; + } + case td_api::supergroupMembersFilterRestricted::ID: + type_ = Type::Restricted; + query_ = static_cast(filter.get())->query_; + return; + case td_api::supergroupMembersFilterBanned::ID: + type_ = Type::Banned; + query_ = static_cast(filter.get())->query_; + return; + case td_api::supergroupMembersFilterBots::ID: + type_ = Type::Bots; + return; + default: + UNREACHABLE(); + type_ = Type::Recent; + } +} + +StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantFilter &filter) { + switch (filter.type_) { + case ChannelParticipantFilter::Type::Recent: + return string_builder << "Recent"; + case ChannelParticipantFilter::Type::Contacts: + return string_builder << "Contacts \"" << filter.query_ << '"'; + case ChannelParticipantFilter::Type::Administrators: + return string_builder << "Administrators"; + case ChannelParticipantFilter::Type::Search: + return string_builder << "Search \"" << filter.query_ << '"'; + case ChannelParticipantFilter::Type::Mention: + return string_builder << "Mention \"" << filter.query_ << "\" in thread of " << filter.top_thread_message_id_; + case ChannelParticipantFilter::Type::Restricted: + return string_builder << "Restricted \"" << filter.query_ << '"'; + case ChannelParticipantFilter::Type::Banned: + return string_builder << "Banned \"" << filter.query_ << '"'; + case ChannelParticipantFilter::Type::Bots: + return string_builder << "Bots"; + default: + UNREACHABLE(); + return string_builder; + } +} + +} // namespace td diff --git a/td/telegram/ChannelParticipantFilter.h b/td/telegram/ChannelParticipantFilter.h new file mode 100644 index 000000000..8e17c79e4 --- /dev/null +++ b/td/telegram/ChannelParticipantFilter.h @@ -0,0 +1,62 @@ +// +// 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/MessageId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class ChannelParticipantFilter { + enum class Type : int32 { Recent, Contacts, Administrators, Search, Mention, Restricted, Banned, Bots }; + Type type_; + string query_; + MessageId top_thread_message_id_; + + friend StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantFilter &filter); + + public: + explicit ChannelParticipantFilter(const td_api::object_ptr &filter); + + tl_object_ptr get_input_channel_participants_filter() const; + + bool is_administrators() const { + return type_ == Type::Administrators; + } + + bool is_bots() const { + return type_ == Type::Bots; + } + + bool is_recent() const { + return type_ == Type::Recent; + } + + bool is_contacts() const { + return type_ == Type::Contacts; + } + + bool is_search() const { + return type_ == Type::Search; + } + + bool is_restricted() const { + return type_ == Type::Restricted; + } + + bool is_banned() const { + return type_ == Type::Banned; + } +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantFilter &filter); + +} // namespace td diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 50d1a0778..365c64f7d 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -7,6 +7,7 @@ #include "td/telegram/ContactsManager.h" #include "td/telegram/AuthManager.h" +#include "td/telegram/ChannelParticipantFilter.h" #include "td/telegram/ConfigShared.h" #include "td/telegram/Dependencies.h" #include "td/telegram/DialogInviteLink.h" @@ -2807,7 +2808,7 @@ class GetChannelParticipantsQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(ChannelId channel_id, const ChannelParticipantsFilter &filter, int32 offset, int32 limit) { + void send(ChannelId channel_id, const ChannelParticipantFilter &filter, int32 offset, int32 limit) { auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { return promise_.set_error(Status::Error(400, "Supergroup not found")); @@ -12039,7 +12040,7 @@ bool ContactsManager::is_user_contact(const User *u, UserId user_id, bool is_mut } void ContactsManager::on_get_channel_participants( - ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit, string additional_query, + ChannelId channel_id, ChannelParticipantFilter &&filter, int32 offset, int32 limit, string additional_query, int32 additional_limit, tl_object_ptr &&channel_participants, Promise &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); @@ -15414,9 +15415,9 @@ void ContactsManager::get_channel_participants(ChannelId channel_id, return promise.set_error(Status::Error(400, "Member list is inaccessible")); } - ChannelParticipantsFilter participants_filter(filter); + ChannelParticipantFilter participant_filter(filter); auto get_channel_participants_promise = PromiseCreator::lambda( - [actor_id = actor_id(this), channel_id, filter = participants_filter, + [actor_id = actor_id(this), channel_id, filter = participant_filter, additional_query = std::move(additional_query), offset, limit, additional_limit, promise = std::move(promise)]( Result> &&result) mutable { if (result.is_error()) { @@ -15427,7 +15428,7 @@ void ContactsManager::get_channel_participants(ChannelId channel_id, } }); td_->create_handler(std::move(get_channel_participants_promise)) - ->send(channel_id, participants_filter, offset, limit); + ->send(channel_id, participant_filter, offset, limit); } td_api::object_ptr ContactsManager::get_chat_administrators_object( diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 77fa43ea3..1ad671c4c 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -56,6 +56,8 @@ namespace td { struct BinlogEvent; +class ChannelParticipantFilter; + struct MinChannel; class Td; @@ -1566,7 +1568,7 @@ class ContactsManager final : public Actor { 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, + void on_get_channel_participants(ChannelId channel_id, ChannelParticipantFilter &&filter, int32 offset, int32 limit, string additional_query, int32 additional_limit, tl_object_ptr &&channel_participants, Promise &&promise); diff --git a/td/telegram/DialogParticipant.cpp b/td/telegram/DialogParticipant.cpp index 3aa44e576..7b5ecadf1 100644 --- a/td/telegram/DialogParticipant.cpp +++ b/td/telegram/DialogParticipant.cpp @@ -740,109 +740,4 @@ td_api::object_ptr DialogParticipants::get_chat_members_obj return td_api::make_object(total_count_, std::move(chat_members)); } -tl_object_ptr -ChannelParticipantsFilter::get_input_channel_participants_filter() const { - switch (type_) { - case Type::Recent: - return make_tl_object(); - case Type::Contacts: - return make_tl_object(query_); - case Type::Administrators: - return make_tl_object(); - case Type::Search: - return make_tl_object(query_); - case Type::Mention: { - int32 flags = 0; - if (!query_.empty()) { - flags |= telegram_api::channelParticipantsMentions::Q_MASK; - } - if (top_thread_message_id_.is_valid()) { - flags |= telegram_api::channelParticipantsMentions::TOP_MSG_ID_MASK; - } - return make_tl_object( - flags, query_, top_thread_message_id_.get_server_message_id().get()); - } - case Type::Restricted: - return make_tl_object(query_); - case Type::Banned: - return make_tl_object(query_); - case Type::Bots: - return make_tl_object(); - default: - UNREACHABLE(); - return nullptr; - } -} - -ChannelParticipantsFilter::ChannelParticipantsFilter(const tl_object_ptr &filter) { - if (filter == nullptr) { - type_ = Type::Recent; - return; - } - switch (filter->get_id()) { - case td_api::supergroupMembersFilterRecent::ID: - type_ = Type::Recent; - return; - case td_api::supergroupMembersFilterContacts::ID: - type_ = Type::Contacts; - query_ = static_cast(filter.get())->query_; - return; - case td_api::supergroupMembersFilterAdministrators::ID: - type_ = Type::Administrators; - return; - case td_api::supergroupMembersFilterSearch::ID: - type_ = Type::Search; - query_ = static_cast(filter.get())->query_; - return; - case td_api::supergroupMembersFilterMention::ID: { - auto mention_filter = static_cast(filter.get()); - type_ = Type::Mention; - query_ = mention_filter->query_; - 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(); - } - return; - } - case td_api::supergroupMembersFilterRestricted::ID: - type_ = Type::Restricted; - query_ = static_cast(filter.get())->query_; - return; - case td_api::supergroupMembersFilterBanned::ID: - type_ = Type::Banned; - query_ = static_cast(filter.get())->query_; - return; - case td_api::supergroupMembersFilterBots::ID: - type_ = Type::Bots; - return; - default: - UNREACHABLE(); - type_ = Type::Recent; - } -} - -StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantsFilter &filter) { - switch (filter.type_) { - case ChannelParticipantsFilter::Type::Recent: - return string_builder << "Recent"; - case ChannelParticipantsFilter::Type::Contacts: - return string_builder << "Contacts \"" << filter.query_ << '"'; - case ChannelParticipantsFilter::Type::Administrators: - return string_builder << "Administrators"; - case ChannelParticipantsFilter::Type::Search: - return string_builder << "Search \"" << filter.query_ << '"'; - case ChannelParticipantsFilter::Type::Mention: - return string_builder << "Mention \"" << filter.query_ << "\" in thread of " << filter.top_thread_message_id_; - case ChannelParticipantsFilter::Type::Restricted: - return string_builder << "Restricted \"" << filter.query_ << '"'; - case ChannelParticipantsFilter::Type::Banned: - return string_builder << "Banned \"" << filter.query_ << '"'; - case ChannelParticipantsFilter::Type::Bots: - return string_builder << "Bots"; - default: - UNREACHABLE(); - return string_builder; - } -} - } // namespace td diff --git a/td/telegram/DialogParticipant.h b/td/telegram/DialogParticipant.h index a31d36aed..91ef31c16 100644 --- a/td/telegram/DialogParticipant.h +++ b/td/telegram/DialogParticipant.h @@ -535,50 +535,6 @@ struct DialogParticipants { td_api::object_ptr get_chat_members_object(Td *td) const; }; -class ChannelParticipantsFilter { - enum class Type : int32 { Recent, Contacts, Administrators, Search, Mention, Restricted, Banned, Bots }; - Type type_; - string query_; - MessageId top_thread_message_id_; - - friend StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantsFilter &filter); - - public: - explicit ChannelParticipantsFilter(const tl_object_ptr &filter); - - tl_object_ptr get_input_channel_participants_filter() const; - - bool is_administrators() const { - return type_ == Type::Administrators; - } - - bool is_bots() const { - return type_ == Type::Bots; - } - - bool is_recent() const { - return type_ == Type::Recent; - } - - bool is_contacts() const { - return type_ == Type::Contacts; - } - - bool is_search() const { - return type_ == Type::Search; - } - - bool is_restricted() const { - return type_ == Type::Restricted; - } - - bool is_banned() const { - return type_ == Type::Banned; - } -}; - -StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantsFilter &filter); - DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr &status); AdministratorRights get_administrator_rights(tl_object_ptr &&admin_rights);