Return administrator ranks from getChatAdministrators.
GitOrigin-RevId: 8e3e540ae73aebacf9a3fe954b2b81511c999953
This commit is contained in:
parent
fbbf6470f3
commit
43d8e6ccdb
@ -373,6 +373,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/DelayDispatcher.cpp
|
td/telegram/DelayDispatcher.cpp
|
||||||
td/telegram/DeviceTokenManager.cpp
|
td/telegram/DeviceTokenManager.cpp
|
||||||
td/telegram/DhCache.cpp
|
td/telegram/DhCache.cpp
|
||||||
|
td/telegram/DialogAdministrator.cpp
|
||||||
td/telegram/DialogDb.cpp
|
td/telegram/DialogDb.cpp
|
||||||
td/telegram/DialogId.cpp
|
td/telegram/DialogId.cpp
|
||||||
td/telegram/DialogLocation.cpp
|
td/telegram/DialogLocation.cpp
|
||||||
@ -518,6 +519,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/DeviceTokenManager.h
|
td/telegram/DeviceTokenManager.h
|
||||||
td/telegram/DhCache.h
|
td/telegram/DhCache.h
|
||||||
td/telegram/DhConfig.h
|
td/telegram/DhConfig.h
|
||||||
|
td/telegram/DialogAdministrator.h
|
||||||
td/telegram/DialogDate.h
|
td/telegram/DialogDate.h
|
||||||
td/telegram/DialogDb.h
|
td/telegram/DialogDb.h
|
||||||
td/telegram/DialogId.h
|
td/telegram/DialogId.h
|
||||||
|
@ -321,6 +321,13 @@ userProfilePhotos total_count:int32 photos:vector<userProfilePhoto> = UserProfil
|
|||||||
users total_count:int32 user_ids:vector<int32> = Users;
|
users total_count:int32 user_ids:vector<int32> = Users;
|
||||||
|
|
||||||
|
|
||||||
|
//@description Contains information about a chat administrator @user_id User identifier of the administrator @custom_title Custom title of the administrator
|
||||||
|
chatAdministrator user_id:int32 custom_title:string = ChatAdministrator;
|
||||||
|
|
||||||
|
//@description Represents a list of chat administrators @administrators A list of chat administrators
|
||||||
|
chatAdministrators administrators:vector<chatAdministrator> = ChatAdministrators;
|
||||||
|
|
||||||
|
|
||||||
//@description Describes actions that a user is allowed to take in a chat
|
//@description Describes actions that a user is allowed to take in a chat
|
||||||
//@can_send_messages True, if the user can send text messages, contacts, locations, and venues
|
//@can_send_messages True, if the user can send text messages, contacts, locations, and venues
|
||||||
//@can_send_media_messages True, if the user can send audio files, documents, photos, videos, video notes, and voice notes. Implies can_send_messages permissions
|
//@can_send_media_messages True, if the user can send audio files, documents, photos, videos, video notes, and voice notes. Implies can_send_messages permissions
|
||||||
@ -3532,8 +3539,8 @@ getChatMember chat_id:int53 user_id:int32 = ChatMember;
|
|||||||
//@description Searches for a specified query in the first name, last name and username of the members of a specified chat. Requires administrator rights in channels @chat_id Chat identifier @query Query to search for @limit The maximum number of users to be returned @filter The type of users to return. By default, chatMembersFilterMembers
|
//@description Searches for a specified query in the first name, last name and username of the members of a specified chat. Requires administrator rights in channels @chat_id Chat identifier @query Query to search for @limit The maximum number of users to be returned @filter The type of users to return. By default, chatMembersFilterMembers
|
||||||
searchChatMembers chat_id:int53 query:string limit:int32 filter:ChatMembersFilter = ChatMembers;
|
searchChatMembers chat_id:int53 query:string limit:int32 filter:ChatMembersFilter = ChatMembers;
|
||||||
|
|
||||||
//@description Returns a list of users who are administrators of the chat @chat_id Chat identifier
|
//@description Returns a list of administrators of the chat with their custom titles @chat_id Chat identifier
|
||||||
getChatAdministrators chat_id:int53 = Users;
|
getChatAdministrators chat_id:int53 = ChatAdministrators;
|
||||||
|
|
||||||
|
|
||||||
//@description Clears draft messages in all chats @exclude_secret_chats If true, local draft messages in secret chats will not be cleared
|
//@description Clears draft messages in all chats @exclude_secret_chats If true, local draft messages in secret chats will not be cleared
|
||||||
|
Binary file not shown.
@ -2461,6 +2461,8 @@ class GetChannelAdministratorsQuery : public Td::ResultHandler {
|
|||||||
return promise_.set_error(Status::Error(3, "Supergroup not found"));
|
return promise_.set_error(Status::Error(3, "Supergroup not found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hash = 0; // to load even only ranks changed
|
||||||
|
|
||||||
channel_id_ = channel_id;
|
channel_id_ = channel_id;
|
||||||
send_query(G()->net_query_creator().create(create_storer(telegram_api::channels_getParticipants(
|
send_query(G()->net_query_creator().create(create_storer(telegram_api::channels_getParticipants(
|
||||||
std::move(input_channel), telegram_api::make_object<telegram_api::channelParticipantsAdmins>(), 0,
|
std::move(input_channel), telegram_api::make_object<telegram_api::channelParticipantsAdmins>(), 0,
|
||||||
@ -2479,18 +2481,23 @@ class GetChannelAdministratorsQuery : public Td::ResultHandler {
|
|||||||
case telegram_api::channels_channelParticipants::ID: {
|
case telegram_api::channels_channelParticipants::ID: {
|
||||||
auto participants = telegram_api::move_object_as<telegram_api::channels_channelParticipants>(participants_ptr);
|
auto participants = telegram_api::move_object_as<telegram_api::channels_channelParticipants>(participants_ptr);
|
||||||
td->contacts_manager_->on_get_users(std::move(participants->users_), "GetChannelAdministratorsQuery");
|
td->contacts_manager_->on_get_users(std::move(participants->users_), "GetChannelAdministratorsQuery");
|
||||||
vector<UserId> administrator_user_ids;
|
vector<DialogAdministrator> administrators;
|
||||||
administrator_user_ids.reserve(participants->participants_.size());
|
administrators.reserve(participants->participants_.size());
|
||||||
for (auto &participant : participants->participants_) {
|
for (auto &participant : participants->participants_) {
|
||||||
UserId user_id;
|
DialogParticipant dialog_participant =
|
||||||
downcast_call(*participant, [&user_id](auto &participant) { user_id = UserId(participant.user_id_); });
|
td->contacts_manager_->get_dialog_participant(channel_id_, std::move(participant));
|
||||||
if (user_id.is_valid()) {
|
if (!dialog_participant.user_id.is_valid() || !dialog_participant.status.is_administrator()) {
|
||||||
administrator_user_ids.push_back(user_id);
|
LOG(ERROR) << "Receive " << dialog_participant.user_id << " with status " << dialog_participant.status
|
||||||
|
<< " as an administrator of " << channel_id_;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
administrators.emplace_back(dialog_participant.user_id, dialog_participant.status.get_rank());
|
||||||
}
|
}
|
||||||
|
|
||||||
td->contacts_manager_->on_update_dialog_administrators(DialogId(channel_id_), std::move(administrator_user_ids),
|
td->contacts_manager_->on_update_channel_administrator_count(channel_id_,
|
||||||
true);
|
narrow_cast<int32>(administrators.size()));
|
||||||
|
td->contacts_manager_->on_update_dialog_administrators(DialogId(channel_id_), std::move(administrators), true);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case telegram_api::channels_channelParticipantsNotModified::ID:
|
case telegram_api::channels_channelParticipantsNotModified::ID:
|
||||||
@ -7901,18 +7908,18 @@ void ContactsManager::update_chat_full(ChatFull *chat_full, ChatId chat_id, bool
|
|||||||
chat_full->need_save_to_database |= chat_full->is_changed;
|
chat_full->need_save_to_database |= chat_full->is_changed;
|
||||||
chat_full->is_changed = false;
|
chat_full->is_changed = false;
|
||||||
if (chat_full->need_send_update) {
|
if (chat_full->need_send_update) {
|
||||||
vector<UserId> administrator_user_ids;
|
vector<DialogAdministrator> administrators;
|
||||||
vector<UserId> bot_user_ids;
|
vector<UserId> bot_user_ids;
|
||||||
for (const auto &participant : chat_full->participants) {
|
for (const auto &participant : chat_full->participants) {
|
||||||
auto user_id = participant.user_id;
|
auto user_id = participant.user_id;
|
||||||
if (participant.status.is_administrator()) {
|
if (participant.status.is_administrator()) {
|
||||||
administrator_user_ids.push_back(user_id);
|
administrators.emplace_back(user_id, participant.status.get_rank());
|
||||||
}
|
}
|
||||||
if (is_user_bot(user_id)) {
|
if (is_user_bot(user_id)) {
|
||||||
bot_user_ids.push_back(user_id);
|
bot_user_ids.push_back(user_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
on_update_dialog_administrators(DialogId(chat_id), std::move(administrator_user_ids), chat_full->version != -1);
|
on_update_dialog_administrators(DialogId(chat_id), std::move(administrators), chat_full->version != -1);
|
||||||
td_->messages_manager_->on_dialog_bots_updated(DialogId(chat_id), std::move(bot_user_ids));
|
td_->messages_manager_->on_dialog_bots_updated(DialogId(chat_id), std::move(bot_user_ids));
|
||||||
|
|
||||||
send_closure(
|
send_closure(
|
||||||
@ -9165,33 +9172,34 @@ void ContactsManager::on_get_channel_participants_success(
|
|||||||
filter.is_recent() && total_count != 0 && total_count < max_participant_count ? total_count : -1;
|
filter.is_recent() && total_count != 0 && total_count < max_participant_count ? total_count : -1;
|
||||||
int32 administrator_count = filter.is_administrators() ? total_count : -1;
|
int32 administrator_count = filter.is_administrators() ? total_count : -1;
|
||||||
if (is_full && (filter.is_administrators() || filter.is_bots() || filter.is_recent())) {
|
if (is_full && (filter.is_administrators() || filter.is_bots() || filter.is_recent())) {
|
||||||
vector<UserId> administrator_user_ids;
|
vector<DialogAdministrator> administrators;
|
||||||
vector<UserId> bot_user_ids;
|
vector<UserId> bot_user_ids;
|
||||||
{
|
{
|
||||||
auto user_ids = transform(result, [](const DialogParticipant &participant) { return participant.user_id; });
|
|
||||||
if (filter.is_recent()) {
|
if (filter.is_recent()) {
|
||||||
for (const auto &participant : result) {
|
for (const auto &participant : result) {
|
||||||
if (participant.status.is_administrator()) {
|
if (participant.status.is_administrator()) {
|
||||||
administrator_user_ids.push_back(participant.user_id);
|
administrators.emplace_back(participant.user_id, participant.status.get_rank());
|
||||||
}
|
}
|
||||||
if (is_user_bot(participant.user_id)) {
|
if (is_user_bot(participant.user_id)) {
|
||||||
bot_user_ids.push_back(participant.user_id);
|
bot_user_ids.push_back(participant.user_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
administrator_count = narrow_cast<int32>(administrator_user_ids.size());
|
administrator_count = narrow_cast<int32>(administrators.size());
|
||||||
|
|
||||||
if (get_channel_type(channel_id) == ChannelType::Megagroup && !td_->auth_manager_->is_bot()) {
|
if (get_channel_type(channel_id) == ChannelType::Megagroup && !td_->auth_manager_->is_bot()) {
|
||||||
cached_channel_participants_[channel_id] = result;
|
cached_channel_participants_[channel_id] = result;
|
||||||
update_channel_online_member_count(channel_id, true);
|
update_channel_online_member_count(channel_id, true);
|
||||||
}
|
}
|
||||||
} else if (filter.is_administrators()) {
|
} else if (filter.is_administrators()) {
|
||||||
administrator_user_ids = std::move(user_ids);
|
for (const auto &participant : result) {
|
||||||
|
administrators.emplace_back(participant.user_id, participant.status.get_rank());
|
||||||
|
}
|
||||||
} else if (filter.is_bots()) {
|
} else if (filter.is_bots()) {
|
||||||
bot_user_ids = std::move(user_ids);
|
bot_user_ids = transform(result, [](const DialogParticipant &participant) { return participant.user_id; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (filter.is_administrators() || filter.is_recent()) {
|
if (filter.is_administrators() || filter.is_recent()) {
|
||||||
on_update_dialog_administrators(DialogId(channel_id), std::move(administrator_user_ids), true);
|
on_update_dialog_administrators(DialogId(channel_id), std::move(administrators), true);
|
||||||
}
|
}
|
||||||
if (filter.is_bots() || filter.is_recent()) {
|
if (filter.is_bots() || filter.is_recent()) {
|
||||||
on_update_channel_bot_user_ids(channel_id, std::move(bot_user_ids));
|
on_update_channel_bot_user_ids(channel_id, std::move(bot_user_ids));
|
||||||
@ -9356,19 +9364,36 @@ void ContactsManager::speculative_add_channel_user(ChannelId channel_id, UserId
|
|||||||
update_channel(c, channel_id);
|
update_channel(c, channel_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_status.is_administrator() != old_status.is_administrator()) {
|
if (new_status.is_administrator() != old_status.is_administrator() ||
|
||||||
|
new_status.get_rank() != old_status.get_rank()) {
|
||||||
DialogId dialog_id(channel_id);
|
DialogId dialog_id(channel_id);
|
||||||
auto administrators_it = dialog_administrators_.find(dialog_id);
|
auto administrators_it = dialog_administrators_.find(dialog_id);
|
||||||
if (administrators_it != dialog_administrators_.end()) {
|
if (administrators_it != dialog_administrators_.end()) {
|
||||||
auto user_ids = administrators_it->second;
|
auto administrators = administrators_it->second;
|
||||||
if (new_status.is_administrator()) {
|
if (new_status.is_administrator()) {
|
||||||
if (!td::contains(user_ids, user_id)) {
|
bool is_found = false;
|
||||||
user_ids.push_back(user_id);
|
for (auto &administrator : administrators) {
|
||||||
on_update_dialog_administrators(dialog_id, std::move(user_ids), true);
|
if (administrator.get_user_id() == user_id) {
|
||||||
|
is_found = true;
|
||||||
|
if (administrator.get_rank() != new_status.get_rank()) {
|
||||||
|
administrator = DialogAdministrator(user_id, new_status.get_rank());
|
||||||
|
on_update_dialog_administrators(dialog_id, std::move(administrators), true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_found) {
|
||||||
|
administrators.emplace_back(user_id, new_status.get_rank());
|
||||||
|
on_update_dialog_administrators(dialog_id, std::move(administrators), true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (td::remove(user_ids, user_id)) {
|
size_t i = 0;
|
||||||
on_update_dialog_administrators(dialog_id, std::move(user_ids), true);
|
while (i != administrators.size() && administrators[i].get_user_id() != user_id) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i != administrators.size()) {
|
||||||
|
administrators.erase(administrators.begin() + i);
|
||||||
|
on_update_dialog_administrators(dialog_id, std::move(administrators), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11597,13 +11622,15 @@ void ContactsManager::send_get_channel_participants_query(ChannelId channel_id,
|
|||||||
->send(channel_id, std::move(filter), offset, limit, random_id);
|
->send(channel_id, std::move(filter), offset, limit, random_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<UserId> ContactsManager::get_dialog_administrators(DialogId dialog_id, int left_tries, Promise<Unit> &&promise) {
|
vector<DialogAdministrator> ContactsManager::get_dialog_administrators(DialogId dialog_id, int left_tries,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
auto it = dialog_administrators_.find(dialog_id);
|
auto it = dialog_administrators_.find(dialog_id);
|
||||||
if (it != dialog_administrators_.end()) {
|
if (it != dialog_administrators_.end()) {
|
||||||
promise.set_value(Unit());
|
promise.set_value(Unit());
|
||||||
if (left_tries >= 2) {
|
if (left_tries >= 2) {
|
||||||
auto hash =
|
auto hash = get_vector_hash(transform(it->second, [](const DialogAdministrator &administrator) {
|
||||||
get_vector_hash(transform(it->second, [](UserId user_id) { return static_cast<uint32>(user_id.get()); }));
|
return static_cast<uint32>(administrator.get_user_id().get());
|
||||||
|
}));
|
||||||
reload_dialog_administrators(dialog_id, hash, Auto()); // update administrators cache
|
reload_dialog_administrators(dialog_id, hash, Auto()); // update administrators cache
|
||||||
}
|
}
|
||||||
return it->second;
|
return it->second;
|
||||||
@ -11625,7 +11652,7 @@ vector<UserId> ContactsManager::get_dialog_administrators(DialogId dialog_id, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
string ContactsManager::get_dialog_administrators_database_key(DialogId dialog_id) {
|
string ContactsManager::get_dialog_administrators_database_key(DialogId dialog_id) {
|
||||||
return PSTRING() << "admin" << (-dialog_id.get());
|
return PSTRING() << "adm" << (-dialog_id.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::load_dialog_administrators(DialogId dialog_id, Promise<Unit> &&promise) {
|
void ContactsManager::load_dialog_administrators(DialogId dialog_id, Promise<Unit> &&promise) {
|
||||||
@ -11649,50 +11676,63 @@ void ContactsManager::on_load_dialog_administrators_from_database(DialogId dialo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<UserId> user_ids;
|
vector<DialogAdministrator> administrators;
|
||||||
log_event_parse(user_ids, value).ensure();
|
log_event_parse(administrators, value).ensure();
|
||||||
|
|
||||||
LOG(INFO) << "Successfully loaded " << user_ids.size() << " administrators in " << dialog_id << " from database";
|
LOG(INFO) << "Successfully loaded " << administrators.size() << " administrators in " << dialog_id
|
||||||
|
<< " from database";
|
||||||
|
|
||||||
MultiPromiseActorSafe load_users_multipromise{"LoadUsersMultiPromiseActor"};
|
MultiPromiseActorSafe load_users_multipromise{"LoadUsersMultiPromiseActor"};
|
||||||
load_users_multipromise.add_promise(
|
load_users_multipromise.add_promise(
|
||||||
PromiseCreator::lambda([dialog_id, user_ids, promise = std::move(promise)](Result<> result) mutable {
|
PromiseCreator::lambda([dialog_id, administrators, promise = std::move(promise)](Result<> result) mutable {
|
||||||
send_closure(G()->contacts_manager(), &ContactsManager::on_load_administrator_users_finished, dialog_id,
|
send_closure(G()->contacts_manager(), &ContactsManager::on_load_administrator_users_finished, dialog_id,
|
||||||
std::move(user_ids), std::move(result), std::move(promise));
|
std::move(administrators), std::move(result), std::move(promise));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
auto lock_promise = load_users_multipromise.get_promise();
|
auto lock_promise = load_users_multipromise.get_promise();
|
||||||
|
|
||||||
for (auto user_id : user_ids) {
|
for (auto &administrator : administrators) {
|
||||||
get_user(user_id, 3, load_users_multipromise.get_promise());
|
get_user(administrator.get_user_id(), 3, load_users_multipromise.get_promise());
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_promise.set_value(Unit());
|
lock_promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::on_load_administrator_users_finished(DialogId dialog_id, vector<UserId> user_ids, Result<> result,
|
void ContactsManager::on_load_administrator_users_finished(DialogId dialog_id,
|
||||||
|
vector<DialogAdministrator> administrators, Result<> result,
|
||||||
Promise<Unit> promise) {
|
Promise<Unit> promise) {
|
||||||
if (result.is_ok()) {
|
if (result.is_ok()) {
|
||||||
dialog_administrators_.emplace(dialog_id, std::move(user_ids));
|
dialog_administrators_.emplace(dialog_id, std::move(administrators));
|
||||||
}
|
}
|
||||||
promise.set_value(Unit());
|
promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::on_update_dialog_administrators(DialogId dialog_id, vector<UserId> administrator_user_ids,
|
void ContactsManager::on_update_channel_administrator_count(ChannelId channel_id, int32 administrator_count) {
|
||||||
|
auto channel_full = get_channel_full_force(channel_id);
|
||||||
|
if (channel_full != nullptr && channel_full->administrator_count != administrator_count) {
|
||||||
|
channel_full->administrator_count = administrator_count;
|
||||||
|
channel_full->is_changed = true;
|
||||||
|
update_channel_full(channel_full, channel_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactsManager::on_update_dialog_administrators(DialogId dialog_id, vector<DialogAdministrator> &&administrators,
|
||||||
bool have_access) {
|
bool have_access) {
|
||||||
LOG(INFO) << "Update administrators in " << dialog_id << " to " << format::as_array(administrator_user_ids);
|
LOG(INFO) << "Update administrators in " << dialog_id << " to " << format::as_array(administrators);
|
||||||
if (have_access) {
|
if (have_access) {
|
||||||
std::sort(administrator_user_ids.begin(), administrator_user_ids.end(),
|
std::sort(administrators.begin(), administrators.end(),
|
||||||
[](UserId lhs, UserId rhs) { return lhs.get() < rhs.get(); });
|
[](const DialogAdministrator &lhs, const DialogAdministrator &rhs) {
|
||||||
|
return lhs.get_user_id().get() < rhs.get_user_id().get();
|
||||||
|
});
|
||||||
|
|
||||||
auto it = dialog_administrators_.find(dialog_id);
|
auto it = dialog_administrators_.find(dialog_id);
|
||||||
if (it != dialog_administrators_.end()) {
|
if (it != dialog_administrators_.end()) {
|
||||||
if (it->second == administrator_user_ids) {
|
if (it->second == administrators) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
it->second = std::move(administrator_user_ids);
|
it->second = std::move(administrators);
|
||||||
} else {
|
} else {
|
||||||
it = dialog_administrators_.emplace(dialog_id, std::move(administrator_user_ids)).first;
|
it = dialog_administrators_.emplace(dialog_id, std::move(administrators)).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G()->parameters().use_chat_info_db) {
|
if (G()->parameters().use_chat_info_db) {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "td/telegram/ChannelId.h"
|
#include "td/telegram/ChannelId.h"
|
||||||
#include "td/telegram/ChatId.h"
|
#include "td/telegram/ChatId.h"
|
||||||
#include "td/telegram/Contact.h"
|
#include "td/telegram/Contact.h"
|
||||||
|
#include "td/telegram/DialogAdministrator.h"
|
||||||
#include "td/telegram/DialogId.h"
|
#include "td/telegram/DialogId.h"
|
||||||
#include "td/telegram/DialogLocation.h"
|
#include "td/telegram/DialogLocation.h"
|
||||||
#include "td/telegram/DialogParticipant.h"
|
#include "td/telegram/DialogParticipant.h"
|
||||||
@ -186,10 +187,12 @@ class ContactsManager : public Actor {
|
|||||||
void on_update_channel_location(ChannelId channel_id, const DialogLocation &location);
|
void on_update_channel_location(ChannelId channel_id, const DialogLocation &location);
|
||||||
void on_update_channel_is_all_history_available(ChannelId channel_id, bool is_all_history_available);
|
void on_update_channel_is_all_history_available(ChannelId channel_id, bool is_all_history_available);
|
||||||
void on_update_channel_default_permissions(ChannelId channel_id, RestrictedRights default_permissions);
|
void on_update_channel_default_permissions(ChannelId channel_id, RestrictedRights default_permissions);
|
||||||
|
void on_update_channel_administrator_count(ChannelId channel_id, int32 administrator_count);
|
||||||
|
|
||||||
void on_update_peer_located(vector<tl_object_ptr<telegram_api::peerLocated>> &&peers, bool from_update);
|
void on_update_peer_located(vector<tl_object_ptr<telegram_api::peerLocated>> &&peers, bool from_update);
|
||||||
|
|
||||||
void on_update_dialog_administrators(DialogId dialog_id, vector<UserId> administrator_user_ids, bool have_access);
|
void on_update_dialog_administrators(DialogId dialog_id, vector<DialogAdministrator> &&administrators,
|
||||||
|
bool have_access);
|
||||||
|
|
||||||
void speculative_add_channel_participants(ChannelId channel_id, const vector<UserId> &added_user_ids,
|
void speculative_add_channel_participants(ChannelId channel_id, const vector<UserId> &added_user_ids,
|
||||||
UserId inviter_user_id, int32 date, bool by_me);
|
UserId inviter_user_id, int32 date, bool by_me);
|
||||||
@ -455,7 +458,7 @@ class ContactsManager : public Actor {
|
|||||||
DialogParticipant get_dialog_participant(ChannelId channel_id,
|
DialogParticipant get_dialog_participant(ChannelId channel_id,
|
||||||
tl_object_ptr<telegram_api::ChannelParticipant> &&participant_ptr) const;
|
tl_object_ptr<telegram_api::ChannelParticipant> &&participant_ptr) const;
|
||||||
|
|
||||||
vector<UserId> get_dialog_administrators(DialogId chat_id, int left_tries, Promise<Unit> &&promise);
|
vector<DialogAdministrator> get_dialog_administrators(DialogId chat_id, int left_tries, Promise<Unit> &&promise);
|
||||||
|
|
||||||
int32 get_user_id_object(UserId user_id, const char *source) const;
|
int32 get_user_id_object(UserId user_id, const char *source) const;
|
||||||
|
|
||||||
@ -1209,8 +1212,8 @@ class ContactsManager : public Actor {
|
|||||||
|
|
||||||
void on_load_dialog_administrators_from_database(DialogId dialog_id, string value, Promise<Unit> &&promise);
|
void on_load_dialog_administrators_from_database(DialogId dialog_id, string value, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void on_load_administrator_users_finished(DialogId dialog_id, vector<UserId> user_ids, Result<> result,
|
void on_load_administrator_users_finished(DialogId dialog_id, vector<DialogAdministrator> administrators,
|
||||||
Promise<Unit> promise);
|
Result<> result, Promise<Unit> promise);
|
||||||
|
|
||||||
void reload_dialog_administrators(DialogId dialog_id, int32 hash, Promise<Unit> &&promise);
|
void reload_dialog_administrators(DialogId dialog_id, int32 hash, Promise<Unit> &&promise);
|
||||||
|
|
||||||
@ -1335,7 +1338,7 @@ class ContactsManager : public Actor {
|
|||||||
QueryCombiner get_chat_full_queries_{"GetChatFullCombiner", 2.0};
|
QueryCombiner get_chat_full_queries_{"GetChatFullCombiner", 2.0};
|
||||||
QueryCombiner get_channel_full_queries_{"GetChannelFullCombiner", 2.0};
|
QueryCombiner get_channel_full_queries_{"GetChannelFullCombiner", 2.0};
|
||||||
|
|
||||||
std::unordered_map<DialogId, vector<UserId>, DialogIdHash> dialog_administrators_;
|
std::unordered_map<DialogId, vector<DialogAdministrator>, DialogIdHash> dialog_administrators_;
|
||||||
|
|
||||||
class UploadProfilePhotoCallback;
|
class UploadProfilePhotoCallback;
|
||||||
std::shared_ptr<UploadProfilePhotoCallback> upload_profile_photo_callback_;
|
std::shared_ptr<UploadProfilePhotoCallback> upload_profile_photo_callback_;
|
||||||
|
26
td/telegram/DialogAdministrator.cpp
Normal file
26
td/telegram/DialogAdministrator.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019
|
||||||
|
//
|
||||||
|
// 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/DialogAdministrator.h"
|
||||||
|
|
||||||
|
#include "td/telegram/ContactsManager.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::chatAdministrator> DialogAdministrator::get_chat_administrator_object(
|
||||||
|
const ContactsManager *contacts_manager) const {
|
||||||
|
CHECK(contacts_manager != nullptr);
|
||||||
|
CHECK(user_id_.is_valid());
|
||||||
|
return td_api::make_object<td_api::chatAdministrator>(
|
||||||
|
contacts_manager->get_user_id_object(user_id_, "get_chat_administrator_object"), rank_);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const DialogAdministrator &administrator) {
|
||||||
|
return string_builder << "DialogAdministrator[" << administrator.user_id_ << ", title = " << administrator.rank_
|
||||||
|
<< "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
80
td/telegram/DialogAdministrator.h
Normal file
80
td/telegram/DialogAdministrator.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019
|
||||||
|
//
|
||||||
|
// 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/td_api.h"
|
||||||
|
#include "td/telegram/UserId.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/StringBuilder.h"
|
||||||
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class ContactsManager;
|
||||||
|
|
||||||
|
class DialogAdministrator {
|
||||||
|
UserId user_id_;
|
||||||
|
string rank_;
|
||||||
|
|
||||||
|
friend StringBuilder &operator<<(StringBuilder &string_builder, const DialogAdministrator &location);
|
||||||
|
|
||||||
|
public:
|
||||||
|
DialogAdministrator() = default;
|
||||||
|
|
||||||
|
DialogAdministrator(UserId user_id, const string &rank) : user_id_(user_id), rank_(rank) {
|
||||||
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::chatAdministrator> get_chat_administrator_object(
|
||||||
|
const ContactsManager *contacts_manager) const;
|
||||||
|
|
||||||
|
UserId get_user_id() const {
|
||||||
|
return user_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const string &get_rank() const {
|
||||||
|
return rank_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class StorerT>
|
||||||
|
void store(StorerT &storer) const {
|
||||||
|
using td::store;
|
||||||
|
bool has_rank = !rank_.empty();
|
||||||
|
BEGIN_STORE_FLAGS();
|
||||||
|
STORE_FLAG(has_rank);
|
||||||
|
END_STORE_FLAGS();
|
||||||
|
store(user_id_, storer);
|
||||||
|
if (has_rank) {
|
||||||
|
store(rank_, storer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void parse(ParserT &parser) {
|
||||||
|
using td::parse;
|
||||||
|
bool has_rank;
|
||||||
|
BEGIN_PARSE_FLAGS();
|
||||||
|
PARSE_FLAG(has_rank);
|
||||||
|
END_PARSE_FLAGS();
|
||||||
|
parse(user_id_, parser);
|
||||||
|
if (has_rank) {
|
||||||
|
parse(rank_, parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const DialogAdministrator &lhs, const DialogAdministrator &rhs) {
|
||||||
|
return lhs.get_user_id() == rhs.get_user_id() && lhs.get_rank() == rhs.get_rank();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const DialogAdministrator &lhs, const DialogAdministrator &rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const DialogAdministrator &administrator);
|
||||||
|
|
||||||
|
} // namespace td
|
@ -23571,7 +23571,8 @@ std::pair<int32, vector<DialogParticipant>> MessagesManager::search_dialog_parti
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<UserId> MessagesManager::get_dialog_administrators(DialogId dialog_id, int left_tries, Promise<Unit> &&promise) {
|
vector<DialogAdministrator> MessagesManager::get_dialog_administrators(DialogId dialog_id, int left_tries,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
LOG(INFO) << "Receive GetChatAdministrators request in " << dialog_id;
|
LOG(INFO) << "Receive GetChatAdministrators request in " << dialog_id;
|
||||||
if (!have_dialog_force(dialog_id)) {
|
if (!have_dialog_force(dialog_id)) {
|
||||||
promise.set_error(Status::Error(3, "Chat not found"));
|
promise.set_error(Status::Error(3, "Chat not found"));
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "td/telegram/AccessRights.h"
|
#include "td/telegram/AccessRights.h"
|
||||||
#include "td/telegram/ChannelId.h"
|
#include "td/telegram/ChannelId.h"
|
||||||
#include "td/telegram/Dependencies.h"
|
#include "td/telegram/Dependencies.h"
|
||||||
|
#include "td/telegram/DialogAdministrator.h"
|
||||||
#include "td/telegram/DialogDate.h"
|
#include "td/telegram/DialogDate.h"
|
||||||
#include "td/telegram/DialogDb.h"
|
#include "td/telegram/DialogDb.h"
|
||||||
#include "td/telegram/DialogId.h"
|
#include "td/telegram/DialogId.h"
|
||||||
@ -448,7 +449,7 @@ class MessagesManager : public Actor {
|
|||||||
int64 &random_id, bool force,
|
int64 &random_id, bool force,
|
||||||
Promise<Unit> &&promise);
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
vector<UserId> get_dialog_administrators(DialogId dialog_id, int left_tries, Promise<Unit> &&promise);
|
vector<DialogAdministrator> get_dialog_administrators(DialogId dialog_id, int left_tries, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void export_dialog_invite_link(DialogId dialog_id, Promise<Unit> &&promise);
|
void export_dialog_invite_link(DialogId dialog_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
@ -1931,14 +1931,18 @@ class SearchChatMembersRequest : public RequestActor<> {
|
|||||||
class GetChatAdministratorsRequest : public RequestActor<> {
|
class GetChatAdministratorsRequest : public RequestActor<> {
|
||||||
DialogId dialog_id_;
|
DialogId dialog_id_;
|
||||||
|
|
||||||
vector<UserId> user_ids_;
|
vector<DialogAdministrator> administrators_;
|
||||||
|
|
||||||
void do_run(Promise<Unit> &&promise) override {
|
void do_run(Promise<Unit> &&promise) override {
|
||||||
user_ids_ = td->messages_manager_->get_dialog_administrators(dialog_id_, get_tries(), std::move(promise));
|
administrators_ = td->messages_manager_->get_dialog_administrators(dialog_id_, get_tries(), std::move(promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_send_result() override {
|
void do_send_result() override {
|
||||||
send_result(td->contacts_manager_->get_users_object(-1, user_ids_));
|
auto administrator_objects = transform(
|
||||||
|
administrators_, [contacts_manager = td->contacts_manager_.get()](const DialogAdministrator &administrator) {
|
||||||
|
return administrator.get_chat_administrator_object(contacts_manager);
|
||||||
|
});
|
||||||
|
send_result(td_api::make_object<td_api::chatAdministrators>(std::move(administrator_objects)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -3407,6 +3407,9 @@ class CliClient final : public Actor {
|
|||||||
} else if (status_str == "admin") {
|
} else if (status_str == "admin") {
|
||||||
status = td_api::make_object<td_api::chatMemberStatusAdministrator>("", true, true, true, true, true, true,
|
status = td_api::make_object<td_api::chatMemberStatusAdministrator>("", true, true, true, true, true, true,
|
||||||
true, true, true);
|
true, true, true);
|
||||||
|
} else if (status_str == "adminq") {
|
||||||
|
status = td_api::make_object<td_api::chatMemberStatusAdministrator>("title", true, true, true, true, true, true,
|
||||||
|
true, true, true);
|
||||||
} else if (status_str == "minadmin") {
|
} else if (status_str == "minadmin") {
|
||||||
status = td_api::make_object<td_api::chatMemberStatusAdministrator>("", true, true, false, false, false, false,
|
status = td_api::make_object<td_api::chatMemberStatusAdministrator>("", true, true, false, false, false, false,
|
||||||
false, false, false);
|
false, false, false);
|
||||||
|
Reference in New Issue
Block a user