From b76bfe2008998502aa1af9af8f905ac305f96f6c Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 15 Jun 2017 21:09:31 +0300 Subject: [PATCH] Add admin/banned/restricted box using PeerListBox. --- Telegram/Resources/langs/lang.strings | 18 +- Telegram/SourceFiles/observer_peer.h | 2 +- .../profile/profile_block_settings.cpp | 1006 +++++++++++++---- .../profile/profile_block_settings.h | 6 +- Telegram/SourceFiles/structs.cpp | 10 +- 5 files changed, 821 insertions(+), 221 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index ab96052db..054419376 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -142,6 +142,13 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_error_public_groups_denied" = "Unfortunately, you were banned from participating in public groups.\n{more_info}"; "lng_error_cant_edit_admin" = "Sorry, you can't edit permissions for this admin."; "lng_error_cant_add_member" = "Sorry, you can't add the bot to this group. Ask a group admin to do it."; +"lng_error_cant_add_admin_invite" = "Sorry, you can't add this user as an admin because they are not a member of this group and you are not allowed to invite them."; +"lng_error_cant_add_admin_unban" = "Sorry, you can't add this user as an admin because they are in the blacklist and you can't unban them."; +"lng_error_cant_ban_admin" = "Sorry, you can't ban this user because they are an admin in this group and you are not allowed to demote them."; +"lng_sure_add_admin_invite" = "This user is not a member of this group. Add them to the group and promote them to admin?"; +"lng_sure_add_admin_unban" = "This user is currently restricted or banned in this group. Are you sure you want to unban and promote them?"; +"lng_sure_ban_admin" = "This user is an admin in this group. Are you sure you want to go ahead and restrict them?"; +"lng_sure_ban_user_group" = "Ban {user} in the group?"; "lng_edit_deleted" = "This message was deleted"; "lng_edit_too_long" = "Your message text is too long"; @@ -543,7 +550,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_profile_create_public_link" = "Create public link"; "lng_profile_edit_public_link" = "Edit public link"; "lng_profile_manage_admins" = "Manage administrators"; -"lng_profile_manage_blocklist" = "Manage blocked users"; +"lng_profile_manage_blocklist" = "Manage banned users"; "lng_profile_manage_restrictedlist" = "Manage restricted users"; "lng_profile_common_groups#one" = "{count} group in common"; "lng_profile_common_groups#other" = "{count} groups in common"; @@ -625,6 +632,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_channel_add_admins" = "New administrator"; "lng_channel_add_members" = "Add members"; +"lng_channel_add_banned" = "Ban user"; +"lng_channel_add_restricted" = "Restrict user"; "lng_channel_members" = "Members"; "lng_channel_only_last_shown#one" = "Only the last {count} member is shown here"; "lng_channel_only_last_shown#other" = "Only the last {count} members are shown here"; @@ -634,7 +643,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_channel_admin_status_creator" = "Creator"; "lng_channel_admin_status_promoted_by" = "Promoted by {user}"; -"lng_group_blocked_list_about" = "Blocked users are removed from the group and can only come back if invited by an admin.\nInvite links don't work for them."; +"lng_group_blocked_list_about" = "Banned users are removed from the group and can only come back if invited by an admin.\nInvite links don't work for them."; "lng_chat_all_members_admins" = "All Members Are Admins"; "lng_chat_about_all_admins" = "Group members can add new members, edit name and photo of the group."; @@ -1275,9 +1284,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_rights_chat_send_media" = "Send media"; "lng_rights_chat_send_stickers" = "Send stickers & GIFs"; "lng_rights_chat_send_links" = "Embed links"; -"lng_rights_chat_banned_until" = "Banned until: {when}"; +"lng_rights_chat_banned_until" = "Restricted until: {when}"; "lng_rights_chat_banned_forever" = "Forever"; -"lng_rights_chat_banned_block" = "Block and remove from group"; +"lng_rights_chat_banned_block" = "Ban and remove from group"; "lng_restricted_send_message" = "The admins of this group restricted you from writing here."; "lng_restricted_send_media" = "The admins of this group restricted you from posting media content here."; @@ -1286,6 +1295,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_restricted_send_inline" = "The admins of this group restricted you from posting inline content here."; "lng_restricted_list_title" = "Restricted users"; +"lng_banned_list_title" = "Banned users"; // Not used diff --git a/Telegram/SourceFiles/observer_peer.h b/Telegram/SourceFiles/observer_peer.h index 3cdc47e7b..8fc257118 100644 --- a/Telegram/SourceFiles/observer_peer.h +++ b/Telegram/SourceFiles/observer_peer.h @@ -50,7 +50,7 @@ struct PeerUpdate { InviteLinkChanged = 0x00000100U, MembersChanged = 0x00000200U, AdminsChanged = 0x00000400U, - BlockedUsersChanged = 0x00000800U, + BannedUsersChanged = 0x00000800U, // For users UserCanShareContact = 0x00010000U, diff --git a/Telegram/SourceFiles/profile/profile_block_settings.cpp b/Telegram/SourceFiles/profile/profile_block_settings.cpp index 9901d874f..62cbe8d0c 100644 --- a/Telegram/SourceFiles/profile/profile_block_settings.cpp +++ b/Telegram/SourceFiles/profile/profile_block_settings.cpp @@ -36,12 +36,74 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace Profile { namespace { -constexpr auto kBlockedPerPage = 40; +constexpr auto kBannedPerPage = 40; constexpr auto kAdminsPerPage = 200; +constexpr auto kParticipantsPerPage = 200; -class BlockedBoxSearchController : public PeerListSearchController, private MTP::Sender { +// Viewing admins, banned or restricted users list with search. +class ParticipantsBoxController : public PeerListController, private base::Subscriber, private MTP::Sender, public base::enable_weak_from_this { public: - BlockedBoxSearchController(gsl::not_null channel, bool restricted, gsl::not_null, MTPChannelBannedRights>*> rights); + enum class Role { + Admins, + Restricted, + Kicked, + }; + static void Start(gsl::not_null channel, Role role); + + struct Additional { + std::map, MTPChannelAdminRights> adminRights; + std::set> adminCanEdit; + std::map, gsl::not_null> adminPromotedBy; + std::map, MTPChannelBannedRights> restrictedRights; + std::set> kicked; + std::set> external; + std::set> infoNotLoaded; + UserData *creator = nullptr; + }; + + ParticipantsBoxController(gsl::not_null channel, Role role); + + void addNewItem(); + + void prepare() override; + void rowClicked(gsl::not_null row) override; + void rowActionClicked(gsl::not_null row) override; + void loadMoreRows() override; + + void peerListSearchAddRow(gsl::not_null peer) override; + + // Callback(gsl::not_null) + template + static void HandleParticipant(const MTPChannelParticipant &participant, Role role, gsl::not_null additional, Callback callback); + +private: + void editAdmin(gsl::not_null user); + void editAdminDone(gsl::not_null user, const MTPChannelAdminRights &rights); + void editRestricted(gsl::not_null user); + void editRestrictedDone(gsl::not_null user, const MTPChannelBannedRights &rights); + void removeKicked(gsl::not_null row, gsl::not_null user); + bool appendRow(gsl::not_null user); + bool prependRow(gsl::not_null user); + std::unique_ptr createRow(gsl::not_null user) const; + + gsl::not_null _channel; + Role _role = Role::Admins; + int _offset = 0; + mtpRequestId _loadRequestId = 0; + bool _allLoaded = false; + Additional _additional; + QPointer _editBox; + QPointer _addBox; + +}; + +// Banned and restricted users server side search. +class BannedBoxSearchController : public PeerListSearchController, private MTP::Sender { +public: + using Role = ParticipantsBoxController::Role; + using Additional = ParticipantsBoxController::Additional; + + BannedBoxSearchController(gsl::not_null channel, Role role, gsl::not_null additional); void searchQuery(const QString &query) override; bool isLoading() override; @@ -53,8 +115,8 @@ private: void searchDone(const MTPchannels_ChannelParticipants &result, mtpRequestId requestId); gsl::not_null _channel; - bool _restricted = false; - gsl::not_null, MTPChannelBannedRights>*> _rights; + Role _role = Role::Restricted; + gsl::not_null _additional; base::Timer _timer; QString _query; @@ -66,27 +128,34 @@ private: }; -class ParticipantsBoxController : public PeerListController, private base::Subscriber, private MTP::Sender, public base::enable_weak_from_this { +// Adding an admin, banned or restricted user from channel members with search + contacts search + global search. +class AddParticipantBoxController : public PeerListController, private base::Subscriber, private MTP::Sender, public base::enable_weak_from_this { public: - enum class Role { - Admins, - Restricted, - Kicked, - }; + using Role = ParticipantsBoxController::Role; + using Additional = ParticipantsBoxController::Additional; - ParticipantsBoxController(gsl::not_null channel, Role role); + AddParticipantBoxController(gsl::not_null channel, Role role, base::lambda doneCallback); void prepare() override; void rowClicked(gsl::not_null row) override; - void rowActionClicked(gsl::not_null row) override; void loadMoreRows() override; void peerListSearchAddRow(gsl::not_null peer) override; + // Callback(gsl::not_null) + template + static void HandleParticipant(const MTPChannelParticipant &participant, gsl::not_null additional, Callback callback); + private: - void editAdmin(gsl::not_null user); - void editRestricted(gsl::not_null user); - void removeKicked(gsl::not_null row, gsl::not_null user); + template + bool checkInfoLoaded(gsl::not_null user, Callback callback); + + void editAdmin(gsl::not_null user, bool sure = false); + void editAdminDone(gsl::not_null user, const MTPChannelAdminRights &rights); + void editRestricted(gsl::not_null user, bool sure = false); + void editRestrictedDone(gsl::not_null user, const MTPChannelBannedRights &rights); + void kickUser(gsl::not_null user, bool sure = false); + void restrictUserSure(gsl::not_null user, const MTPChannelBannedRights &rights); bool appendRow(gsl::not_null user); bool prependRow(gsl::not_null user); std::unique_ptr createRow(gsl::not_null user) const; @@ -96,119 +165,79 @@ private: int _offset = 0; mtpRequestId _loadRequestId = 0; bool _allLoaded = false; - std::map, MTPChannelAdminRights> _adminRights; - std::map, bool> _adminCanEdit; - std::map, gsl::not_null> _adminPromotedBy; - std::map, MTPChannelBannedRights> _restrictedRights; + Additional _additional; QPointer _editBox; + base::lambda _doneCallback; }; -BlockedBoxSearchController::BlockedBoxSearchController(gsl::not_null channel, bool restricted, gsl::not_null, MTPChannelBannedRights>*> rights) -: _channel(channel) -, _restricted(restricted) -, _rights(rights) { - _timer.setCallback([this] { searchOnServer(); }); -} +// Finds channel members, then contacts, then global search results. +class AddParticipantBoxSearchController : public PeerListSearchController, private MTP::Sender { +public: + using Role = ParticipantsBoxController::Role; + using Additional = ParticipantsBoxController::Additional; -void BlockedBoxSearchController::searchQuery(const QString &query) { - if (_query != query) { - _query = query; - _offset = 0; - _requestId = 0; - _allLoaded = false; - if (!_query.isEmpty() && !searchInCache()) { - _timer.callOnce(AutoSearchTimeout); - } else { - _timer.cancel(); - } - } -} + AddParticipantBoxSearchController(gsl::not_null channel, Role role, gsl::not_null additional); -bool BlockedBoxSearchController::searchInCache() { - auto it = _cache.find(_query); - if (it != _cache.cend()) { - _requestId = 0; - searchDone(it->second, _requestId); - return true; - } - return false; -} + void searchQuery(const QString &query) override; + bool isLoading() override; + bool loadMoreRows() override; -void BlockedBoxSearchController::searchOnServer() { - Expects(!_query.isEmpty()); - loadMoreRows(); -} +private: + bool searchInCache(); + void searchOnServer(); + void searchDone(const MTPchannels_ChannelParticipants &result, mtpRequestId requestId); -void BlockedBoxSearchController::searchDone(const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { - Expects(result.type() == mtpc_channels_channelParticipants); + gsl::not_null _channel; + Role _role = Role::Admins; + gsl::not_null _additional; - auto &participants = result.c_channels_channelParticipants(); - auto query = _query; - if (requestId) { - App::feedUsers(participants.vusers); - auto it = _queries.find(requestId); - if (it != _queries.cend()) { - query = it->second.first; // query - if (it->second.second == 0) { // offset - _cache[query] = result; - } - _queries.erase(it); - } - } + base::Timer _timer; + QString _query; + mtpRequestId _requestId = 0; + int _offset = 0; + bool _allLoaded = false; + std::map _cache; + std::map> _queries; // query, offset - if (_requestId == requestId) { - _requestId = 0; - auto &list = participants.vparticipants.v; - if (list.isEmpty()) { - _allLoaded = true; - } else { - for_const (auto &participant, list) { - ++_offset; - if (participant.type() == mtpc_channelParticipantBanned) { - auto &banned = participant.c_channelParticipantBanned(); - auto userId = banned.vuser_id.v; - if (auto user = App::userLoaded(userId)) { - delegate()->peerListSearchAddRow(user); - (*_rights)[user] = banned.vbanned_rights; - } - } else { - LOG(("API Error: Non banned participant got while requesting for kicked participants: %1").arg(participant.type())); - continue; - } - } - } - delegate()->peerListSearchRefreshRows(); - } -} +}; -bool BlockedBoxSearchController::isLoading() { - return _timer.isActive() || _requestId; -} - -bool BlockedBoxSearchController::loadMoreRows() { - if (_query.isEmpty()) { - return false; - } - if (!_allLoaded && !isLoading()) { - auto filter = _restricted ? MTP_channelParticipantsBanned(MTP_string(_query)) : MTP_channelParticipantsKicked(MTP_string(_query)); - _requestId = request(MTPchannels_GetParticipants(_channel->inputChannel, filter, MTP_int(_offset), MTP_int(kBlockedPerPage))).done([this](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { - searchDone(result, requestId); - }).fail([this](const RPCError &error, mtpRequestId requestId) { - if (_requestId == requestId) { - _requestId = 0; - _allLoaded = true; - delegate()->peerListSearchRefreshRows(); - } - }).send(); - _queries.emplace(_requestId, std::make_pair(_query, _offset)); - } - return true; -} - -ParticipantsBoxController::ParticipantsBoxController(gsl::not_null channel, Role role) : PeerListController((role == Role::Admins) ? nullptr : std::make_unique(channel, (role == Role::Restricted), &_restrictedRights)) +ParticipantsBoxController::ParticipantsBoxController(gsl::not_null channel, Role role) : PeerListController((role == Role::Admins) ? nullptr : std::make_unique(channel, role, &_additional)) , _channel(channel) , _role(role) { + if (_channel->mgInfo) { + _additional.creator = _channel->mgInfo->creator; + } +} + +void ParticipantsBoxController::Start(gsl::not_null channel, Role role) { + auto controller = std::make_unique(channel, role); + auto initBox = [role, channel, controller = controller.get()](PeerListBox *box) { + box->addButton(langFactory(lng_close), [box] { box->closeBox(); }); + auto buttonText = [role] { + switch (role) { + case Role::Admins: return langFactory(lng_channel_add_admin); + case Role::Restricted: return langFactory(lng_channel_add_restricted); + case Role::Kicked: return langFactory(lng_channel_add_banned); + } + Unexpected("Role value in ParticipantsBoxController::Start()"); + }; + if ((role == Role::Admins && channel->canAddAdmins()) || ((role == Role::Restricted || role == Role::Kicked) && channel->canBanMembers())) { + box->addLeftButton(buttonText(), [controller] { controller->addNewItem(); }); + } + }; + Ui::show(Box(std::move(controller), std::move(initBox)), KeepOtherLayers); +} + +void ParticipantsBoxController::addNewItem() { + auto weak = base::weak_unique_ptr(this); + _addBox = Ui::show(Box(std::make_unique(_channel, _role, [weak] { + if (weak && weak->_addBox) { + weak->_addBox->closeBox(); + } + }), [](PeerListBox *box) { + box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); }); + }), KeepOtherLayers); } void ParticipantsBoxController::peerListSearchAddRow(gsl::not_null peer) { @@ -219,17 +248,53 @@ void ParticipantsBoxController::peerListSearchAddRow(gsl::not_null pe } } +template +void ParticipantsBoxController::HandleParticipant(const MTPChannelParticipant &participant, Role role, gsl::not_null additional, Callback callback) { + if (role == Role::Admins && participant.type() == mtpc_channelParticipantAdmin) { + auto &admin = participant.c_channelParticipantAdmin(); + if (auto user = App::userLoaded(admin.vuser_id.v)) { + additional->adminRights[user] = admin.vadmin_rights; + if (admin.is_can_edit()) { + additional->adminCanEdit.emplace(user); + } else { + additional->adminCanEdit.erase(user); + } + if (auto promoted = App::userLoaded(admin.vpromoted_by.v)) { + auto it = additional->adminPromotedBy.find(user); + if (it == additional->adminPromotedBy.end()) { + additional->adminPromotedBy.emplace(user, promoted); + } else { + it->second = promoted; + } + } else { + LOG(("API Error: No user %1 for admin promoted by.").arg(admin.vpromoted_by.v)); + } + callback(user); + } + } else if (role == Role::Admins && participant.type() == mtpc_channelParticipantCreator) { + auto &creator = participant.c_channelParticipantCreator(); + if (auto user = App::userLoaded(creator.vuser_id.v)) { + additional->creator = user; + callback(user); + } + } else if ((role == Role::Restricted || role == Role::Kicked) && participant.type() == mtpc_channelParticipantBanned) { + auto &banned = participant.c_channelParticipantBanned(); + if (auto user = App::userLoaded(banned.vuser_id.v)) { + additional->restrictedRights[user] = banned.vbanned_rights; + callback(user); + } + } else { + LOG(("API Error: Bad participant type got while requesting for participants: %1").arg(participant.type())); + } +} + void ParticipantsBoxController::prepare() { if (_role == Role::Admins) { delegate()->peerListSetSearchMode(PeerListSearchMode::Local); delegate()->peerListSetTitle(langFactory(lng_channel_admins)); } else { delegate()->peerListSetSearchMode(PeerListSearchMode::Complex); - if (_role == Role::Restricted) { - delegate()->peerListSetTitle(langFactory(lng_restricted_list_title)); - } else { - delegate()->peerListSetTitle(langFactory(lng_blocked_list_title)); - } + delegate()->peerListSetTitle(langFactory((_role == Role::Restricted) ? lng_restricted_list_title : lng_banned_list_title)); } setDescriptionText(lang(lng_contacts_loading)); setSearchNoResultsText(lang(lng_blocked_list_not_found)); @@ -254,7 +319,7 @@ void ParticipantsBoxController::loadMoreRows() { } return MTP_channelParticipantsKicked(MTP_string(QString())); }; - auto perPage = (_role == Role::Admins) ? kAdminsPerPage : kBlockedPerPage; + auto perPage = (_role == Role::Admins) ? kAdminsPerPage : kBannedPerPage; _loadRequestId = request(MTPchannels_GetParticipants(_channel->inputChannel, filter(), MTP_int(_offset), MTP_int(perPage))).done([this](const MTPchannels_ChannelParticipants &result) { Expects(result.type() == mtpc_channels_channelParticipants); @@ -272,38 +337,9 @@ void ParticipantsBoxController::loadMoreRows() { } else { for_const (auto &participant, list) { ++_offset; - if (_role == Role::Admins && participant.type() == mtpc_channelParticipantAdmin) { - auto &admin = participant.c_channelParticipantAdmin(); - if (auto user = App::userLoaded(admin.vuser_id.v)) { - _adminRights.emplace(user, admin.vadmin_rights); - if (admin.is_can_edit()) { - _adminCanEdit.emplace(user, true); - } else { - _adminCanEdit.erase(user); - } - if (auto promoted = App::userLoaded(admin.vpromoted_by.v)) { - _adminPromotedBy.emplace(user, promoted); - } else { - LOG(("API Error: No user %1 for admin promoted by.").arg(admin.vpromoted_by.v)); - } - appendRow(user); - } - } else if (_role == Role::Admins && participant.type() == mtpc_channelParticipantCreator) { - auto &creator = participant.c_channelParticipantCreator(); - if (auto user = App::userLoaded(creator.vuser_id.v)) { - _adminCanEdit.erase(user); - appendRow(user); - } - } else if ((_role == Role::Restricted || _role == Role::Kicked) && participant.type() == mtpc_channelParticipantBanned) { - auto &banned = participant.c_channelParticipantBanned(); - if (auto user = App::userLoaded(banned.vuser_id.v)) { - _restrictedRights.emplace(user, banned.vbanned_rights); - appendRow(user); - } - } else { - LOG(("API Error: Bad participant type got while requesting for participants: %1").arg(participant.type())); - continue; - } + HandleParticipant(participant, _role, &_additional, [this](gsl::not_null user) { + appendRow(user); + }); } } delegate()->peerListRefreshRows(); @@ -330,61 +366,69 @@ void ParticipantsBoxController::rowActionClicked(gsl::not_null row } void ParticipantsBoxController::editAdmin(gsl::not_null user) { - if (_adminCanEdit.find(user) == _adminCanEdit.end()) { + if (_additional.adminCanEdit.find(user) == _additional.adminCanEdit.end()) { return; } - auto it = _adminRights.find(user); - t_assert(it != _adminRights.cend()); + auto it = _additional.adminRights.find(user); + t_assert(it != _additional.adminRights.cend()); auto weak = base::weak_unique_ptr(this); _editBox = Ui::show(Box(_channel, user, it->second, [megagroup = _channel.get(), user, weak](const MTPChannelAdminRights &rights) { MTP::send(MTPchannels_EditAdmin(megagroup->inputChannel, user->inputUser, rights), rpcDone([megagroup, user, weak, rights](const MTPUpdates &result) { if (App::main()) App::main()->sentUpdatesReceived(result); megagroup->applyEditAdmin(user, rights); if (weak) { - weak->_editBox->closeBox(); - if (rights.c_channelAdminRights().vflags.v == 0) { - if (auto row = weak->delegate()->peerListFindRow(user->id)) { - weak->delegate()->peerListRemoveRow(row); - if (!weak->delegate()->peerListFullRowsCount()) { - weak->setDescriptionText(lang(lng_blocked_list_not_found)); - } - weak->delegate()->peerListRefreshRows(); - } - } else { - weak->_adminRights[user] = rights; - } + weak->editAdminDone(user, rights); } })); }), KeepOtherLayers); } +void ParticipantsBoxController::editAdminDone(gsl::not_null user, const MTPChannelAdminRights &rights) { + if (_editBox) _editBox->closeBox(); + if (rights.c_channelAdminRights().vflags.v == 0) { + if (auto row = delegate()->peerListFindRow(user->id)) { + delegate()->peerListRemoveRow(row); + if (!delegate()->peerListFullRowsCount()) { + setDescriptionText(lang(lng_blocked_list_not_found)); + } + delegate()->peerListRefreshRows(); + } + } else { + _additional.adminRights[user] = rights; + } +} + void ParticipantsBoxController::editRestricted(gsl::not_null user) { - auto it = _restrictedRights.find(user); - t_assert(it != _restrictedRights.cend()); + auto it = _additional.restrictedRights.find(user); + t_assert(it != _additional.restrictedRights.cend()); auto weak = base::weak_unique_ptr(this); _editBox = Ui::show(Box(_channel, user, it->second, [megagroup = _channel.get(), user, weak](const MTPChannelBannedRights &rights) { MTP::send(MTPchannels_EditBanned(megagroup->inputChannel, user->inputUser, rights), rpcDone([megagroup, user, weak, rights](const MTPUpdates &result) { if (App::main()) App::main()->sentUpdatesReceived(result); megagroup->applyEditBanned(user, rights); if (weak) { - weak->_editBox->closeBox(); - if (rights.c_channelBannedRights().vflags.v == 0 || rights.c_channelBannedRights().is_view_messages()) { - if (auto row = weak->delegate()->peerListFindRow(user->id)) { - weak->delegate()->peerListRemoveRow(row); - if (!weak->delegate()->peerListFullRowsCount()) { - weak->setDescriptionText(lang(lng_blocked_list_not_found)); - } - weak->delegate()->peerListRefreshRows(); - } - } else { - weak->_restrictedRights[user] = rights; - } + weak->editRestrictedDone(user, rights); } })); }), KeepOtherLayers); } +void ParticipantsBoxController::editRestrictedDone(gsl::not_null user, const MTPChannelBannedRights &rights) { + if (_editBox) _editBox->closeBox(); + if (rights.c_channelBannedRights().vflags.v == 0 || rights.c_channelBannedRights().is_view_messages()) { + if (auto row = delegate()->peerListFindRow(user->id)) { + delegate()->peerListRemoveRow(row); + if (!delegate()->peerListFullRowsCount()) { + setDescriptionText(lang(lng_blocked_list_not_found)); + } + delegate()->peerListRefreshRows(); + } + } else { + _additional.restrictedRights[user] = rights; + } +} + void ParticipantsBoxController::removeKicked(gsl::not_null row, gsl::not_null user) { delegate()->peerListRemoveRow(row); delegate()->peerListRefreshRows(); @@ -417,14 +461,14 @@ bool ParticipantsBoxController::prependRow(gsl::not_null user) { std::unique_ptr ParticipantsBoxController::createRow(gsl::not_null user) const { auto row = std::make_unique(user); if (_role == Role::Admins) { - auto promotedBy = _adminPromotedBy.find(user); - if (promotedBy == _adminPromotedBy.end()) { + auto promotedBy = _additional.adminPromotedBy.find(user); + if (promotedBy == _additional.adminPromotedBy.end()) { row->setCustomStatus(lang(lng_channel_admin_status_creator)); } else { row->setCustomStatus(lng_channel_admin_status_promoted_by(lt_user, App::peerName(promotedBy->second))); } } - if (_role == Role::Restricted || (_role == Role::Admins && _adminCanEdit.find(user) != _adminCanEdit.end())) { + if (_role == Role::Restricted || (_role == Role::Admins && _additional.adminCanEdit.find(user) != _additional.adminCanEdit.end())) { row->setActionLink(lang(lng_profile_edit_permissions)); } else if (_role == Role::Kicked) { row->setActionLink(lang(lng_blocked_list_unblock)); @@ -432,6 +476,558 @@ std::unique_ptr ParticipantsBoxController::createRow(gsl::not_null< return std::move(row); } +BannedBoxSearchController::BannedBoxSearchController(gsl::not_null channel, Role role, gsl::not_null additional) +: _channel(channel) +, _role(role) +, _additional(additional) { + Expects(role != Role::Admins); + _timer.setCallback([this] { searchOnServer(); }); +} + +void BannedBoxSearchController::searchQuery(const QString &query) { + if (_query != query) { + _query = query; + _offset = 0; + _requestId = 0; + _allLoaded = false; + if (!_query.isEmpty() && !searchInCache()) { + _timer.callOnce(AutoSearchTimeout); + } else { + _timer.cancel(); + } + } +} + +bool BannedBoxSearchController::searchInCache() { + auto it = _cache.find(_query); + if (it != _cache.cend()) { + _requestId = 0; + searchDone(it->second, _requestId); + return true; + } + return false; +} + +void BannedBoxSearchController::searchOnServer() { + Expects(!_query.isEmpty()); + loadMoreRows(); +} + +void BannedBoxSearchController::searchDone(const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { + Expects(result.type() == mtpc_channels_channelParticipants); + + auto &participants = result.c_channels_channelParticipants(); + auto query = _query; + if (requestId) { + App::feedUsers(participants.vusers); + auto it = _queries.find(requestId); + if (it != _queries.cend()) { + query = it->second.first; // query + if (it->second.second == 0) { // offset + _cache[query] = result; + } + _queries.erase(it); + } + } + + if (_requestId == requestId) { + _requestId = 0; + auto &list = participants.vparticipants.v; + if (list.isEmpty()) { + _allLoaded = true; + } else { + for_const (auto &participant, list) { + ++_offset; + ParticipantsBoxController::HandleParticipant(participant, _role, _additional, [this](gsl::not_null user) { + delegate()->peerListSearchAddRow(user); + }); + } + } + delegate()->peerListSearchRefreshRows(); + } +} + +bool BannedBoxSearchController::isLoading() { + return _timer.isActive() || _requestId; +} + +bool BannedBoxSearchController::loadMoreRows() { + if (_query.isEmpty()) { + return false; + } + if (!_allLoaded && !isLoading()) { + auto filter = (_role == Role::Restricted) ? MTP_channelParticipantsBanned(MTP_string(_query)) : MTP_channelParticipantsKicked(MTP_string(_query)); + _requestId = request(MTPchannels_GetParticipants(_channel->inputChannel, filter, MTP_int(_offset), MTP_int(kBannedPerPage))).done([this](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { + searchDone(result, requestId); + }).fail([this](const RPCError &error, mtpRequestId requestId) { + if (_requestId == requestId) { + _requestId = 0; + _allLoaded = true; + delegate()->peerListSearchRefreshRows(); + } + }).send(); + _queries.emplace(_requestId, std::make_pair(_query, _offset)); + } + return true; +} + +AddParticipantBoxController::AddParticipantBoxController(gsl::not_null channel, Role role, base::lambda doneCallback) +: _channel(channel) +, _role(role) +, _doneCallback(std::move(doneCallback)) { + if (_channel->mgInfo) { + _additional.creator = _channel->mgInfo->creator; + } +} + +void AddParticipantBoxController::peerListSearchAddRow(gsl::not_null peer) { + if (peer->isSelf()) { + return; + } + PeerListController::peerListSearchAddRow(peer); +} + +void AddParticipantBoxController::prepare() { + delegate()->peerListSetSearchMode(PeerListSearchMode::Complex); + auto title = [this] { + switch (_role) { + case Role::Admins: return langFactory(lng_channel_add_admin); + case Role::Restricted: return langFactory(lng_channel_add_restricted); + case Role::Kicked: return langFactory(lng_channel_add_banned); + } + Unexpected("Role in AddParticipantBoxController::prepare()"); + }; + delegate()->peerListSetTitle(title()); + setDescriptionText(lang(lng_contacts_loading)); + setSearchNoResultsText(lang(lng_blocked_list_not_found)); + delegate()->peerListRefreshRows(); + + loadMoreRows(); +} + +void AddParticipantBoxController::loadMoreRows() { + if (searchController() && searchController()->loadMoreRows()) { + return; + } + if (_loadRequestId || _allLoaded) { + return; + } + + _loadRequestId = request(MTPchannels_GetParticipants(_channel->inputChannel, MTP_channelParticipantsRecent(), MTP_int(_offset), MTP_int(kParticipantsPerPage))).done([this](const MTPchannels_ChannelParticipants &result) { + Expects(result.type() == mtpc_channels_channelParticipants); + + _loadRequestId = 0; + + auto &participants = result.c_channels_channelParticipants(); + App::feedUsers(participants.vusers); + + auto &list = participants.vparticipants.v; + if (list.isEmpty()) { + _allLoaded = true; + } else { + for_const (auto &participant, list) { + ++_offset; + HandleParticipant(participant, &_additional, [this](gsl::not_null user) { + appendRow(user); + }); + } + } + if (delegate()->peerListFullRowsCount() > 0) { + setDescriptionText(QString()); + } + delegate()->peerListRefreshRows(); + }).fail([this](const RPCError &error) { + _loadRequestId = 0; + }).send(); +} + +void AddParticipantBoxController::rowClicked(gsl::not_null row) { + auto user = row->peer()->asUser(); + switch (_role) { + case Role::Admins: return editAdmin(user); + case Role::Restricted: return editRestricted(user); + case Role::Kicked: return kickUser(user); + } + Unexpected("Role in AddParticipantBoxController::rowClicked()"); +} + +template +bool AddParticipantBoxController::checkInfoLoaded(gsl::not_null user, Callback callback) { + if (_additional.infoNotLoaded.find(user) == _additional.infoNotLoaded.end()) { + return true; + } + + // We don't know what this user status is in the group. + request(MTPchannels_GetParticipant(_channel->inputChannel, user->inputUser)).done([this, user, callback](const MTPchannels_ChannelParticipant &result) { + Expects(result.type() == mtpc_channels_channelParticipant); + auto &participant = result.c_channels_channelParticipant(); + App::feedUsers(participant.vusers); + HandleParticipant(participant.vparticipant, &_additional, [](gsl::not_null) {}); + _additional.infoNotLoaded.erase(user); + callback(); + }).fail([this, user, callback](const RPCError &error) { + _additional.infoNotLoaded.erase(user); + _additional.external.emplace(user); + callback(); + }).send(); + return false; +} + +void AddParticipantBoxController::editAdmin(gsl::not_null user, bool sure) { + if (!checkInfoLoaded(user, [this, user] { editAdmin(user); })) { + return; + } + + if (sure && _editBox) { + // Close the confirmation box. + _editBox->closeBox(); + } + + // Check restrictions. + auto weak = base::weak_unique_ptr(this); + auto alreadyIt = _additional.adminRights.find(user); + auto currentRights = EditAdminBox::DefaultRights(_channel); + if (alreadyIt != _additional.adminRights.end() || _additional.creator == user) { + // The user is already an admin. + if (_additional.adminCanEdit.find(user) == _additional.adminCanEdit.end() || _additional.creator == user) { + Ui::show(Box(lang(lng_error_cant_edit_admin)), KeepOtherLayers); + return; + } + currentRights = alreadyIt->second; + } else if (_additional.restrictedRights.find(user) != _additional.restrictedRights.end() || _additional.kicked.find(user) != _additional.kicked.end()) { + // The user is banned or restricted. + if (_channel->canBanMembers()) { + if (!sure) { + _editBox = Ui::show(Box(lang(lng_sure_add_admin_unban), [weak, user] { weak->editAdmin(user, true); }), KeepOtherLayers); + return; + } + } else { + Ui::show(Box(lang(lng_error_cant_add_admin_unban)), KeepOtherLayers); + return; + } + } else if (_additional.external.find(user) != _additional.external.end()) { + // The user is not in the group yet. + if (_channel->canAddMembers()) { + if (!sure) { + _editBox = Ui::show(Box(lang(lng_sure_add_admin_invite), [weak, user] { weak->editAdmin(user, true); }), KeepOtherLayers); + return; + } + } else { + Ui::show(Box(lang(lng_error_cant_add_admin_invite)), KeepOtherLayers); + return; + } + } + + // Finally edit the admin. + _editBox = Ui::show(Box(_channel, user, currentRights, [megagroup = _channel.get(), user, weak](const MTPChannelAdminRights &rights) { + MTP::send(MTPchannels_EditAdmin(megagroup->inputChannel, user->inputUser, rights), rpcDone([megagroup, user, weak, rights](const MTPUpdates &result) { + if (App::main()) App::main()->sentUpdatesReceived(result); + megagroup->applyEditAdmin(user, rights); + if (weak) { + weak->editAdminDone(user, rights); + } + })); + }), KeepOtherLayers); +} + +void AddParticipantBoxController::editAdminDone(gsl::not_null user, const MTPChannelAdminRights &rights) { + if (_editBox) _editBox->closeBox(); + _additional.restrictedRights.erase(user); + _additional.kicked.erase(user); + _additional.external.erase(user); + if (rights.c_channelAdminRights().vflags.v == 0) { + _additional.adminRights.erase(user); + _additional.adminPromotedBy.erase(user); + _additional.adminCanEdit.erase(user); + } else { + _additional.adminRights[user] = rights; + _additional.adminCanEdit.emplace(user); + auto it = _additional.adminPromotedBy.find(user); + if (it == _additional.adminPromotedBy.end()) { + _additional.adminPromotedBy.emplace(user, App::self()); + } + } + _doneCallback(); +} + +void AddParticipantBoxController::editRestricted(gsl::not_null user, bool sure) { + if (!checkInfoLoaded(user, [this, user] { editRestricted(user); })) { + return; + } + + if (sure && _editBox) { + // Close the confirmation box. + _editBox->closeBox(); + } + + // Check restrictions. + auto weak = base::weak_unique_ptr(this); + auto alreadyIt = _additional.restrictedRights.find(user); + auto currentRights = EditRestrictedBox::DefaultRights(_channel); + if (alreadyIt != _additional.restrictedRights.end()) { + // The user is already banned or restricted. + currentRights = alreadyIt->second; + } else if (_additional.adminRights.find(user) != _additional.adminRights.end() || _additional.creator == user) { + // The user is an admin or creator. + if (_additional.adminCanEdit.find(user) != _additional.adminCanEdit.end()) { + if (!sure) { + _editBox = Ui::show(Box(lang(lng_sure_ban_admin), [weak, user] { weak->editRestricted(user, true); }), KeepOtherLayers); + return; + } + } else { + Ui::show(Box(lang(lng_error_cant_ban_admin)), KeepOtherLayers); + return; + } + } + + // Finally edit the restricted. + _editBox = Ui::show(Box(_channel, user, currentRights, [user, weak](const MTPChannelBannedRights &rights) { + if (weak) { + weak->restrictUserSure(user, rights); + } + }), KeepOtherLayers); +} + +void AddParticipantBoxController::restrictUserSure(gsl::not_null user, const MTPChannelBannedRights &rights) { + auto weak = base::weak_unique_ptr(this); + MTP::send(MTPchannels_EditBanned(_channel->inputChannel, user->inputUser, rights), rpcDone([megagroup = _channel.get(), user, weak, rights](const MTPUpdates &result) { + if (App::main()) App::main()->sentUpdatesReceived(result); + megagroup->applyEditBanned(user, rights); + if (weak) { + weak->editRestrictedDone(user, rights); + } + })); +} + +void AddParticipantBoxController::editRestrictedDone(gsl::not_null user, const MTPChannelBannedRights &rights) { + if (_editBox) _editBox->closeBox(); + _additional.adminRights.erase(user); + _additional.adminCanEdit.erase(user); + _additional.adminPromotedBy.erase(user); + if (rights.c_channelBannedRights().vflags.v == 0) { + _additional.restrictedRights.erase(user); + _additional.kicked.erase(user); + } else if (rights.c_channelBannedRights().vflags.v & MTPDchannelBannedRights::Flag::f_view_messages) { + _additional.restrictedRights.erase(user); + _additional.kicked.emplace(user); + } else { + _additional.restrictedRights[user] = rights; + _additional.kicked.erase(user); + } + _doneCallback(); +} + +void AddParticipantBoxController::kickUser(gsl::not_null user, bool sure) { + if (!checkInfoLoaded(user, [this, user] { kickUser(user); })) { + return; + } + + // Check restrictions. + auto weak = base::weak_unique_ptr(this); + if (_additional.adminRights.find(user) != _additional.adminRights.end() || _additional.creator == user) { + // The user is an admin or creator. + if (_additional.adminCanEdit.find(user) != _additional.adminCanEdit.end()) { + if (!sure) { + Ui::show(Box(lang(lng_sure_ban_admin), [weak, user] { weak->kickUser(user, true); }), KeepOtherLayers); + return; + } + } else { + Ui::show(Box(lang(lng_error_cant_ban_admin)), KeepOtherLayers); + return; + } + } + + // Finally kick him. + if (!sure) { + auto text = lng_sure_ban_user_group(lt_user, App::peerName(user)); + Ui::show(Box(text, [weak, user] { weak->kickUser(user, true); }), KeepOtherLayers); + return; + } + restrictUserSure(user, ChannelData::KickedRestrictedRights()); +} + +bool AddParticipantBoxController::appendRow(gsl::not_null user) { + if (delegate()->peerListFindRow(user->id) || user->isSelf()) { + return false; + } + delegate()->peerListAppendRow(createRow(user)); + return true; +} + +bool AddParticipantBoxController::prependRow(gsl::not_null user) { + if (delegate()->peerListFindRow(user->id)) { + return false; + } + delegate()->peerListPrependRow(createRow(user)); + return true; +} + +std::unique_ptr AddParticipantBoxController::createRow(gsl::not_null user) const { + auto row = std::make_unique(user); + return std::move(row); +} + +template +void AddParticipantBoxController::HandleParticipant(const MTPChannelParticipant &participant, gsl::not_null additional, Callback callback) { + switch (participant.type()) { + case mtpc_channelParticipantAdmin: { + auto &admin = participant.c_channelParticipantAdmin(); + if (auto user = App::userLoaded(admin.vuser_id.v)) { + additional->infoNotLoaded.erase(user); + additional->restrictedRights.erase(user); + additional->kicked.erase(user); + additional->adminRights[user] = admin.vadmin_rights; + if (admin.is_can_edit()) { + additional->adminCanEdit.emplace(user); + } else { + additional->adminCanEdit.erase(user); + } + if (auto promoted = App::userLoaded(admin.vpromoted_by.v)) { + auto it = additional->adminPromotedBy.find(user); + if (it == additional->adminPromotedBy.end()) { + additional->adminPromotedBy.emplace(user, promoted); + } else { + it->second = promoted; + } + } else { + LOG(("API Error: No user %1 for admin promoted by.").arg(admin.vpromoted_by.v)); + } + callback(user); + } + } break; + case mtpc_channelParticipantCreator: { + auto &creator = participant.c_channelParticipantCreator(); + if (auto user = App::userLoaded(creator.vuser_id.v)) { + additional->infoNotLoaded.erase(user); + additional->creator = user; + callback(user); + } + } break; + case mtpc_channelParticipantBanned: { + auto &banned = participant.c_channelParticipantBanned(); + if (auto user = App::userLoaded(banned.vuser_id.v)) { + additional->infoNotLoaded.erase(user); + additional->adminRights.erase(user); + additional->adminCanEdit.erase(user); + additional->adminPromotedBy.erase(user); + if (banned.is_left()) { + additional->kicked.emplace(user); + } else { + additional->kicked.erase(user); + } + additional->restrictedRights[user] = banned.vbanned_rights; + callback(user); + } + } break; + case mtpc_channelParticipant: { + auto &data = participant.c_channelParticipant(); + if (auto user = App::userLoaded(data.vuser_id.v)) { + additional->infoNotLoaded.erase(user); + additional->adminRights.erase(user); + additional->adminCanEdit.erase(user); + additional->adminPromotedBy.erase(user); + additional->restrictedRights.erase(user); + additional->kicked.erase(user); + callback(user); + } + } break; + default: Unexpected("Participant type in AddParticipantBoxController::HandleParticipant()"); + } +} + +AddParticipantBoxSearchController::AddParticipantBoxSearchController(gsl::not_null channel, Role role, gsl::not_null additional) +: _channel(channel) +, _role(role) +, _additional(additional) { + _timer.setCallback([this] { searchOnServer(); }); +} + +void AddParticipantBoxSearchController::searchQuery(const QString &query) { + if (_query != query) { + _query = query; + _offset = 0; + _requestId = 0; + _allLoaded = false; + if (!_query.isEmpty() && !searchInCache()) { + _timer.callOnce(AutoSearchTimeout); + } else { + _timer.cancel(); + } + } +} + +bool AddParticipantBoxSearchController::searchInCache() { + auto it = _cache.find(_query); + if (it != _cache.cend()) { + _requestId = 0; + searchDone(it->second, _requestId); + return true; + } + return false; +} + +void AddParticipantBoxSearchController::searchOnServer() { + Expects(!_query.isEmpty()); + loadMoreRows(); +} + +void AddParticipantBoxSearchController::searchDone(const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { + Expects(result.type() == mtpc_channels_channelParticipants); + + auto &participants = result.c_channels_channelParticipants(); + auto query = _query; + if (requestId) { + App::feedUsers(participants.vusers); + auto it = _queries.find(requestId); + if (it != _queries.cend()) { + query = it->second.first; // query + if (it->second.second == 0) { // offset + _cache[query] = result; + } + _queries.erase(it); + } + } + + if (_requestId == requestId) { + _requestId = 0; + auto &list = participants.vparticipants.v; + if (list.isEmpty()) { + _allLoaded = true; + } else { + for_const (auto &participant, list) { + ++_offset; + AddParticipantBoxController::HandleParticipant(participant, _additional, [this](gsl::not_null user) { + delegate()->peerListSearchAddRow(user); + }); + } + } + delegate()->peerListSearchRefreshRows(); + } +} + +bool AddParticipantBoxSearchController::isLoading() { + return _timer.isActive() || _requestId; +} + +bool AddParticipantBoxSearchController::loadMoreRows() { + if (_query.isEmpty()) { + return false; + } + if (!_allLoaded && !isLoading()) { + _requestId = request(MTPchannels_GetParticipants(_channel->inputChannel, MTP_channelParticipantsSearch(MTP_string(_query)), MTP_int(_offset), MTP_int(kBannedPerPage))).done([this](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { + searchDone(result, requestId); + }).fail([this](const RPCError &error, mtpRequestId requestId) { + if (_requestId == requestId) { + _requestId = 0; + _allLoaded = true; + delegate()->peerListSearchRefreshRows(); + } + }).send(); + _queries.emplace(_requestId, std::make_pair(_query, _offset)); + } + return true; +} + } // namespace using UpdateFlag = Notify::PeerUpdate::Flag; @@ -446,7 +1042,7 @@ SettingsWidget::SettingsWidget(QWidget *parent, PeerData *peer) : BlockWidget(pa observeEvents |= UpdateFlag::ChatCanEdit | UpdateFlag::InviteLinkChanged; } } else if (auto channel = peer->asChannel()) { - observeEvents |= UpdateFlag::ChannelRightsChanged | UpdateFlag::BlockedUsersChanged | UpdateFlag::UsernameChanged | UpdateFlag::InviteLinkChanged; + observeEvents |= UpdateFlag::ChannelRightsChanged | UpdateFlag::BannedUsersChanged | UpdateFlag::UsernameChanged | UpdateFlag::InviteLinkChanged; } subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) { notifyPeerUpdated(update); @@ -472,8 +1068,8 @@ void SettingsWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { if (update.flags & (UpdateFlag::ChannelRightsChanged | UpdateFlag::ChatCanEdit)) { refreshManageAdminsButton(); } - if (update.flags & (UpdateFlag::ChannelRightsChanged | UpdateFlag::BlockedUsersChanged)) { - refreshManageBlockedUsersButton(); + if (update.flags & (UpdateFlag::ChannelRightsChanged | UpdateFlag::BannedUsersChanged)) { + refreshManageBannedUsersButton(); } contentSizeUpdated(); @@ -496,7 +1092,7 @@ int SettingsWidget::resizeGetHeight(int newWidth) { newHeight += button->height(); }; moveLink(_manageAdmins); - moveLink(_manageBlockedUsers); + moveLink(_manageBannedUsers); moveLink(_manageRestrictedUsers); moveLink(_inviteLink); @@ -507,7 +1103,7 @@ int SettingsWidget::resizeGetHeight(int newWidth) { void SettingsWidget::refreshButtons() { refreshEnableNotifications(); refreshManageAdminsButton(); - refreshManageBlockedUsersButton(); + refreshManageBannedUsersButton(); refreshInviteLinkButton(); } @@ -538,18 +1134,18 @@ void SettingsWidget::refreshManageAdminsButton() { } } -void SettingsWidget::refreshManageBlockedUsersButton() { - auto hasManageBlockedUsers = [this] { +void SettingsWidget::refreshManageBannedUsersButton() { + auto hasManageBannedUsers = [this] { if (auto channel = peer()->asMegagroup()) { return channel->canBanMembers() && (channel->kickedCount() > 0); } return false; }; - _manageBlockedUsers.destroy(); - if (hasManageBlockedUsers()) { - _manageBlockedUsers.create(this, lang(lng_profile_manage_blocklist), st::defaultLeftOutlineButton); - _manageBlockedUsers->show(); - connect(_manageBlockedUsers, SIGNAL(clicked()), this, SLOT(onManageBlockedUsers())); + _manageBannedUsers.destroy(); + if (hasManageBannedUsers()) { + _manageBannedUsers.create(this, lang(lng_profile_manage_blocklist), st::defaultLeftOutlineButton); + _manageBannedUsers->show(); + connect(_manageBannedUsers, SIGNAL(clicked()), this, SLOT(onManageBannedUsers())); } auto hasManageRestrictedUsers = [this] { @@ -597,25 +1193,19 @@ void SettingsWidget::onManageAdmins() { if (auto chat = peer()->asChat()) { Ui::show(Box(chat, MembersFilter::Admins)); } else if (auto channel = peer()->asChannel()) { - Ui::show(Box(std::make_unique(channel, ParticipantsBoxController::Role::Admins), [](PeerListBox *box) { - box->addButton(langFactory(lng_close), [box] { box->closeBox(); }); - })); + ParticipantsBoxController::Start(channel, ParticipantsBoxController::Role::Admins); } } -void SettingsWidget::onManageBlockedUsers() { +void SettingsWidget::onManageBannedUsers() { if (auto channel = peer()->asMegagroup()) { - Ui::show(Box(std::make_unique(channel, ParticipantsBoxController::Role::Kicked), [](PeerListBox *box) { - box->addButton(langFactory(lng_close), [box] { box->closeBox(); }); - })); + ParticipantsBoxController::Start(channel, ParticipantsBoxController::Role::Kicked); } } void SettingsWidget::onManageRestrictedUsers() { if (auto channel = peer()->asMegagroup()) { - Ui::show(Box(std::make_unique(channel, ParticipantsBoxController::Role::Restricted), [](PeerListBox *box) { - box->addButton(langFactory(lng_close), [box] { box->closeBox(); }); - })); + ParticipantsBoxController::Start(channel, ParticipantsBoxController::Role::Restricted); } } diff --git a/Telegram/SourceFiles/profile/profile_block_settings.h b/Telegram/SourceFiles/profile/profile_block_settings.h index cb958f933..7058562d6 100644 --- a/Telegram/SourceFiles/profile/profile_block_settings.h +++ b/Telegram/SourceFiles/profile/profile_block_settings.h @@ -46,7 +46,7 @@ protected: private slots: void onNotificationsChange(); void onManageAdmins(); - void onManageBlockedUsers(); + void onManageBannedUsers(); void onManageRestrictedUsers(); void onInviteLink(); @@ -57,7 +57,7 @@ private: void refreshButtons(); void refreshEnableNotifications(); void refreshManageAdminsButton(); - void refreshManageBlockedUsersButton(); + void refreshManageBannedUsersButton(); void refreshInviteLinkButton(); object_ptr _enableNotifications; @@ -65,7 +65,7 @@ private: // In groups: creator of non-deactivated groups can see this link. // In channels: creator of supergroup can see this link. object_ptr _manageAdmins = { nullptr }; - object_ptr _manageBlockedUsers = { nullptr }; + object_ptr _manageBannedUsers = { nullptr }; object_ptr _manageRestrictedUsers = { nullptr }; object_ptr _inviteLink = { nullptr }; diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index fe65b30ee..1edb09bc9 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -751,14 +751,14 @@ void ChannelData::setAdminsCount(int newAdminsCount) { void ChannelData::setRestrictedCount(int newRestrictedCount) { if (_restrictedCount != newRestrictedCount) { _restrictedCount = newRestrictedCount; - Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::BlockedUsersChanged); + Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::BannedUsersChanged); } } void ChannelData::setKickedCount(int newKickedCount) { if (_kickedCount != newKickedCount) { _kickedCount = newKickedCount; - Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::BlockedUsersChanged); + Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::BannedUsersChanged); } } @@ -810,7 +810,7 @@ void ChannelData::applyEditAdmin(gsl::not_null user, const MTPChannel } void ChannelData::applyEditBanned(gsl::not_null user, const MTPChannelBannedRights &rights) { - auto flags = Notify::PeerUpdate::Flag::BlockedUsersChanged | Notify::PeerUpdate::Flag::None; + auto flags = Notify::PeerUpdate::Flag::BannedUsersChanged | Notify::PeerUpdate::Flag::None; if (mgInfo) { if (mgInfo->lastAdmins.contains(user)) { // If rights are empty - still remove admin? TODO check mgInfo->lastAdmins.remove(user); @@ -922,7 +922,7 @@ void ChannelData::setAdminRights(const MTPChannelAdminRights &rights) { mgInfo->lastAdmins.remove(App::self()); } } - Notify::peerUpdatedDelayed(this, UpdateFlag::ChannelRightsChanged | UpdateFlag::AdminsChanged | UpdateFlag::BlockedUsersChanged); + Notify::peerUpdatedDelayed(this, UpdateFlag::ChannelRightsChanged | UpdateFlag::AdminsChanged | UpdateFlag::BannedUsersChanged); } void ChannelData::setRestrictedRights(const MTPChannelBannedRights &rights) { @@ -942,7 +942,7 @@ void ChannelData::setRestrictedRights(const MTPChannelBannedRights &rights) { mgInfo->lastRestricted.remove(App::self()); } } - Notify::peerUpdatedDelayed(this, UpdateFlag::ChannelRightsChanged | UpdateFlag::AdminsChanged | UpdateFlag::BlockedUsersChanged); + Notify::peerUpdatedDelayed(this, UpdateFlag::ChannelRightsChanged | UpdateFlag::AdminsChanged | UpdateFlag::BannedUsersChanged); } uint64 PtsWaiter::ptsKey(PtsSkippedQueue queue) {