Move get_channel_participant to DialogParticipantManager.

This commit is contained in:
levlam 2024-01-08 17:45:04 +03:00
parent f8565154a1
commit bba173ea7d
4 changed files with 110 additions and 109 deletions

View File

@ -3039,62 +3039,6 @@ class GetFullChannelQuery final : public Td::ResultHandler {
}
};
class GetChannelParticipantQuery final : public Td::ResultHandler {
Promise<DialogParticipant> promise_;
ChannelId channel_id_;
DialogId participant_dialog_id_;
public:
explicit GetChannelParticipantQuery(Promise<DialogParticipant> &&promise) : promise_(std::move(promise)) {
}
void send(ChannelId channel_id, DialogId participant_dialog_id, tl_object_ptr<telegram_api::InputPeer> &&input_peer) {
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"));
}
CHECK(input_peer != nullptr);
channel_id_ = channel_id;
participant_dialog_id_ = participant_dialog_id;
send_query(G()->net_query_creator().create(
telegram_api::channels_getParticipant(std::move(input_channel), std::move(input_peer))));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::channels_getParticipant>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
auto participant = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for GetChannelParticipantQuery: " << to_string(participant);
td_->contacts_manager_->on_get_users(std::move(participant->users_), "GetChannelParticipantQuery");
td_->contacts_manager_->on_get_chats(std::move(participant->chats_), "GetChannelParticipantQuery");
DialogParticipant result(std::move(participant->participant_),
td_->contacts_manager_->get_channel_type(channel_id_));
if (!result.is_valid()) {
LOG(ERROR) << "Receive invalid " << result;
return promise_.set_error(Status::Error(500, "Receive invalid chat member"));
}
promise_.set_value(std::move(result));
}
void on_error(Status status) final {
if (status.message() == "USER_NOT_PARTICIPANT") {
promise_.set_value(DialogParticipant::left(participant_dialog_id_));
return;
}
if (participant_dialog_id_.get_type() != DialogType::Channel) {
td_->contacts_manager_->on_get_channel_error(channel_id_, status, "GetChannelParticipantQuery");
}
promise_.set_error(std::move(status));
}
};
class GetChannelParticipantsQuery final : public Td::ResultHandler {
Promise<tl_object_ptr<telegram_api::channels_channelParticipants>> promise_;
ChannelId channel_id_;
@ -8234,7 +8178,8 @@ void ContactsManager::set_channel_participant_status(ChannelId channel_id, Dialo
std::move(status), r_dialog_participant.ok().status_, std::move(promise));
});
get_channel_participant(channel_id, participant_dialog_id, std::move(on_result_promise));
td_->dialog_participant_manager_->get_channel_participant(channel_id, participant_dialog_id,
std::move(on_result_promise));
}
void ContactsManager::set_channel_participant_status_impl(ChannelId channel_id, DialogId participant_dialog_id,
@ -17830,48 +17775,6 @@ void ContactsManager::do_search_chat_participants(ChatId chat_id, const string &
})});
}
void ContactsManager::get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
Promise<DialogParticipant> &&promise) {
LOG(INFO) << "Trying to get " << participant_dialog_id << " as member of " << channel_id;
auto input_peer = td_->dialog_manager_->get_input_peer(participant_dialog_id, AccessRights::Know);
if (input_peer == nullptr) {
return promise.set_error(Status::Error(400, "Member not found"));
}
if (have_channel_participant_cache(channel_id)) {
auto *participant = get_channel_participant_from_cache(channel_id, participant_dialog_id);
if (participant != nullptr) {
return promise.set_value(DialogParticipant{*participant});
}
}
auto on_result_promise = PromiseCreator::lambda([actor_id = actor_id(this), channel_id, promise = std::move(promise)](
Result<DialogParticipant> r_dialog_participant) mutable {
TRY_RESULT_PROMISE(promise, dialog_participant, std::move(r_dialog_participant));
send_closure(actor_id, &ContactsManager::finish_get_channel_participant, channel_id, std::move(dialog_participant),
std::move(promise));
});
td_->create_handler<GetChannelParticipantQuery>(std::move(on_result_promise))
->send(channel_id, participant_dialog_id, std::move(input_peer));
}
void ContactsManager::finish_get_channel_participant(ChannelId channel_id, DialogParticipant &&dialog_participant,
Promise<DialogParticipant> &&promise) {
TRY_STATUS_PROMISE(promise, G()->close_status());
CHECK(dialog_participant.is_valid()); // checked in GetChannelParticipantQuery
LOG(INFO) << "Receive " << dialog_participant.dialog_id_ << " as a member of a channel " << channel_id;
dialog_participant.status_.update_restrictions();
if (have_channel_participant_cache(channel_id)) {
add_channel_participant_to_cache(channel_id, dialog_participant, false);
}
promise.set_value(std::move(dialog_participant));
}
void ContactsManager::get_channel_participants(ChannelId channel_id,
tl_object_ptr<td_api::SupergroupMembersFilter> &&filter,
string additional_query, int32 offset, int32 limit,

View File

@ -273,6 +273,8 @@ class ContactsManager final : public Actor {
void add_channel_participant_to_cache(ChannelId channel_id, const DialogParticipant &dialog_participant,
bool allow_replace);
const DialogParticipant *get_channel_participant_from_cache(ChannelId channel_id, DialogId participant_dialog_id);
void drop_channel_participant_cache(ChannelId channel_id);
int32 on_update_peer_located(vector<tl_object_ptr<telegram_api::PeerLocated>> &&peers, bool from_update);
@ -672,9 +674,6 @@ class ContactsManager final : public Actor {
void get_chat_participant(ChatId chat_id, UserId user_id, Promise<DialogParticipant> &&promise);
void get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
Promise<DialogParticipant> &&promise);
void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantFilter filter,
Promise<DialogParticipants> &&promise);
@ -1749,9 +1748,6 @@ class ContactsManager final : public Actor {
void finish_get_chat_participant(ChatId chat_id, UserId user_id, Promise<DialogParticipant> &&promise);
void finish_get_channel_participant(ChannelId channel_id, DialogParticipant &&dialog_participant,
Promise<DialogParticipant> &&promise);
void remove_dialog_suggested_action(SuggestedAction action);
void on_dismiss_suggested_action(SuggestedAction action, Result<Unit> &&result);
@ -1840,8 +1836,6 @@ class ContactsManager final : public Actor {
void update_channel_participant_status_cache(ChannelId channel_id, DialogId participant_dialog_id,
DialogParticipantStatus &&dialog_participant_status);
const DialogParticipant *get_channel_participant_from_cache(ChannelId channel_id, DialogId participant_dialog_id);
void set_chat_participant_status(ChatId chat_id, UserId user_id, DialogParticipantStatus status,
Promise<Unit> &&promise);

View File

@ -309,6 +309,62 @@ class GetChannelAdministratorsQuery final : public Td::ResultHandler {
}
};
class GetChannelParticipantQuery final : public Td::ResultHandler {
Promise<DialogParticipant> promise_;
ChannelId channel_id_;
DialogId participant_dialog_id_;
public:
explicit GetChannelParticipantQuery(Promise<DialogParticipant> &&promise) : promise_(std::move(promise)) {
}
void send(ChannelId channel_id, DialogId participant_dialog_id, tl_object_ptr<telegram_api::InputPeer> &&input_peer) {
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"));
}
CHECK(input_peer != nullptr);
channel_id_ = channel_id;
participant_dialog_id_ = participant_dialog_id;
send_query(G()->net_query_creator().create(
telegram_api::channels_getParticipant(std::move(input_channel), std::move(input_peer))));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::channels_getParticipant>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
auto participant = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for GetChannelParticipantQuery: " << to_string(participant);
td_->contacts_manager_->on_get_users(std::move(participant->users_), "GetChannelParticipantQuery");
td_->contacts_manager_->on_get_chats(std::move(participant->chats_), "GetChannelParticipantQuery");
DialogParticipant result(std::move(participant->participant_),
td_->contacts_manager_->get_channel_type(channel_id_));
if (!result.is_valid()) {
LOG(ERROR) << "Receive invalid " << result;
return promise_.set_error(Status::Error(500, "Receive invalid chat member"));
}
promise_.set_value(std::move(result));
}
void on_error(Status status) final {
if (status.message() == "USER_NOT_PARTICIPANT") {
promise_.set_value(DialogParticipant::left(participant_dialog_id_));
return;
}
if (participant_dialog_id_.get_type() != DialogType::Channel) {
td_->contacts_manager_->on_get_channel_error(channel_id_, status, "GetChannelParticipantQuery");
}
promise_.set_error(std::move(status));
}
};
DialogParticipantManager::DialogParticipantManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
update_dialog_online_member_count_timeout_.set_callback(on_update_dialog_online_member_count_timeout_callback);
update_dialog_online_member_count_timeout_.set_callback_data(static_cast<void *>(this));
@ -1008,8 +1064,7 @@ void DialogParticipantManager::do_get_dialog_participant(DialogId dialog_id, Dia
return td_->contacts_manager_->get_chat_participant(dialog_id.get_chat_id(), participant_dialog_id.get_user_id(),
std::move(promise));
case DialogType::Channel:
return td_->contacts_manager_->get_channel_participant(dialog_id.get_channel_id(), participant_dialog_id,
std::move(promise));
return get_channel_participant(dialog_id.get_channel_id(), participant_dialog_id, std::move(promise));
case DialogType::SecretChat: {
auto my_user_id = td_->contacts_manager_->get_my_id();
auto peer_user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id());
@ -1029,4 +1084,47 @@ void DialogParticipantManager::do_get_dialog_participant(DialogId dialog_id, Dia
}
}
void DialogParticipantManager::get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
Promise<DialogParticipant> &&promise) {
LOG(INFO) << "Trying to get " << participant_dialog_id << " as member of " << channel_id;
auto input_peer = td_->dialog_manager_->get_input_peer(participant_dialog_id, AccessRights::Know);
if (input_peer == nullptr) {
return promise.set_error(Status::Error(400, "Member not found"));
}
if (td_->contacts_manager_->have_channel_participant_cache(channel_id)) {
auto *participant = td_->contacts_manager_->get_channel_participant_from_cache(channel_id, participant_dialog_id);
if (participant != nullptr) {
return promise.set_value(DialogParticipant{*participant});
}
}
auto on_result_promise = PromiseCreator::lambda([actor_id = actor_id(this), channel_id, promise = std::move(promise)](
Result<DialogParticipant> r_dialog_participant) mutable {
TRY_RESULT_PROMISE(promise, dialog_participant, std::move(r_dialog_participant));
send_closure(actor_id, &DialogParticipantManager::finish_get_channel_participant, channel_id,
std::move(dialog_participant), std::move(promise));
});
td_->create_handler<GetChannelParticipantQuery>(std::move(on_result_promise))
->send(channel_id, participant_dialog_id, std::move(input_peer));
}
void DialogParticipantManager::finish_get_channel_participant(ChannelId channel_id,
DialogParticipant &&dialog_participant,
Promise<DialogParticipant> &&promise) {
TRY_STATUS_PROMISE(promise, G()->close_status());
CHECK(dialog_participant.is_valid()); // checked in GetChannelParticipantQuery
LOG(INFO) << "Receive " << dialog_participant.dialog_id_ << " as a member of a channel " << channel_id;
dialog_participant.status_.update_restrictions();
if (td_->contacts_manager_->have_channel_participant_cache(channel_id)) {
td_->contacts_manager_->add_channel_participant_to_cache(channel_id, dialog_participant, false);
}
promise.set_value(std::move(dialog_participant));
}
} // namespace td

View File

@ -82,6 +82,9 @@ class DialogParticipantManager final : public Actor {
void get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id,
Promise<td_api::object_ptr<td_api::chatMember>> &&promise);
void get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
Promise<DialogParticipant> &&promise);
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
private:
@ -127,6 +130,9 @@ class DialogParticipantManager final : public Actor {
void finish_get_dialog_participant(DialogParticipant &&dialog_participant,
Promise<td_api::object_ptr<td_api::chatMember>> &&promise);
void finish_get_channel_participant(ChannelId channel_id, DialogParticipant &&dialog_participant,
Promise<DialogParticipant> &&promise);
struct OnlineMemberCountInfo {
int32 online_member_count = 0;
double update_time = 0;