Use ParticipantsBoxController for members list.

Add search in channel/supergroup members inside PeerListBox.
Also MembersBox is not used anymore.
This commit is contained in:
John Preston 2017-07-10 19:13:40 +03:00
parent b79ddb7a1c
commit 06d4ea2975
8 changed files with 187 additions and 44 deletions

View file

@ -557,6 +557,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_profile_invite_link_section" = "Invite link"; "lng_profile_invite_link_section" = "Invite link";
"lng_profile_create_public_link" = "Create public link"; "lng_profile_create_public_link" = "Create public link";
"lng_profile_edit_public_link" = "Edit public link"; "lng_profile_edit_public_link" = "Edit public link";
"lng_profile_search_members" = "Search members";
"lng_profile_manage_admins" = "Manage administrators"; "lng_profile_manage_admins" = "Manage administrators";
"lng_profile_manage_blocklist" = "Manage banned users"; "lng_profile_manage_blocklist" = "Manage banned users";
"lng_profile_manage_restrictedlist" = "Manage restricted users"; "lng_profile_manage_restrictedlist" = "Manage restricted users";

View file

@ -58,9 +58,10 @@ void BoxContent::setInner(object_ptr<TWidget> inner, const style::ScrollArea &st
_topShadow.create(this, object_ptr<BoxLayerTitleShadow>(this)); _topShadow.create(this, object_ptr<BoxLayerTitleShadow>(this));
_bottomShadow.create(this, object_ptr<BoxLayerTitleShadow>(this)); _bottomShadow.create(this, object_ptr<BoxLayerTitleShadow>(this));
} }
updateScrollAreaGeometry(); if (!_preparing) {
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); // We didn't set dimensions yet, this will be called from finishPrepare();
connect(_scroll, SIGNAL(innerResized()), this, SLOT(onInnerResize())); finishScrollCreate();
}
} else { } else {
getDelegate()->setLayerType(false); getDelegate()->setLayerType(false);
_scroll.destroyDelayed(); _scroll.destroyDelayed();
@ -69,6 +70,21 @@ void BoxContent::setInner(object_ptr<TWidget> inner, const style::ScrollArea &st
} }
} }
void BoxContent::finishPrepare() {
_preparing = false;
if (_scroll) {
finishScrollCreate();
}
setInnerFocus();
}
void BoxContent::finishScrollCreate() {
Expects(_scroll != nullptr);
updateScrollAreaGeometry();
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
connect(_scroll, SIGNAL(innerResized()), this, SLOT(onInnerResize()));
}
void BoxContent::onScrollToY(int top, int bottom) { void BoxContent::onScrollToY(int top, int bottom) {
if (_scroll) { if (_scroll) {
_scroll->scrollToY(top, bottom); _scroll->scrollToY(top, bottom);

View file

@ -111,8 +111,9 @@ public:
void setDelegate(BoxContentDelegate *newDelegate) { void setDelegate(BoxContentDelegate *newDelegate) {
_delegate = newDelegate; _delegate = newDelegate;
_preparing = true;
prepare(); prepare();
setInnerFocus(); finishPrepare();
} }
public slots: public slots:
@ -177,6 +178,8 @@ private slots:
void onDraggingScrollTimer(); void onDraggingScrollTimer();
private: private:
void finishPrepare();
void finishScrollCreate();
void setInner(object_ptr<TWidget> inner); void setInner(object_ptr<TWidget> inner);
void setInner(object_ptr<TWidget> inner, const style::ScrollArea &st); void setInner(object_ptr<TWidget> inner, const style::ScrollArea &st);
void updateScrollAreaGeometry(); void updateScrollAreaGeometry();
@ -190,6 +193,7 @@ private:
} }
BoxContentDelegate *_delegate = nullptr; BoxContentDelegate *_delegate = nullptr;
bool _preparing = false;
bool _noContentMargin = false; bool _noContentMargin = false;
int _innerTopSkip = 0; int _innerTopSkip = 0;
object_ptr<Ui::ScrollArea> _scroll = { nullptr }; object_ptr<Ui::ScrollArea> _scroll = { nullptr };

View file

@ -144,7 +144,7 @@ int ChannelMembersWidget::resizeGetHeight(int newWidth) {
void ChannelMembersWidget::onMembers() { void ChannelMembersWidget::onMembers() {
if (auto channel = peer()->asChannel()) { if (auto channel = peer()->asChannel()) {
Ui::show(Box<MembersBox>(channel, MembersFilter::Recent)); ParticipantsBoxController::Start(channel, ParticipantsBoxController::Role::Members);
} }
} }

View file

@ -96,6 +96,7 @@ int SettingsWidget::resizeGetHeight(int newWidth) {
button->moveToLeft(left, newHeight); button->moveToLeft(left, newHeight);
newHeight += button->height(); newHeight += button->height();
}; };
moveLink(_searchMembers);
moveLink(_manageAdmins); moveLink(_manageAdmins);
moveLink(_recentActions); moveLink(_recentActions);
moveLink(_manageBannedUsers); moveLink(_manageBannedUsers);
@ -109,6 +110,11 @@ int SettingsWidget::resizeGetHeight(int newWidth) {
void SettingsWidget::refreshButtons() { void SettingsWidget::refreshButtons() {
refreshEnableNotifications(); refreshEnableNotifications();
refreshManageAdminsButton(); refreshManageAdminsButton();
if (auto megagroup = peer()->asMegagroup()) {
_searchMembers.create(this, lang(lng_profile_search_members), st::defaultLeftOutlineButton);
_searchMembers->show();
connect(_searchMembers, SIGNAL(clicked()), this, SLOT(onSearchMembers()));
}
refreshManageBannedUsersButton(); refreshManageBannedUsersButton();
refreshInviteLinkButton(); refreshInviteLinkButton();
} }
@ -208,6 +214,12 @@ void SettingsWidget::onNotificationsChange() {
App::main()->updateNotifySetting(peer(), _enableNotifications->checked() ? NotifySettingSetNotify : NotifySettingSetMuted); App::main()->updateNotifySetting(peer(), _enableNotifications->checked() ? NotifySettingSetNotify : NotifySettingSetMuted);
} }
void SettingsWidget::onSearchMembers() {
if (auto channel = peer()->asChannel()) {
ParticipantsBoxController::Start(channel, ParticipantsBoxController::Role::Members);
}
}
void SettingsWidget::onManageAdmins() { void SettingsWidget::onManageAdmins() {
if (auto chat = peer()->asChat()) { if (auto chat = peer()->asChat()) {
Ui::show(Box<ContactsBox>(chat, MembersFilter::Admins)); Ui::show(Box<ContactsBox>(chat, MembersFilter::Admins));

View file

@ -45,6 +45,7 @@ protected:
private slots: private slots:
void onNotificationsChange(); void onNotificationsChange();
void onSearchMembers();
void onManageAdmins(); void onManageAdmins();
void onRecentActions(); void onRecentActions();
void onManageBannedUsers(); void onManageBannedUsers();
@ -62,9 +63,7 @@ private:
void refreshInviteLinkButton(); void refreshInviteLinkButton();
object_ptr<Ui::Checkbox> _enableNotifications; object_ptr<Ui::Checkbox> _enableNotifications;
object_ptr<Ui::LeftOutlineButton> _searchMembers = { nullptr };
// In groups: creator of non-deactivated groups can see this link.
// In channels: creator of supergroup can see this link.
object_ptr<Ui::LeftOutlineButton> _manageAdmins = { nullptr }; object_ptr<Ui::LeftOutlineButton> _manageAdmins = { nullptr };
object_ptr<Ui::LeftOutlineButton> _recentActions = { nullptr }; object_ptr<Ui::LeftOutlineButton> _recentActions = { nullptr };
object_ptr<Ui::LeftOutlineButton> _manageBannedUsers = { nullptr }; object_ptr<Ui::LeftOutlineButton> _manageBannedUsers = { nullptr };

View file

@ -37,7 +37,7 @@ constexpr auto kParticipantsPerPage = 200;
} // namespace } // namespace
ParticipantsBoxController::ParticipantsBoxController(gsl::not_null<ChannelData*> channel, Role role) : PeerListController((role == Role::Admins) ? nullptr : std::make_unique<BannedBoxSearchController>(channel, role, &_additional)) ParticipantsBoxController::ParticipantsBoxController(gsl::not_null<ChannelData*> channel, Role role) : PeerListController((role == Role::Admins) ? nullptr : std::make_unique<ParticipantsBoxSearchController>(channel, role, &_additional))
, _channel(channel) , _channel(channel)
, _role(role) { , _role(role) {
if (_channel->mgInfo) { if (_channel->mgInfo) {
@ -51,6 +51,7 @@ void ParticipantsBoxController::Start(gsl::not_null<ChannelData*> channel, Role
box->addButton(langFactory(lng_close), [box] { box->closeBox(); }); box->addButton(langFactory(lng_close), [box] { box->closeBox(); });
auto canAddNewItem = [role, channel] { auto canAddNewItem = [role, channel] {
switch (role) { switch (role) {
case Role::Members: return false;
case Role::Admins: return channel->canAddAdmins(); case Role::Admins: return channel->canAddAdmins();
case Role::Restricted: case Role::Restricted:
case Role::Kicked: return channel->canBanMembers(); case Role::Kicked: return channel->canBanMembers();
@ -104,7 +105,7 @@ std::unique_ptr<PeerListRow> ParticipantsBoxController::createSearchRow(gsl::not
template <typename Callback> template <typename Callback>
void ParticipantsBoxController::HandleParticipant(const MTPChannelParticipant &participant, Role role, gsl::not_null<Additional*> additional, Callback callback) { void ParticipantsBoxController::HandleParticipant(const MTPChannelParticipant &participant, Role role, gsl::not_null<Additional*> additional, Callback callback) {
if (role == Role::Admins && participant.type() == mtpc_channelParticipantAdmin) { if ((role == Role::Members || role == Role::Admins) && participant.type() == mtpc_channelParticipantAdmin) {
auto &admin = participant.c_channelParticipantAdmin(); auto &admin = participant.c_channelParticipantAdmin();
if (auto user = App::userLoaded(admin.vuser_id.v)) { if (auto user = App::userLoaded(admin.vuser_id.v)) {
additional->adminRights[user] = admin.vadmin_rights; additional->adminRights[user] = admin.vadmin_rights;
@ -125,18 +126,28 @@ void ParticipantsBoxController::HandleParticipant(const MTPChannelParticipant &p
} }
callback(user); callback(user);
} }
} else if (role == Role::Admins && participant.type() == mtpc_channelParticipantCreator) { } else if ((role == Role::Members || role == Role::Admins) && participant.type() == mtpc_channelParticipantCreator) {
auto &creator = participant.c_channelParticipantCreator(); auto &creator = participant.c_channelParticipantCreator();
if (auto user = App::userLoaded(creator.vuser_id.v)) { if (auto user = App::userLoaded(creator.vuser_id.v)) {
additional->creator = user; additional->creator = user;
callback(user); callback(user);
} }
} else if ((role == Role::Restricted || role == Role::Kicked) && participant.type() == mtpc_channelParticipantBanned) { } else if ((role == Role::Members || role == Role::Restricted || role == Role::Kicked) && participant.type() == mtpc_channelParticipantBanned) {
auto &banned = participant.c_channelParticipantBanned(); auto &banned = participant.c_channelParticipantBanned();
if (auto user = App::userLoaded(banned.vuser_id.v)) { if (auto user = App::userLoaded(banned.vuser_id.v)) {
additional->restrictedRights[user] = banned.vbanned_rights; additional->restrictedRights[user] = banned.vbanned_rights;
callback(user); callback(user);
} }
} else if (role == Role::Members && participant.type() == mtpc_channelParticipant) {
auto &member = participant.c_channelParticipant();
if (auto user = App::userLoaded(member.vuser_id.v)) {
callback(user);
}
} else if (role == Role::Members && participant.type() == mtpc_channelParticipantSelf) {
auto &member = participant.c_channelParticipantSelf();
if (auto user = App::userLoaded(member.vuser_id.v)) {
callback(user);
}
} else { } else {
LOG(("API Error: Bad participant type got while requesting for participants: %1").arg(participant.type())); LOG(("API Error: Bad participant type got while requesting for participants: %1").arg(participant.type()));
} }
@ -148,13 +159,19 @@ void ParticipantsBoxController::prepare() {
delegate()->peerListSetTitle(langFactory(lng_channel_admins)); delegate()->peerListSetTitle(langFactory(lng_channel_admins));
} else { } else {
delegate()->peerListSetSearchMode(PeerListSearchMode::Complex); delegate()->peerListSetSearchMode(PeerListSearchMode::Complex);
delegate()->peerListSetTitle(langFactory((_role == Role::Restricted) ? lng_restricted_list_title : lng_banned_list_title)); if (_role == Role::Members) {
delegate()->peerListSetTitle(langFactory(lng_profile_participants_section));
} else if (_role == Role::Restricted) {
delegate()->peerListSetTitle(langFactory(lng_restricted_list_title));
} else {
delegate()->peerListSetTitle(langFactory(lng_banned_list_title));
}
} }
setDescriptionText(lang(lng_contacts_loading)); setDescriptionText(lang(lng_contacts_loading));
setSearchNoResultsText(lang(lng_blocked_list_not_found)); setSearchNoResultsText(lang(lng_blocked_list_not_found));
delegate()->peerListRefreshRows();
loadMoreRows(); loadMoreRows();
delegate()->peerListRefreshRows();
} }
void ParticipantsBoxController::loadMoreRows() { void ParticipantsBoxController::loadMoreRows() {
@ -165,8 +182,14 @@ void ParticipantsBoxController::loadMoreRows() {
return; return;
} }
if (feedMegagroupLastParticipants()) {
return;
}
auto filter = [this] { auto filter = [this] {
if (_role == Role::Admins) { if (_role == Role::Members) {
return MTP_channelParticipantsRecent();
} else if (_role == Role::Admins) {
return MTP_channelParticipantsAdmins(); return MTP_channelParticipantsAdmins();
} else if (_role == Role::Restricted) { } else if (_role == Role::Restricted) {
return MTP_channelParticipantsBanned(MTP_string(QString())); return MTP_channelParticipantsBanned(MTP_string(QString()));
@ -185,26 +208,71 @@ void ParticipantsBoxController::loadMoreRows() {
setDescriptionText((_role == Role::Restricted) ? lang(lng_group_blocked_list_about) : QString()); setDescriptionText((_role == Role::Restricted) ? lang(lng_group_blocked_list_about) : QString());
} }
auto &participants = result.c_channels_channelParticipants(); auto &participants = result.c_channels_channelParticipants();
App::feedUsers(participants.vusers); App::feedUsers(participants.vusers);
auto &list = participants.vparticipants.v; auto &list = participants.vparticipants.v;
if (list.isEmpty()) { if (list.isEmpty()) {
// To be sure - wait for a whole empty result list. // To be sure - wait for a whole empty result list.
_allLoaded = true; _allLoaded = true;
} else { } else {
for_const (auto &participant, list) { for_const (auto &participant, list) {
++_offset; ++_offset;
HandleParticipant(participant, _role, &_additional, [this](gsl::not_null<UserData*> user) { HandleParticipant(participant, _role, &_additional, [this](gsl::not_null<UserData*> user) {
appendRow(user); appendRow(user);
}); });
} }
} }
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
}).fail([this](const RPCError &error) { }).fail([this](const RPCError &error) {
_loadRequestId = 0; _loadRequestId = 0;
}).send(); }).send();
} }
bool ParticipantsBoxController::feedMegagroupLastParticipants() {
if (_role != Role::Members || _offset > 0) {
return false;
}
auto megagroup = _channel->asMegagroup();
if (!megagroup) {
return false;
}
auto info = megagroup->mgInfo.get();
if (info->lastParticipantsStatus != MegagroupInfo::LastParticipantsUpToDate) {
return false;
}
if (info->lastParticipants.isEmpty()) {
return false;
}
if (info->creator) {
_additional.creator = info->creator;
}
for_const (auto user, info->lastParticipants) {
auto admin = info->lastAdmins.constFind(user);
if (admin != info->lastAdmins.cend()) {
_additional.restrictedRights.erase(user);
if (admin->canEdit) {
_additional.adminCanEdit.emplace(user);
} else {
_additional.adminCanEdit.erase(user);
}
_additional.adminRights.emplace(user, admin->rights);
} else {
_additional.adminCanEdit.erase(user);
_additional.adminRights.erase(user);
auto restricted = info->lastRestricted.constFind(user);
if (restricted != info->lastRestricted.cend()) {
_additional.restrictedRights.emplace(user, restricted->rights);
} else {
_additional.restrictedRights.erase(user);
}
}
appendRow(user);
++_offset;
}
return true;
}
void ParticipantsBoxController::rowClicked(gsl::not_null<PeerListRow*> row) { void ParticipantsBoxController::rowClicked(gsl::not_null<PeerListRow*> row) {
auto user = row->peer()->asUser(); auto user = row->peer()->asUser();
Expects(user != nullptr); Expects(user != nullptr);
@ -222,7 +290,9 @@ void ParticipantsBoxController::rowActionClicked(gsl::not_null<PeerListRow*> row
auto user = row->peer()->asUser(); auto user = row->peer()->asUser();
Expects(user != nullptr); Expects(user != nullptr);
if (_role == Role::Admins) { if (_role == Role::Members) {
kickMember(user);
} else if (_role == Role::Admins) {
showAdmin(user); showAdmin(user);
} else if (_role == Role::Restricted) { } else if (_role == Role::Restricted) {
showRestricted(user); showRestricted(user);
@ -350,6 +420,30 @@ void ParticipantsBoxController::editRestrictedDone(gsl::not_null<UserData*> user
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
} }
void ParticipantsBoxController::kickMember(gsl::not_null<UserData*> user) {
auto text = (_channel->isMegagroup() ? lng_profile_sure_kick : lng_profile_sure_kick_channel)(lt_user, user->firstName);
auto weak = base::weak_unique_ptr<ParticipantsBoxController>(this);
_editBox = Ui::show(Box<ConfirmBox>(text, lang(lng_box_remove), [weak, user] {
if (weak) {
weak->kickMemberSure(user);
}
}), KeepOtherLayers);
}
void ParticipantsBoxController::kickMemberSure(gsl::not_null<UserData*> user) {
if (_editBox) {
_editBox->closeBox();
}
auto alreadyIt = _additional.restrictedRights.find(user);
auto currentRights = (alreadyIt == _additional.restrictedRights.cend()) ? MTP_channelBannedRights(MTP_flags(0), MTP_int(0)) : alreadyIt->second;
if (auto row = delegate()->peerListFindRow(user->id)) {
delegate()->peerListRemoveRow(row);
delegate()->peerListRefreshRows();
}
AuthSession::Current().api().kickParticipant(_channel, user, currentRights);
}
void ParticipantsBoxController::removeKicked(gsl::not_null<PeerListRow*> row, gsl::not_null<UserData*> user) { void ParticipantsBoxController::removeKicked(gsl::not_null<PeerListRow*> row, gsl::not_null<UserData*> user) {
delegate()->peerListRemoveRow(row); delegate()->peerListRemoveRow(row);
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
@ -394,21 +488,27 @@ std::unique_ptr<PeerListRow> ParticipantsBoxController::createRow(gsl::not_null<
auto row = std::make_unique<PeerListRowWithLink>(user); auto row = std::make_unique<PeerListRowWithLink>(user);
if (_role == Role::Admins) { if (_role == Role::Admins) {
auto promotedBy = _additional.adminPromotedBy.find(user); auto promotedBy = _additional.adminPromotedBy.find(user);
if (promotedBy == _additional.adminPromotedBy.end()) { if (promotedBy == _additional.adminPromotedBy.cend()) {
row->setCustomStatus(lang(lng_channel_admin_status_creator)); row->setCustomStatus(lang(lng_channel_admin_status_creator));
} else { } else {
row->setCustomStatus(lng_channel_admin_status_promoted_by(lt_user, App::peerName(promotedBy->second))); row->setCustomStatus(lng_channel_admin_status_promoted_by(lt_user, App::peerName(promotedBy->second)));
} }
} }
if (_role == Role::Restricted || (_role == Role::Admins && _additional.adminCanEdit.find(user) != _additional.adminCanEdit.end())) { if (_role == Role::Restricted || (_role == Role::Admins && _additional.adminCanEdit.find(user) != _additional.adminCanEdit.cend())) {
// row->setActionLink(lang(lng_profile_edit_permissions)); // row->setActionLink(lang(lng_profile_edit_permissions));
} else if (_role == Role::Kicked) { } else if (_role == Role::Kicked) {
row->setActionLink(lang(lng_blocked_list_unblock)); row->setActionLink(lang(lng_blocked_list_unblock));
} else if (_role == Role::Members) {
if (_channel->canBanMembers() && _additional.creator != user
&& (_additional.adminRights.find(user) == _additional.adminRights.cend()
|| _additional.adminCanEdit.find(user) != _additional.adminCanEdit.cend())) {
row->setActionLink(lang(lng_profile_kick));
}
} }
return std::move(row); return std::move(row);
} }
BannedBoxSearchController::BannedBoxSearchController(gsl::not_null<ChannelData*> channel, Role role, gsl::not_null<Additional*> additional) ParticipantsBoxSearchController::ParticipantsBoxSearchController(gsl::not_null<ChannelData*> channel, Role role, gsl::not_null<Additional*> additional)
: _channel(channel) : _channel(channel)
, _role(role) , _role(role)
, _additional(additional) { , _additional(additional) {
@ -416,7 +516,7 @@ BannedBoxSearchController::BannedBoxSearchController(gsl::not_null<ChannelData*>
_timer.setCallback([this] { searchOnServer(); }); _timer.setCallback([this] { searchOnServer(); });
} }
void BannedBoxSearchController::searchQuery(const QString &query) { void ParticipantsBoxSearchController::searchQuery(const QString &query) {
if (_query != query) { if (_query != query) {
_query = query; _query = query;
_offset = 0; _offset = 0;
@ -430,16 +530,16 @@ void BannedBoxSearchController::searchQuery(const QString &query) {
} }
} }
void BannedBoxSearchController::searchOnServer() { void ParticipantsBoxSearchController::searchOnServer() {
Expects(!_query.isEmpty()); Expects(!_query.isEmpty());
loadMoreRows(); loadMoreRows();
} }
bool BannedBoxSearchController::isLoading() { bool ParticipantsBoxSearchController::isLoading() {
return _timer.isActive() || _requestId; return _timer.isActive() || _requestId;
} }
bool BannedBoxSearchController::searchInCache() { bool ParticipantsBoxSearchController::searchInCache() {
auto it = _cache.find(_query); auto it = _cache.find(_query);
if (it != _cache.cend()) { if (it != _cache.cend()) {
_requestId = 0; _requestId = 0;
@ -449,18 +549,25 @@ bool BannedBoxSearchController::searchInCache() {
return false; return false;
} }
bool BannedBoxSearchController::loadMoreRows() { bool ParticipantsBoxSearchController::loadMoreRows() {
if (_query.isEmpty()) { if (_query.isEmpty()) {
return false; return false;
} }
if (!_allLoaded && !isLoading()) { if (!_allLoaded && !isLoading()) {
auto filter = (_role == Role::Restricted) ? MTP_channelParticipantsBanned(MTP_string(_query)) : MTP_channelParticipantsKicked(MTP_string(_query)); auto filter = [this] {
switch (_role) {
case Role::Members: return MTP_channelParticipantsSearch(MTP_string(_query));
case Role::Restricted: return MTP_channelParticipantsBanned(MTP_string(_query));
case Role::Kicked: return MTP_channelParticipantsKicked(MTP_string(_query));
}
Unexpected("Role in ParticipantsBoxSearchController::loadMoreRows()");
};
// For search we request a lot of rows from the first query. // For search we request a lot of rows from the first query.
// (because we've waited for search request by timer already, // (because we've waited for search request by timer already,
// so we don't expect it to be fast, but we want to fill cache). // so we don't expect it to be fast, but we want to fill cache).
auto perPage = kParticipantsPerPage; auto perPage = kParticipantsPerPage;
_requestId = request(MTPchannels_GetParticipants(_channel->inputChannel, filter, MTP_int(_offset), MTP_int(perPage))).done([this, perPage](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { _requestId = request(MTPchannels_GetParticipants(_channel->inputChannel, filter(), MTP_int(_offset), MTP_int(perPage))).done([this, perPage](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) {
searchDone(requestId, result, perPage); searchDone(requestId, result, perPage);
}).fail([this](const RPCError &error, mtpRequestId requestId) { }).fail([this](const RPCError &error, mtpRequestId requestId) {
if (_requestId == requestId) { if (_requestId == requestId) {
@ -478,7 +585,7 @@ bool BannedBoxSearchController::loadMoreRows() {
return true; return true;
} }
void BannedBoxSearchController::searchDone(mtpRequestId requestId, const MTPchannels_ChannelParticipants &result, int requestedCount) { void ParticipantsBoxSearchController::searchDone(mtpRequestId requestId, const MTPchannels_ChannelParticipants &result, int requestedCount) {
Expects(result.type() == mtpc_channels_channelParticipants); Expects(result.type() == mtpc_channels_channelParticipants);
auto &participants = result.c_channels_channelParticipants(); auto &participants = result.c_channels_channelParticipants();

View file

@ -30,6 +30,7 @@ namespace Profile {
class ParticipantsBoxController : public PeerListController, private base::Subscriber, private MTP::Sender, public base::enable_weak_from_this { class ParticipantsBoxController : public PeerListController, private base::Subscriber, private MTP::Sender, public base::enable_weak_from_this {
public: public:
enum class Role { enum class Role {
Members,
Admins, Admins,
Restricted, Restricted,
Kicked, Kicked,
@ -69,10 +70,13 @@ private:
void showRestricted(gsl::not_null<UserData*> user); void showRestricted(gsl::not_null<UserData*> user);
void editRestrictedDone(gsl::not_null<UserData*> user, const MTPChannelBannedRights &rights); void editRestrictedDone(gsl::not_null<UserData*> user, const MTPChannelBannedRights &rights);
void removeKicked(gsl::not_null<PeerListRow*> row, gsl::not_null<UserData*> user); void removeKicked(gsl::not_null<PeerListRow*> row, gsl::not_null<UserData*> user);
void kickMember(gsl::not_null<UserData*> user);
void kickMemberSure(gsl::not_null<UserData*> user);
bool appendRow(gsl::not_null<UserData*> user); bool appendRow(gsl::not_null<UserData*> user);
bool prependRow(gsl::not_null<UserData*> user); bool prependRow(gsl::not_null<UserData*> user);
bool removeRow(gsl::not_null<UserData*> user); bool removeRow(gsl::not_null<UserData*> user);
std::unique_ptr<PeerListRow> createRow(gsl::not_null<UserData*> user) const; std::unique_ptr<PeerListRow> createRow(gsl::not_null<UserData*> user) const;
bool feedMegagroupLastParticipants();
gsl::not_null<ChannelData*> _channel; gsl::not_null<ChannelData*> _channel;
Role _role = Role::Admins; Role _role = Role::Admins;
@ -85,13 +89,13 @@ private:
}; };
// Banned and restricted users server side search. // Members, banned and restricted users server side search.
class BannedBoxSearchController : public PeerListSearchController, private MTP::Sender { class ParticipantsBoxSearchController : public PeerListSearchController, private MTP::Sender {
public: public:
using Role = ParticipantsBoxController::Role; using Role = ParticipantsBoxController::Role;
using Additional = ParticipantsBoxController::Additional; using Additional = ParticipantsBoxController::Additional;
BannedBoxSearchController(gsl::not_null<ChannelData*> channel, Role role, gsl::not_null<Additional*> additional); ParticipantsBoxSearchController(gsl::not_null<ChannelData*> channel, Role role, gsl::not_null<Additional*> additional);
void searchQuery(const QString &query) override; void searchQuery(const QString &query) override;
bool isLoading() override; bool isLoading() override;