diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index f01ab6da4..2bc56a1b9 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1628,6 +1628,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_rights_edit_admin" = "Manage permissions"; "lng_rights_edit_admin_header" = "What can this admin do?"; +"lng_rights_edit_admin_rank_name" = "Custom admin badge (optional)"; +"lng_rights_edit_admin_rank_about" = "You can specify a custom badge that will be shown in all messages from this admin."; "lng_rights_about_add_admins_yes" = "This admin will be able to add new admins with the same (or more limited) permissions."; "lng_rights_about_add_admins_no" = "This admin will not be able to add new admins."; diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 78a1c6ccc..c91ea0fed 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -761,6 +761,7 @@ rightsHeaderLabel: FlatLabel(boxLabel) { textFg: windowActiveTextFg; } rightsUntilMargin: margins(0px, 8px, 0px, 20px); +rightsRankMargin: margins(0px, 8px, 0px, 2px); mutePhotoButton: UserpicButton(defaultUserpicButton) { size: size(40px, 40px); diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp index 196a803b4..ebf26c579 100644 --- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp @@ -583,7 +583,13 @@ void AddSpecialBoxController::editAdminDone( } const auto date = base::unixtime::now(); // Incorrect, but ignored. - if (rights.c_chatAdminRights().vflags().v == 0) { + if (_additional.isCreator(user) && user->isSelf()) { + using Flag = MTPDchannelParticipantCreator::Flag; + _additional.applyParticipant(MTP_channelParticipantCreator( + MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank), + MTP_int(user->bareId()), + MTP_string(rank))); + } else if (rights.c_chatAdminRights().vflags().v == 0) { _additional.applyParticipant(MTP_channelParticipant( MTP_int(user->bareId()), MTP_int(date))); diff --git a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp index 59a811a1e..7cca5cba8 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp @@ -43,6 +43,7 @@ namespace { constexpr auto kMaxRestrictDelayDays = 366; constexpr auto kSecondsInDay = 24 * 60 * 60; constexpr auto kSecondsInWeek = 7 * kSecondsInDay; +constexpr auto kAdminRoleLimit = 16; enum class PasswordErrorType { None, @@ -244,6 +245,15 @@ Widget *EditParticipantBox::addControl( return _inner->addControl(std::move(widget), margin); } +bool EditParticipantBox::amCreator() const { + if (const auto chat = _peer->asChat()) { + return chat->amCreator(); + } else if (const auto channel = _peer->asChannel()) { + return channel->amCreator(); + } + Unexpected("Peer type in EditParticipantBox::Inner::amCreator."); +} + EditAdminBox::EditAdminBox( QWidget*, not_null peer, @@ -306,7 +316,7 @@ void EditAdminBox::prepare() { const auto disabledMessages = [&] { auto result = std::map(); - if (!canSave()) { + if (!canSave() || (amCreator() && user()->isSelf())) { result.emplace( ~Flags(0), tr::lng_rights_about_admin_cant_edit(tr::now)); @@ -365,17 +375,11 @@ void EditAdminBox::prepare() { refreshAboutAddAdminsText(checked); }, lifetime()); - const auto rank = canSave() - ? addControl( - object_ptr( - this, - st::defaultInputField, - tr::lng_rights_edit_admin_header(), - _oldRank), - st::rightsAboutMargin) - : nullptr; - if (canSave()) { + const auto rank = (chat || channel->isMegagroup()) + ? addRankInput().get() + : nullptr; + addButton(tr::lng_settings_save(), [=, value = getChecked] { if (!_saveCallback) { return; @@ -387,14 +391,38 @@ void EditAdminBox::prepare() { _saveCallback( _oldRights, MTP_chatAdminRights(MTP_flags(newFlags)), - rank->getLastText().trimmed()); + rank ? rank->getLastText().trimmed() : QString()); }); - addButton(tr::lng_cancel(), [this] { closeBox(); }); + addButton(tr::lng_cancel(), [=] { closeBox(); }); } else { - addButton(tr::lng_box_ok(), [this] { closeBox(); }); + addButton(tr::lng_box_ok(), [=] { closeBox(); }); } } +not_null EditAdminBox::addRankInput() { + addControl( + object_ptr(this), + st::rightsRankMargin); + + const auto result = addControl( + object_ptr( + this, + st::defaultInputField, + tr::lng_rights_edit_admin_rank_name(), + _oldRank), + st::rightsAboutMargin); + result->setMaxLength(kAdminRoleLimit); + + addControl( + object_ptr( + this, + tr::lng_rights_edit_admin_rank_about(), + st::boxDividerLabel), + st::rightsAboutMargin); + + return result; +} + bool EditAdminBox::canTransferOwnership() const { if (user()->isInaccessible() || user()->isBot() || user()->isSelf()) { return false; @@ -583,7 +611,7 @@ void EditAdminBox::sendTransferRequestFrom( void EditAdminBox::refreshAboutAddAdminsText(bool canAddAdmins) { _aboutAddAdmins->setText([&] { - if (!canSave()) { + if (!canSave() || (amCreator() && user()->isSelf())) { return tr::lng_rights_about_admin_cant_edit(tr::now); } else if (canAddAdmins) { return tr::lng_rights_about_add_admins_yes(tr::now); diff --git a/Telegram/SourceFiles/boxes/peers/edit_participant_box.h b/Telegram/SourceFiles/boxes/peers/edit_participant_box.h index d433e2d9a..1804aae46 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participant_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_participant_box.h @@ -38,12 +38,13 @@ public: protected: void prepare() override; - not_null user() const { + [[nodiscard]] not_null user() const { return _user; } - not_null peer() const { + [[nodiscard]] not_null peer() const { return _peer; } + [[nodiscard]] bool amCreator() const; template Widget *addControl(object_ptr widget, QMargins margin = {}); @@ -88,6 +89,7 @@ private: static MTPChatAdminRights Defaults(not_null peer); + not_null addRankInput(); void transferOwnership(); void transferOwnershipChecked(); bool handleTransferPasswordError(const RPCError &error); diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp index eed3896b2..7737d3208 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp @@ -221,7 +221,7 @@ Fn user) const { - if (_creator == user || user->isSelf()) { - return false; - } else if (_creator && _creator->isSelf()) { + if (_creator && _creator->isSelf()) { return true; + } else if (_creator == user || user->isSelf()) { + return false; } else if (adminRights(user).has_value()) { return !_peer->isChat() && _adminCanEdit.contains(user); } @@ -1480,7 +1480,13 @@ void ParticipantsBoxController::editAdminDone( } const auto date = base::unixtime::now(); // Incorrect, but ignored. - if (rights.c_chatAdminRights().vflags().v == 0) { + if (_additional.isCreator(user) && user->isSelf()) { + using Flag = MTPDchannelParticipantCreator::Flag; + _additional.applyParticipant(MTP_channelParticipantCreator( + MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank), + MTP_int(user->bareId()), + MTP_string(rank))); + } else if (rights.c_chatAdminRights().vflags().v == 0) { _additional.applyParticipant(MTP_channelParticipant( MTP_int(user->bareId()), MTP_int(date)));