diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 33ecc62c5..4801cce00 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -728,17 +728,17 @@ void ApiWrap::requestSelfParticipant(ChannelData *channel) { _selfParticipantRequests.insert(channel, requestId); } -void ApiWrap::kickParticipant(PeerData *peer, UserData *user) { +void ApiWrap::kickParticipant(PeerData *peer, UserData *user, const MTPChannelBannedRights ¤tRights) { auto kick = KickRequest(peer, user); if (_kickRequests.contains(kick)) return; if (auto channel = peer->asChannel()) { auto rights = ChannelData::KickedRestrictedRights(); - auto requestId = request(MTPchannels_EditBanned(channel->inputChannel, user->inputUser, rights)).done([this, channel, user, rights](const MTPUpdates &result) { + auto requestId = request(MTPchannels_EditBanned(channel->inputChannel, user->inputUser, rights)).done([this, channel, user, currentRights, rights](const MTPUpdates &result) { applyUpdates(result); _kickRequests.remove(KickRequest(channel, user)); - channel->applyEditBanned(user, rights); + channel->applyEditBanned(user, currentRights, rights); }).fail([this, kick](const RPCError &error) { _kickRequests.remove(kick); }).send(); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 1b9c4d79e..de4c2710c 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -59,7 +59,7 @@ public: void processFullPeer(UserData *user, const MTPUserFull &result); void requestSelfParticipant(ChannelData *channel); - void kickParticipant(PeerData *peer, UserData *user); + void kickParticipant(PeerData *peer, UserData *user, const MTPChannelBannedRights ¤tRights); void unblockParticipant(PeerData *peer, UserData *user); void requestWebPageDelayed(WebPageData *page); diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 897b0c80e..f0c14e80a 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -531,7 +531,7 @@ void DeleteMessagesBox::deleteAndClear() { if (_moderateFrom) { if (_banUser && _banUser->checked()) { - App::api()->kickParticipant(_moderateInChannel, _moderateFrom); + App::api()->kickParticipant(_moderateInChannel, _moderateFrom, MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); } if (_reportSpam->checked()) { MTP::send(MTPchannels_ReportSpam(_moderateInChannel->inputChannel, _moderateFrom->inputUser, MTP_vector(1, MTP_int(_ids[0].msg)))); diff --git a/Telegram/SourceFiles/boxes/contacts_box.cpp b/Telegram/SourceFiles/boxes/contacts_box.cpp index edcd1e1ce..6d866a32f 100644 --- a/Telegram/SourceFiles/boxes/contacts_box.cpp +++ b/Telegram/SourceFiles/boxes/contacts_box.cpp @@ -745,37 +745,6 @@ void ContactsBox::Inner::onAllAdminsChanged() { update(); } -void ContactsBox::Inner::addAdminDone(MTPChannelAdminRights rights, const MTPUpdates &result, mtpRequestId req) { - if (App::main()) App::main()->sentUpdatesReceived(result); - if (req != _addAdminRequestId) return; - - _addAdminRequestId = 0; - if (_addAdmin && _channel) { - _channel->applyEditAdmin(_addAdmin, rights); - } - if (_addAdminBox) _addAdminBox->closeBox(); - emit adminAdded(); -} - -bool ContactsBox::Inner::addAdminFail(const RPCError &error, mtpRequestId req) { - if (MTP::isDefaultHandledError(error)) return false; - - if (req != _addAdminRequestId) return true; - - _addAdminRequestId = 0; - if (_addAdminBox) _addAdminBox->closeBox(); - if (error.type() == "USERS_TOO_MUCH") { - Ui::show(Box(_channel->inviteLink()), KeepOtherLayers); - } else if (error.type() == "ADMINS_TOO_MUCH") { - Ui::show(Box(lang(lng_channel_admins_too_much)), KeepOtherLayers); - } else if (error.type() == qstr("USER_RESTRICTED")) { - Ui::show(Box(lang(lng_cant_do_this)), KeepOtherLayers); - } else { - emit adminAdded(); - } - return true; -} - void ContactsBox::Inner::saving(bool flag) { _saving = flag; _allAdminsChecked = _allAdmins->checked(); @@ -1409,7 +1378,7 @@ void ContactsBox::Inner::chooseParticipant() { changeMultiSelectCheckState(); } else { if (_channel && _membersFilter == MembersFilter::Admins) { - addSelectedAsChannelAdmin(); + Unexpected("Not supported any more"); } else if (sharingBotGame()) { shareBotGameToSelected(); } else if (bot()) { @@ -1422,70 +1391,6 @@ void ContactsBox::Inner::chooseParticipant() { update(); } -void ContactsBox::Inner::addSelectedAsChannelAdmin() { - auto peer = selectedPeer(); - if (!peer) { - return; - } - - _addAdmin = peer->asUser(); - t_assert(_addAdmin != nullptr); - - if (_addAdminRequestId) { - MTP::cancel(_addAdminRequestId); - _addAdminRequestId = 0; - } - if (_addAdminBox) _addAdminBox->deleteLater(); - - auto showBox = [this](auto &¤tRights, bool hasAdminRights) { - _addAdminBox = Ui::show(Box(_channel, _addAdmin, hasAdminRights, currentRights, base::lambda_guarded(this, [this](const MTPChannelAdminRights &rights) { - if (_addAdminRequestId) return; - _addAdminRequestId = MTP::send(MTPchannels_EditAdmin(_channel->inputChannel, _addAdmin->inputUser, rights), rpcDone(&Inner::addAdminDone, rights), rpcFail(&Inner::addAdminFail)); - })), KeepOtherLayers); - }; - - auto loadedRights = [this]() -> const MegagroupInfo::Admin * { - if (_channel->isMegagroup()) { - auto it = _channel->mgInfo->lastAdmins.constFind(_addAdmin); - if (it != _channel->mgInfo->lastAdmins.cend()) { - return &it.value(); - } - } - return nullptr; - }; - - if (auto rights = loadedRights()) { - if (rights->canEdit) { - showBox(rights->rights, true); - } else { - Ui::show(Box(lang(lng_error_cant_edit_admin)), KeepOtherLayers); - } - } else { - // We don't have current rights yet. - _addAdminRequestId = MTP::send(MTPchannels_GetParticipant(_channel->inputChannel, _addAdmin->inputUser), ::rpcDone(base::lambda_guarded(this, [this, showBox](const MTPchannels_ChannelParticipant &result) { - Expects(result.type() == mtpc_channels_channelParticipant); - auto &participant = result.c_channels_channelParticipant(); - App::feedUsers(participant.vusers); - _addAdminRequestId = 0; - if (participant.vparticipant.type() == mtpc_channelParticipantAdmin) { - if (participant.vparticipant.c_channelParticipantAdmin().is_can_edit()) { - showBox(participant.vparticipant.c_channelParticipantAdmin().vadmin_rights, true); - } else { - Ui::show(Box(lang(lng_error_cant_edit_admin)), KeepOtherLayers); - } - } else { - showBox(EditAdminBox::DefaultRights(_channel), false); - } - })), ::rpcFail(base::lambda_guarded(this, [this](const RPCError &error) { - if (MTP::isDefaultHandledError(error)) { - return false; - } - _addAdminRequestId = 0; - return true; - }))); - } -} - void ContactsBox::Inner::shareBotGameToSelected() { _addToPeer = selectedPeer(); if (!_addToPeer) { diff --git a/Telegram/SourceFiles/boxes/contacts_box.h b/Telegram/SourceFiles/boxes/contacts_box.h index f36078de6..856c0819d 100644 --- a/Telegram/SourceFiles/boxes/contacts_box.h +++ b/Telegram/SourceFiles/boxes/contacts_box.h @@ -25,8 +25,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "ui/effects/round_checkbox.h" #include "boxes/members_box.h" -class EditAdminBox; - namespace Dialogs { class Row; class IndexedList; @@ -252,8 +250,6 @@ private: void updateSelectedRow(); int getRowTopWithPeer(PeerData *peer) const; void updateRowWithPeer(PeerData *peer); - void addAdminDone(MTPChannelAdminRights rights, const MTPUpdates &result, mtpRequestId req); - bool addAdminFail(const RPCError &error, mtpRequestId req); void paintDialog(Painter &p, TimeMs ms, PeerData *peer, ContactData *data, bool sel); void paintDisabledCheckUserpic(Painter &p, PeerData *peer, int x, int y, int outerWidth) const; @@ -274,7 +270,6 @@ private: return (_chat != nullptr) || (_creating != CreatingGroupNone && (!_channel || _membersFilter != MembersFilter::Admins)); } void changeMultiSelectCheckState(); - void addSelectedAsChannelAdmin(); void shareBotGameToSelected(); void addBotToSelectedGroup(); @@ -299,9 +294,6 @@ private: base::lambda _allAdminsChangedCallback; PeerData *_addToPeer = nullptr; - UserData *_addAdmin = nullptr; - mtpRequestId _addAdminRequestId = 0; - QPointer _addAdminBox; int32 _time; diff --git a/Telegram/SourceFiles/boxes/edit_participant_box.cpp b/Telegram/SourceFiles/boxes/edit_participant_box.cpp index 402450f45..38cd4c295 100644 --- a/Telegram/SourceFiles/boxes/edit_participant_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_participant_box.cpp @@ -163,8 +163,8 @@ void EditParticipantBox::resizeToContent() { setDimensions(_inner->width(), _inner->height()); } -EditAdminBox::EditAdminBox(QWidget*, gsl::not_null channel, gsl::not_null user, bool hasAdminRights, const MTPChannelAdminRights &rights, base::lambda callback) : EditParticipantBox(nullptr, channel, user, hasAdminRights) -, _rights(rights) +EditAdminBox::EditAdminBox(QWidget*, gsl::not_null channel, gsl::not_null user, const MTPChannelAdminRights &rights, base::lambda callback) : EditParticipantBox(nullptr, channel, user, (rights.c_channelAdminRights().vflags.v != 0)) +, _oldRights(rights) , _saveCallback(std::move(callback)) { auto dependency = [this](Flag dependent, Flag dependency) { _dependencies.push_back(std::make_pair(dependent, dependency)); @@ -176,7 +176,7 @@ EditAdminBox::EditAdminBox(QWidget*, gsl::not_null channel, gsl::n MTPChannelAdminRights EditAdminBox::DefaultRights(gsl::not_null channel) { auto defaultRights = channel->isMegagroup() ? (Flag::f_change_info | Flag::f_delete_messages | Flag::f_ban_users | Flag::f_invite_users | Flag::f_invite_link | Flag::f_pin_messages) - : (Flag::f_change_info | Flag::f_post_messages | Flag::f_edit_messages | Flag::f_delete_messages); + : (Flag::f_change_info | Flag::f_post_messages | Flag::f_edit_messages | Flag::f_delete_messages | Flag::f_invite_users | Flag::f_invite_link); return MTP_channelAdminRights(MTP_flags(defaultRights)); } @@ -187,13 +187,14 @@ void EditAdminBox::prepare() { addControl(object_ptr(this, lang(lng_rights_edit_admin_header), Ui::FlatLabel::InitType::Simple, st::boxLabel)); - auto addCheckbox = [this](Flags flags, const QString &text) { + auto prepareRights = (_oldRights.c_channelAdminRights().vflags.v ? _oldRights : DefaultRights(channel())); + auto addCheckbox = [this, &prepareRights](Flags flags, const QString &text) { if (!channel()->amCreator()) { if (!(channel()->adminRights().vflags.v & flags)) { return; // Don't add options that we don't have ourselves. } } - auto checked = (_rights.c_channelAdminRights().vflags.v & flags) != 0; + auto checked = (prepareRights.c_channelAdminRights().vflags.v & flags) != 0; auto control = addControl(object_ptr(this, text, checked, st::defaultBoxCheckbox)); connect(control, &Ui::Checkbox::changed, this, [this, control] { applyDependencies(control); @@ -242,7 +243,7 @@ void EditAdminBox::prepare() { // Leave only rights that we have so we could save them. newFlags &= channel()->adminRights().vflags.v; } - _saveCallback(MTP_channelAdminRights(MTP_flags(newFlags))); + _saveCallback(_oldRights, MTP_channelAdminRights(MTP_flags(newFlags))); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); @@ -266,9 +267,8 @@ void EditAdminBox::refreshAboutAddAdminsText() { resizeToContent(); } -EditRestrictedBox::EditRestrictedBox(QWidget*, gsl::not_null channel, gsl::not_null user, bool hasAdminRights, const MTPChannelBannedRights &rights, base::lambda callback) : EditParticipantBox(nullptr, channel, user, hasAdminRights) -, _rights(rights) -, _until(rights.c_channelBannedRights().vuntil_date.v) +EditRestrictedBox::EditRestrictedBox(QWidget*, gsl::not_null channel, gsl::not_null user, bool hasAdminRights, const MTPChannelBannedRights &rights, base::lambda callback) : EditParticipantBox(nullptr, channel, user, hasAdminRights) +, _oldRights(rights) , _saveCallback(std::move(callback)) { auto dependency = [this](Flag dependent, Flag dependency) { _dependencies.push_back(std::make_pair(dependent, dependency)); @@ -292,8 +292,11 @@ void EditRestrictedBox::prepare() { addControl(object_ptr(this, lang(lng_rights_user_restrictions_header), Ui::FlatLabel::InitType::Simple, st::boxLabel)); - auto addCheckbox = [this](Flags flags, const QString &text) { - auto checked = (_rights.c_channelBannedRights().vflags.v & flags) == 0; + auto prepareRights = (_oldRights.c_channelBannedRights().vflags.v ? _oldRights : DefaultRights(channel())); + _until = prepareRights.c_channelBannedRights().vuntil_date.v; + + auto addCheckbox = [this, &prepareRights](Flags flags, const QString &text) { + auto checked = (prepareRights.c_channelBannedRights().vflags.v & flags) == 0; auto control = addControl(object_ptr(this, text, checked, st::defaultBoxCheckbox)); connect(control, &Ui::Checkbox::changed, this, [this, control] { applyDependencies(control); @@ -324,7 +327,7 @@ void EditRestrictedBox::prepare() { newFlags |= checkbox.first; } } - _saveCallback(MTP_channelBannedRights(MTP_flags(newFlags), MTP_int(_until))); + _saveCallback(_oldRights, MTP_channelBannedRights(MTP_flags(newFlags), MTP_int(_until))); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); diff --git a/Telegram/SourceFiles/boxes/edit_participant_box.h b/Telegram/SourceFiles/boxes/edit_participant_box.h index 5469dd6e5..637f16ac8 100644 --- a/Telegram/SourceFiles/boxes/edit_participant_box.h +++ b/Telegram/SourceFiles/boxes/edit_participant_box.h @@ -65,9 +65,7 @@ private: class EditAdminBox : public EditParticipantBox { public: - EditAdminBox(QWidget*, gsl::not_null channel, gsl::not_null user, bool hasAdminRights, const MTPChannelAdminRights &rights, base::lambda callback); - - static MTPChannelAdminRights DefaultRights(gsl::not_null channel); + EditAdminBox(QWidget*, gsl::not_null channel, gsl::not_null user, const MTPChannelAdminRights &rights, base::lambda callback); protected: void prepare() override; @@ -76,12 +74,14 @@ private: using Flag = MTPDchannelAdminRights::Flag; using Flags = MTPDchannelAdminRights::Flags; + static MTPChannelAdminRights DefaultRights(gsl::not_null channel); + void applyDependencies(QPointer changed); void refreshAboutAddAdminsText(); - MTPChannelAdminRights _rights; + const MTPChannelAdminRights _oldRights; std::vector> _dependencies; - base::lambda _saveCallback; + base::lambda _saveCallback; std::map> _checkboxes; QPointer _aboutAddAdmins; @@ -93,9 +93,7 @@ private: class EditRestrictedBox : public EditParticipantBox { public: - EditRestrictedBox(QWidget*, gsl::not_null channel, gsl::not_null user, bool hasAdminRights, const MTPChannelBannedRights &rights, base::lambda callback); - - static MTPChannelBannedRights DefaultRights(gsl::not_null channel); + EditRestrictedBox(QWidget*, gsl::not_null channel, gsl::not_null user, bool hasAdminRights, const MTPChannelBannedRights &rights, base::lambda callback); protected: void prepare() override; @@ -104,6 +102,8 @@ private: using Flag = MTPDchannelBannedRights::Flag; using Flags = MTPDchannelBannedRights::Flags; + static MTPChannelBannedRights DefaultRights(gsl::not_null channel); + void applyDependencies(QPointer changed); void showRestrictUntil(); void setRestrictUntil(int32 until); @@ -111,10 +111,10 @@ private: return ChannelData::IsRestrictedForever(_until); } - MTPChannelBannedRights _rights; + const MTPChannelBannedRights _oldRights; int32 _until = 0; std::vector> _dependencies; - base::lambda _saveCallback; + base::lambda _saveCallback; std::map> _checkboxes; QPointer _restrictUntil; diff --git a/Telegram/SourceFiles/boxes/members_box.cpp b/Telegram/SourceFiles/boxes/members_box.cpp index 6fd31bee7..33587ad1d 100644 --- a/Telegram/SourceFiles/boxes/members_box.cpp +++ b/Telegram/SourceFiles/boxes/members_box.cpp @@ -281,25 +281,33 @@ void MembersBox::Inner::actionPressed(Member &row) { })), KeepOtherLayers); } else { auto currentRights = _rows[_kickSelected].adminRights; - auto hasAdminRights = true; - _kickBox = Ui::show(Box(_channel, user, hasAdminRights, currentRights, base::lambda_guarded(this, [this, user](const MTPChannelAdminRights &rights) { - if (_kickBox) _kickBox->closeBox(); - MTP::send(MTPchannels_EditAdmin(_channel->inputChannel, user->inputUser, rights), ::rpcDone(base::lambda_guarded(this, [this, user, rights](const MTPUpdates &result, mtpRequestId req) { + auto weak = QPointer(this); + auto box = std::make_shared>(nullptr); + _kickBox = *box = Ui::show(Box(_channel, user, currentRights, [channel = _channel, weak, user, box](const MTPChannelAdminRights &oldRights, const MTPChannelAdminRights &newRights) { + if (*box) { + (*box)->closeBox(); + } + MTP::send(MTPchannels_EditAdmin(channel->inputChannel, user->inputUser, newRights), ::rpcDone([channel, weak, user, oldRights, newRights](const MTPUpdates &result, mtpRequestId req) { if (App::main()) App::main()->sentUpdatesReceived(result); - _channel->applyEditAdmin(user, rights); - if (rights.c_channelAdminRights().vflags.v == 0) { - removeKicked(user); - } else { - auto it = std::find_if(_rows.begin(), _rows.end(), [this, user](auto &&row) { - return (row.user == user); - }); - if (it != _rows.end()) { - it->adminRights = rights; - } + channel->applyEditAdmin(user, oldRights, newRights); + if (weak) { + weak->editAdminDone(user, newRights); } - if (_kickBox) _kickBox->closeBox(); - })), rpcFail(&Inner::kickFail)); - })), KeepOtherLayers); + }), weak ? weak->rpcFail(&Inner::kickFail) : RPCFailHandlerPtr()); + }), KeepOtherLayers); + } +} + +void MembersBox::Inner::editAdminDone(gsl::not_null user, const MTPChannelAdminRights &rights) { + if (rights.c_channelAdminRights().vflags.v == 0) { + removeKicked(user); + } else { + auto it = std::find_if(_rows.begin(), _rows.end(), [this, user](auto &&row) { + return (row.user == user); + }); + if (it != _rows.end()) { + it->adminRights = rights; + } } } diff --git a/Telegram/SourceFiles/boxes/members_box.h b/Telegram/SourceFiles/boxes/members_box.h index 4455f2a28..f0b9d5774 100644 --- a/Telegram/SourceFiles/boxes/members_box.h +++ b/Telegram/SourceFiles/boxes/members_box.h @@ -155,6 +155,7 @@ private: void setPressed(int pressed); void chooseParticipant(); void actionPressed(Member &row); + void editAdminDone(gsl::not_null user, const MTPChannelAdminRights &rights); void updateSelection(); void loadProfilePhotos(); diff --git a/Telegram/SourceFiles/history/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/history_admin_log_inner.cpp index 49e537fde..271044523 100644 --- a/Telegram/SourceFiles/history/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/history_admin_log_inner.cpp @@ -1021,9 +1021,9 @@ void InnerWidget::suggestRestrictUser(gsl::not_null user) { auto editRestrictions = [user, this](bool hasAdminRights, const MTPChannelBannedRights ¤tRights) { auto weak = QPointer(this); auto box = std::make_shared>(); - *box = Ui::show(Box(_channel, user, hasAdminRights, currentRights, [user, weak, box](const MTPChannelBannedRights &rights) { + *box = Ui::show(Box(_channel, user, hasAdminRights, currentRights, [user, weak, box](const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights) { if (weak) { - weak->restrictUser(user, rights); + weak->restrictUser(user, oldRights, newRights); } if (*box) { (*box)->closeBox(); @@ -1031,7 +1031,7 @@ void InnerWidget::suggestRestrictUser(gsl::not_null user) { }), KeepOtherLayers); }; if (base::contains(_admins, user)) { - editRestrictions(true, EditRestrictedBox::DefaultRights(_channel)); + editRestrictions(true, MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); } else { request(MTPchannels_GetParticipant(_channel->inputChannel, user->inputUser)).done([this, editRestrictions](const MTPchannels_ChannelParticipant &result) { Expects(result.type() == mtpc_channels_channelParticipant); @@ -1042,22 +1042,22 @@ void InnerWidget::suggestRestrictUser(gsl::not_null user) { editRestrictions(false, participant.vparticipant.c_channelParticipantBanned().vbanned_rights); } else { auto hasAdminRights = (type == mtpc_channelParticipantAdmin || type == mtpc_channelParticipantCreator); - editRestrictions(hasAdminRights, EditRestrictedBox::DefaultRights(_channel)); + editRestrictions(hasAdminRights, MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); } }).fail([this, editRestrictions](const RPCError &error) { - editRestrictions(false, EditRestrictedBox::DefaultRights(_channel)); + editRestrictions(false, MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); }).send(); } }); } -void InnerWidget::restrictUser(gsl::not_null user, const MTPChannelBannedRights &rights) { +void InnerWidget::restrictUser(gsl::not_null user, const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights) { auto weak = QPointer(this); - MTP::send(MTPchannels_EditBanned(_channel->inputChannel, user->inputUser, rights), rpcDone([megagroup = _channel.get(), user, weak, rights](const MTPUpdates &result) { + MTP::send(MTPchannels_EditBanned(_channel->inputChannel, user->inputUser, newRights), rpcDone([megagroup = _channel.get(), user, weak, oldRights, newRights](const MTPUpdates &result) { AuthSession::Current().api().applyUpdates(result); - megagroup->applyEditBanned(user, rights); + megagroup->applyEditBanned(user, oldRights, newRights); if (weak) { - weak->restrictUserDone(user, rights); + weak->restrictUserDone(user, newRights); } })); } diff --git a/Telegram/SourceFiles/history/history_admin_log_inner.h b/Telegram/SourceFiles/history/history_admin_log_inner.h index 3600a6ef3..b79cf2bc8 100644 --- a/Telegram/SourceFiles/history/history_admin_log_inner.h +++ b/Telegram/SourceFiles/history/history_admin_log_inner.h @@ -130,7 +130,7 @@ private: TextWithEntities getSelectedText() const; void setToClipboard(const TextWithEntities &forClipboard, QClipboard::Mode mode = QClipboard::Clipboard); void suggestRestrictUser(gsl::not_null user); - void restrictUser(gsl::not_null user, const MTPChannelBannedRights &rights); + void restrictUser(gsl::not_null user, const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights); void restrictUserDone(gsl::not_null user, const MTPChannelBannedRights &rights); void requestAdmins(); diff --git a/Telegram/SourceFiles/profile/profile_block_group_members.cpp b/Telegram/SourceFiles/profile/profile_block_group_members.cpp index 144e8d2d0..d7303f2df 100644 --- a/Telegram/SourceFiles/profile/profile_block_group_members.cpp +++ b/Telegram/SourceFiles/profile/profile_block_group_members.cpp @@ -72,17 +72,17 @@ void GroupMembersWidget::editAdmin(gsl::not_null user) { if (!megagroup) { return; // not supported } - auto defaultAdmin = MegagroupInfo::Admin { EditAdminBox::DefaultRights(megagroup) }; auto currentRightsIt = megagroup->mgInfo->lastAdmins.find(user); auto hasAdminRights = (currentRightsIt != megagroup->mgInfo->lastAdmins.cend()); - auto currentRights = hasAdminRights ? currentRightsIt->rights : EditAdminBox::DefaultRights(megagroup); - Ui::show(Box(megagroup, user, hasAdminRights, currentRights, base::lambda_guarded(this, [this, megagroup, user](const MTPChannelAdminRights &rights) { + auto currentRights = hasAdminRights ? currentRightsIt->rights : MTP_channelAdminRights(MTP_flags(0)); + auto weak = QPointer(this); + Ui::show(Box(megagroup, user, currentRights, [weak, megagroup, user](const MTPChannelAdminRights &oldRights, const MTPChannelAdminRights &newRights) { Ui::hideLayer(); - MTP::send(MTPchannels_EditAdmin(megagroup->inputChannel, user->inputUser, rights), rpcDone(base::lambda_guarded(this, [this, megagroup, user, rights](const MTPUpdates &result) { + MTP::send(MTPchannels_EditAdmin(megagroup->inputChannel, user->inputUser, newRights), rpcDone([weak, megagroup, user, oldRights, newRights](const MTPUpdates &result) { if (App::main()) App::main()->sentUpdatesReceived(result); - megagroup->applyEditAdmin(user, rights); - }))); - }))); + megagroup->applyEditAdmin(user, oldRights, newRights); + })); + })); } void GroupMembersWidget::restrictUser(gsl::not_null user) { @@ -90,14 +90,14 @@ void GroupMembersWidget::restrictUser(gsl::not_null user) { if (!megagroup) { return; // not supported } - auto defaultRestricted = MegagroupInfo::Restricted { EditRestrictedBox::DefaultRights(megagroup) }; + auto defaultRestricted = MegagroupInfo::Restricted { MTP_channelBannedRights(MTP_flags(0), MTP_int(0)) }; auto currentRights = megagroup->mgInfo->lastRestricted.value(user, defaultRestricted).rights; auto hasAdminRights = megagroup->mgInfo->lastAdmins.find(user) != megagroup->mgInfo->lastAdmins.cend(); - Ui::show(Box(megagroup, user, hasAdminRights, currentRights, [megagroup, user](const MTPChannelBannedRights &rights) { + Ui::show(Box(megagroup, user, hasAdminRights, currentRights, [megagroup, user](const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights) { Ui::hideLayer(); - MTP::send(MTPchannels_EditBanned(megagroup->inputChannel, user->inputUser, rights), rpcDone([megagroup, user, rights](const MTPUpdates &result) { + MTP::send(MTPchannels_EditBanned(megagroup->inputChannel, user->inputUser, newRights), rpcDone([megagroup, user, oldRights, newRights](const MTPUpdates &result) { if (App::main()) App::main()->sentUpdatesReceived(result); - megagroup->applyEditBanned(user, rights); + megagroup->applyEditBanned(user, oldRights, newRights); })); })); } @@ -106,12 +106,19 @@ void GroupMembersWidget::removePeer(PeerData *selectedPeer) { auto user = selectedPeer->asUser(); t_assert(user != nullptr); auto text = lng_profile_sure_kick(lt_user, user->firstName); - Ui::show(Box(text, lang(lng_box_remove), base::lambda_guarded(this, [user, peer = peer()] { + auto currentRestrictedRights = MTP_channelBannedRights(MTP_flags(0), MTP_int(0)); + if (auto channel = peer()->asMegagroup()) { + auto it = channel->mgInfo->lastRestricted.find(user); + if (it != channel->mgInfo->lastRestricted.cend()) { + currentRestrictedRights = it->rights; + } + } + Ui::show(Box(text, lang(lng_box_remove), base::lambda_guarded(this, [user, currentRestrictedRights, peer = peer()] { Ui::hideLayer(); if (auto chat = peer->asChat()) { if (App::main()) App::main()->kickParticipant(chat, user); } else if (auto channel = peer->asChannel()) { - if (App::api()) App::api()->kickParticipant(channel, user); + if (App::api()) App::api()->kickParticipant(channel, user, currentRestrictedRights); } }))); } diff --git a/Telegram/SourceFiles/profile/profile_channel_controllers.cpp b/Telegram/SourceFiles/profile/profile_channel_controllers.cpp index fb6b112d3..32e7f840b 100644 --- a/Telegram/SourceFiles/profile/profile_channel_controllers.cpp +++ b/Telegram/SourceFiles/profile/profile_channel_controllers.cpp @@ -230,25 +230,12 @@ void ParticipantsBoxController::editAdmin(gsl::not_null user) { auto it = _additional.adminRights.find(user); t_assert(it != _additional.adminRights.cend()); auto weak = base::weak_unique_ptr(this); - auto hasAdminRights = true; - _editBox = Ui::show(Box(_channel, user, hasAdminRights, it->second, [channel = _channel.get(), user, hasAdminRights, weak](const MTPChannelAdminRights &rights) { - MTP::send(MTPchannels_EditAdmin(channel->inputChannel, user->inputUser, rights), rpcDone([channel, user, hasAdminRights, weak, rights](const MTPUpdates &result) { + _editBox = Ui::show(Box(_channel, user, it->second, [channel = _channel.get(), user, weak](const MTPChannelAdminRights &oldRights, const MTPChannelAdminRights &newRights) { + MTP::send(MTPchannels_EditAdmin(channel->inputChannel, user->inputUser, newRights), rpcDone([channel, user, weak, oldRights, newRights](const MTPUpdates &result) { AuthSession::Current().api().applyUpdates(result); - channel->applyEditAdmin(user, rights); - if (hasAdminRights && !rights.c_channelAdminRights().vflags.v) { - // We removed an admin. - if (channel->adminsCount() > 1) { - channel->setAdminsCount(channel->adminsCount() - 1); - if (App::main()) emit App::main()->peerUpdated(channel); - } - if (!channel->isMegagroup() && user->botInfo && channel->membersCount() > 1) { - // Removing bot admin removes it from channel. - channel->setMembersCount(channel->membersCount() - 1); - if (App::main()) emit App::main()->peerUpdated(channel); - } - } + channel->applyEditAdmin(user, oldRights, newRights); if (weak) { - weak->editAdminDone(user, rights); + weak->editAdminDone(user, newRights); } })); }), KeepOtherLayers); @@ -290,12 +277,12 @@ void ParticipantsBoxController::editRestricted(gsl::not_null user) { t_assert(it != _additional.restrictedRights.cend()); auto weak = base::weak_unique_ptr(this); auto hasAdminRights = false; - _editBox = Ui::show(Box(_channel, user, hasAdminRights, 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) { + _editBox = Ui::show(Box(_channel, user, hasAdminRights, it->second, [megagroup = _channel.get(), user, weak](const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights) { + MTP::send(MTPchannels_EditBanned(megagroup->inputChannel, user->inputUser, newRights), rpcDone([megagroup, user, weak, oldRights, newRights](const MTPUpdates &result) { AuthSession::Current().api().applyUpdates(result); - megagroup->applyEditBanned(user, rights); + megagroup->applyEditBanned(user, oldRights, newRights); if (weak) { - weak->editRestrictedDone(user, rights); + weak->editRestrictedDone(user, newRights); } })); }), KeepOtherLayers); @@ -630,15 +617,13 @@ void AddParticipantBoxController::editAdmin(gsl::not_null user, bool // Check restrictions. auto weak = base::weak_unique_ptr(this); auto alreadyIt = _additional.adminRights.find(user); - auto hasAdminRights = false; - auto currentRights = EditAdminBox::DefaultRights(_channel); + auto currentRights = MTP_channelAdminRights(MTP_flags(0)); 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; } - hasAdminRights = true; currentRights = alreadyIt->second; } else if (_additional.kicked.find(user) != _additional.kicked.end()) { // The user is banned. @@ -693,24 +678,12 @@ void AddParticipantBoxController::editAdmin(gsl::not_null user, bool } // Finally edit the admin. - _editBox = Ui::show(Box(_channel, user, hasAdminRights, currentRights, [channel = _channel.get(), user, hasAdminRights, weak](const MTPChannelAdminRights &rights) { - MTP::send(MTPchannels_EditAdmin(channel->inputChannel, user->inputUser, rights), rpcDone([channel, user, hasAdminRights, weak, rights](const MTPUpdates &result) { + _editBox = Ui::show(Box(_channel, user, currentRights, [channel = _channel.get(), user, weak](const MTPChannelAdminRights &oldRights, const MTPChannelAdminRights &newRights) { + MTP::send(MTPchannels_EditAdmin(channel->inputChannel, user->inputUser, newRights), rpcDone([channel, user, weak, oldRights, newRights](const MTPUpdates &result) { AuthSession::Current().api().applyUpdates(result); - channel->applyEditAdmin(user, rights); - if (hasAdminRights && !rights.c_channelAdminRights().vflags.v) { - // We removed an admin. - if (channel->adminsCount() > 1) { - channel->setAdminsCount(channel->adminsCount() - 1); - if (App::main()) emit App::main()->peerUpdated(channel); - } - if (!channel->isMegagroup() && user->botInfo && channel->membersCount() > 1) { - // Removing bot admin removes it from channel. - channel->setMembersCount(channel->membersCount() - 1); - if (App::main()) emit App::main()->peerUpdated(channel); - } - } + channel->applyEditAdmin(user, oldRights, newRights); if (weak) { - weak->editAdminDone(user, rights); + weak->editAdminDone(user, newRights); } }), rpcFail([channel](const RPCError &error) { if (MTP::isDefaultHandledError(error)) { @@ -759,7 +732,7 @@ void AddParticipantBoxController::editRestricted(gsl::not_null user, // Check restrictions. auto weak = base::weak_unique_ptr(this); auto alreadyIt = _additional.restrictedRights.find(user); - auto currentRights = EditRestrictedBox::DefaultRights(_channel); + auto currentRights = MTP_channelBannedRights(MTP_flags(0), MTP_int(0)); auto hasAdminRights = false; if (alreadyIt != _additional.restrictedRights.end()) { // The user is already banned or restricted. @@ -783,20 +756,20 @@ void AddParticipantBoxController::editRestricted(gsl::not_null user, } // Finally edit the restricted. - _editBox = Ui::show(Box(_channel, user, hasAdminRights, currentRights, [user, weak](const MTPChannelBannedRights &rights) { + _editBox = Ui::show(Box(_channel, user, hasAdminRights, currentRights, [user, weak](const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights) { if (weak) { - weak->restrictUserSure(user, rights); + weak->restrictUserSure(user, oldRights, newRights); } }), KeepOtherLayers); } -void AddParticipantBoxController::restrictUserSure(gsl::not_null user, const MTPChannelBannedRights &rights) { +void AddParticipantBoxController::restrictUserSure(gsl::not_null user, const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights) { 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) { + MTP::send(MTPchannels_EditBanned(_channel->inputChannel, user->inputUser, newRights), rpcDone([megagroup = _channel.get(), user, weak, oldRights, newRights](const MTPUpdates &result) { AuthSession::Current().api().applyUpdates(result); - megagroup->applyEditBanned(user, rights); + megagroup->applyEditBanned(user, oldRights, newRights); if (weak) { - weak->editRestrictedDone(user, rights); + weak->editRestrictedDone(user, newRights); } })); } @@ -856,7 +829,13 @@ void AddParticipantBoxController::kickUser(gsl::not_null user, bool s }), KeepOtherLayers); return; } - restrictUserSure(user, ChannelData::KickedRestrictedRights()); + auto currentRights = MTP_channelBannedRights(MTP_flags(0), MTP_int(0)); + auto alreadyIt = _additional.restrictedRights.find(user); + if (alreadyIt != _additional.restrictedRights.end()) { + // The user is already banned or restricted. + currentRights = alreadyIt->second; + } + restrictUserSure(user, currentRights, ChannelData::KickedRestrictedRights()); } bool AddParticipantBoxController::appendRow(gsl::not_null user) { diff --git a/Telegram/SourceFiles/profile/profile_channel_controllers.h b/Telegram/SourceFiles/profile/profile_channel_controllers.h index 3bec06769..365969c66 100644 --- a/Telegram/SourceFiles/profile/profile_channel_controllers.h +++ b/Telegram/SourceFiles/profile/profile_channel_controllers.h @@ -154,7 +154,7 @@ private: 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); + void restrictUserSure(gsl::not_null user, const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights); bool appendRow(gsl::not_null user); bool prependRow(gsl::not_null user); std::unique_ptr createRow(gsl::not_null user) const; diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 982e6327b..8c6b68df6 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -789,7 +789,7 @@ MTPChannelBannedRights ChannelData::KickedRestrictedRights() { return MTP_channelBannedRights(MTP_flags(flags), MTP_int(std::numeric_limits::max())); } -void ChannelData::applyEditAdmin(gsl::not_null user, const MTPChannelAdminRights &rights) { +void ChannelData::applyEditAdmin(gsl::not_null user, const MTPChannelAdminRights &oldRights, const MTPChannelAdminRights &newRights) { auto flags = Notify::PeerUpdate::Flag::AdminsChanged | Notify::PeerUpdate::Flag::None; if (mgInfo) { if (!mgInfo->lastParticipants.contains(user)) { // If rights are empty - still add participant? TODO check @@ -809,8 +809,8 @@ void ChannelData::applyEditAdmin(gsl::not_null user, const MTPChannel } } auto it = mgInfo->lastAdmins.find(user); - if (rights.c_channelAdminRights().vflags.v != 0) { - auto lastAdmin = MegagroupInfo::Admin { rights }; + if (newRights.c_channelAdminRights().vflags.v != 0) { + auto lastAdmin = MegagroupInfo::Admin { newRights }; lastAdmin.canEdit = true; if (it == mgInfo->lastAdmins.cend()) { mgInfo->lastAdmins.insert(user, lastAdmin); @@ -827,10 +827,27 @@ void ChannelData::applyEditAdmin(gsl::not_null user, const MTPChannel } } } + if (oldRights.c_channelAdminRights().vflags.v && !newRights.c_channelAdminRights().vflags.v) { + // We removed an admin. + if (adminsCount() > 1) { + setAdminsCount(adminsCount() - 1); + if (App::main()) emit App::main()->peerUpdated(this); + } + if (!isMegagroup() && user->botInfo && membersCount() > 1) { + // Removing bot admin removes it from channel. + setMembersCount(membersCount() - 1); + if (App::main()) emit App::main()->peerUpdated(this); + } + } else if (!oldRights.c_channelAdminRights().vflags.v && newRights.c_channelAdminRights().vflags.v) { + // We added an admin. + setAdminsCount(adminsCount() + 1); + if (App::main()) emit App::main()->peerUpdated(this); + updateFull(true); + } Notify::peerUpdatedDelayed(this, flags); } -void ChannelData::applyEditBanned(gsl::not_null user, const MTPChannelBannedRights &rights) { +void ChannelData::applyEditBanned(gsl::not_null user, const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights) { 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 @@ -841,15 +858,15 @@ void ChannelData::applyEditBanned(gsl::not_null user, const MTPChanne flags |= Notify::PeerUpdate::Flag::AdminsChanged; } } - auto isKicked = (rights.c_channelBannedRights().vflags.v & MTPDchannelBannedRights::Flag::f_view_messages); - auto isRestricted = !isKicked && (rights.c_channelBannedRights().vflags.v != 0); + auto isKicked = (newRights.c_channelBannedRights().vflags.v & MTPDchannelBannedRights::Flag::f_view_messages); + auto isRestricted = !isKicked && (newRights.c_channelBannedRights().vflags.v != 0); auto it = mgInfo->lastRestricted.find(user); if (isRestricted) { if (it == mgInfo->lastRestricted.cend()) { - mgInfo->lastRestricted.insert(user, MegagroupInfo::Restricted { rights }); + mgInfo->lastRestricted.insert(user, MegagroupInfo::Restricted { newRights }); setRestrictedCount(restrictedCount() + 1); } else { - it->rights = rights; + it->rights = newRights; } } else { if (it != mgInfo->lastRestricted.cend()) { diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 9a0284e9a..5fca12862 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -820,8 +820,8 @@ public: static bool IsRestrictedForever(TimeId until) { return !until || (until == kRestrictUntilForever); } - void applyEditAdmin(gsl::not_null user, const MTPChannelAdminRights &rights); - void applyEditBanned(gsl::not_null user, const MTPChannelBannedRights &rights); + void applyEditAdmin(gsl::not_null user, const MTPChannelAdminRights &oldRights, const MTPChannelAdminRights &newRights); + void applyEditBanned(gsl::not_null user, const MTPChannelBannedRights &oldRights, const MTPChannelBannedRights &newRights); int32 date = 0; int version = 0;