mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Use ParticipantsBoxController for members list.
Add search in channel/supergroup members inside PeerListBox. Also MembersBox is not used anymore.
This commit is contained in:
parent
b79ddb7a1c
commit
06d4ea2975
8 changed files with 187 additions and 44 deletions
|
@ -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";
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue