diff --git a/Telegram/Resources/icons/info/edit/group_manage_permissions.png b/Telegram/Resources/icons/info/edit/group_manage_permissions.png new file mode 100644 index 000000000..bcf7f4567 Binary files /dev/null and b/Telegram/Resources/icons/info/edit/group_manage_permissions.png differ diff --git a/Telegram/Resources/icons/info/edit/group_manage_permissions@2x.png b/Telegram/Resources/icons/info/edit/group_manage_permissions@2x.png new file mode 100644 index 000000000..c8b74c35d Binary files /dev/null and b/Telegram/Resources/icons/info/edit/group_manage_permissions@2x.png differ diff --git a/Telegram/Resources/icons/info/edit/group_manage_permissions@3x.png b/Telegram/Resources/icons/info/edit/group_manage_permissions@3x.png new file mode 100644 index 000000000..894504ae3 Binary files /dev/null and b/Telegram/Resources/icons/info/edit/group_manage_permissions@3x.png differ diff --git a/Telegram/Resources/icons/info/info_blacklist.png b/Telegram/Resources/icons/info/info_blacklist.png new file mode 100644 index 000000000..6fabfff96 Binary files /dev/null and b/Telegram/Resources/icons/info/info_blacklist.png differ diff --git a/Telegram/Resources/icons/info/info_blacklist@2x.png b/Telegram/Resources/icons/info/info_blacklist@2x.png new file mode 100644 index 000000000..e05e0362d Binary files /dev/null and b/Telegram/Resources/icons/info/info_blacklist@2x.png differ diff --git a/Telegram/Resources/icons/info/info_blacklist@3x.png b/Telegram/Resources/icons/info/info_blacklist@3x.png new file mode 100644 index 000000000..3d740024f Binary files /dev/null and b/Telegram/Resources/icons/info/info_blacklist@3x.png differ diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 4c64d41bf..ee276334c 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -233,6 +233,8 @@ void SaveBoostsUnrestrict( api->registerModifyRequest(key, requestId); } +} // namespace + void ShowEditPermissions( not_null navigation, not_null peer) { @@ -2262,9 +2264,6 @@ void Controller::deleteChannel() { }).send(); } -} // namespace - - EditPeerInfoBox::EditPeerInfoBox( QWidget*, not_null navigation, diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.h b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.h index 9844320cf..0858375a2 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.h @@ -26,6 +26,13 @@ class VerticalLayout; class SettingsButton; } // namespace Ui +void ShowEditPermissions( + not_null navigation, + not_null peer); +void ShowEditInviteLinks( + not_null navigation, + not_null peer); + class EditPeerInfoBox : public Ui::BoxContent { public: EditPeerInfoBox( diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index c9738c19b..0d44901dd 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -17,6 +17,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "boxes/peers/add_bot_to_chat_box.h" #include "boxes/peers/edit_contact_box.h" +#include "boxes/peers/edit_peer_info_box.h" +#include "boxes/peers/edit_peer_invite_links.h" +#include "boxes/peers/edit_participants_box.h" #include "boxes/report_messages_box.h" #include "boxes/share_box.h" #include "boxes/translate_box.h" @@ -40,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_item_helpers.h" #include "history/view/history_view_context_menu.h" // HistoryView::ShowReportPeerBox #include "history/view/history_view_item_preview.h" +#include "history/admin_log/history_admin_log_section.h" #include "info/info_controller.h" #include "info/info_memento.h" #include "info/profile/info_profile_icon.h" @@ -70,6 +74,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/vertical_layout.h" #include "window/window_controller.h" // Window::Controller::show. #include "window/window_peer_menu.h" +#include "mainwidget.h" #include "window/window_session_controller.h" #include "styles/style_info.h" #include "styles/style_layers.h" @@ -840,6 +845,31 @@ private: }; +class ManageFiller { +public: + ManageFiller( + not_null controller, + not_null parent, + not_null peer); + + object_ptr fill(); + +private: + void addPeerPermissions(not_null peer); + void addPeerAdmins(not_null peer); + void addPeerInviteLinks(not_null peer); + void addChannelBlockedUsers(not_null channel); + void addChannelRecentActions(not_null channel); + + void fillChatActions(not_null chat); + void fillChannelActions(not_null channel); + + not_null _controller; + not_null _parent; + not_null _peer; + object_ptr _wrap = { nullptr }; +}; + void ReportReactionBox( not_null box, not_null controller, @@ -2114,6 +2144,158 @@ object_ptr ActionsFiller::fill() { return { nullptr }; } +ManageFiller::ManageFiller( + not_null controller, + not_null parent, + not_null peer) +: _controller(controller) +, _parent(parent) +, _peer(peer) { +} + +void ManageFiller::addPeerPermissions( + not_null peer) { + if (peer->isUser() || (peer->isChannel() && !peer->isMegagroup())) return; + + const auto canEditPermissions = [&] { + return peer->isChannel() + ? peer->asChannel()->canEditPermissions() + : peer->asChat()->canEditPermissions(); + }(); + + if (canEditPermissions) { + const auto controller = _controller; + auto button = AddActionButton( + _wrap, + tr::lng_manage_peer_permissions(), + rpl::single(true), + [=] { ShowEditPermissions(controller->parentController(), peer); }, + &st::menuIconPermissions); + } +} + +void ManageFiller::addPeerAdmins( + not_null peer) { + if (peer->isUser()) return; + + const auto canViewAdmins = [&] { + return peer->isChannel() + ? peer->asChannel()->canViewAdmins() + : peer->asChat()->amIn(); + }(); + if (canViewAdmins) { + const auto controller = _controller; + auto button = AddActionButton( + _wrap, + tr::lng_manage_peer_administrators(), + rpl::single(true), + [=] { ParticipantsBoxController::Start( + controller->parentController(), + peer, + ParticipantsBoxController::Role::Admins);}, + &st::menuIconAdmin); + } +} + +void ManageFiller::addPeerInviteLinks( + not_null peer) { + if (peer->isUser()) return; + + const auto canHaveInviteLink = [&] { + return peer->isChannel() + ? peer->asChannel()->canHaveInviteLink() + : peer->asChat()->canHaveInviteLink(); + }(); + if (canHaveInviteLink) { + const auto controller = _controller->parentController(); + auto button = AddActionButton( + _wrap, + tr::lng_manage_peer_invite_links(), + rpl::single(true), + [=] { + controller->window().show(Box(ManageInviteLinksBox, peer, peer->session().user(), 0, 0), + Ui::LayerOption::KeepOther); + }, + &st::menuIconLinks); + } +} + +void ManageFiller::addChannelBlockedUsers( + not_null channel) { + if (channel->hasAdminRights() || channel->amCreator()) { + const auto controller = _controller; + auto button = AddActionButton( + _wrap, + tr::lng_manage_peer_removed_users(), + rpl::single(true), + [=] { ParticipantsBoxController::Start( + controller->parentController(), + channel, + ParticipantsBoxController::Role::Kicked);}, + &st::menuIconRemove); + } +} + +void ManageFiller::addChannelRecentActions( + not_null channel) { + if (channel->hasAdminRights() || channel->amCreator()) { + const auto controller = _controller; + auto button = AddActionButton( + _wrap, + tr::lng_manage_peer_recent_actions(), + rpl::single(true), + [=] { + if (const auto window = controller->parentController()) { + if (const auto mainwidget = window->widget()->sessionContent()) { + if (mainwidget->areRecentActionsOpened()) { + controller->showSection( + std::make_shared(channel)); + } + } + } + }, + &st::menuIconGroupLog); + } +} + +void ManageFiller::fillChatActions( + not_null chat) { + addPeerPermissions(chat); + addPeerAdmins(chat); + addPeerInviteLinks(chat); +} + +void ManageFiller::fillChannelActions( + not_null channel) { + addPeerPermissions(channel); + addPeerAdmins(channel); + addPeerInviteLinks(channel); + addChannelBlockedUsers(channel); + addChannelRecentActions(channel); +} + +object_ptr ManageFiller::fill() { + auto wrapResult = [=](auto &&callback) { + _wrap = object_ptr(_parent); + _wrap->add(CreateSkipWidget(_wrap)); + callback(); + _wrap->add(CreateSkipWidget(_wrap)); + return std::move(_wrap); + }; + if (auto chat = _peer->asChat()) { + return wrapResult([=] { + fillChatActions(chat); + }); + } else if (auto channel = _peer->asChannel()) { + if (channel->isMegagroup() || channel->hasAdminRights() || channel->amCreator()) { + return wrapResult([=] { + fillChannelActions(channel); + }); + } + } + return { nullptr }; +} + } // namespace const char kOptionShowPeerIdBelowAbout[] = "show-peer-id-below-about"; @@ -2135,6 +2317,14 @@ object_ptr SetupDetails( return filler.fill(); } +object_ptr SetupManage( + not_null controller, + not_null parent, + not_null peer) { + ManageFiller filler(controller, parent, peer); + return filler.fill(); +} + object_ptr SetupActions( not_null controller, not_null parent, diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.h b/Telegram/SourceFiles/info/profile/info_profile_actions.h index d31714a82..785deadf2 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.h +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.h @@ -38,6 +38,11 @@ object_ptr SetupDetails( not_null parent, not_null topic); +object_ptr SetupManage( + not_null controller, + not_null parent, + not_null peer); + object_ptr SetupActions( not_null controller, not_null parent, diff --git a/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp b/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp index 92192d3b3..8b4a2e447 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp @@ -108,6 +108,10 @@ object_ptr InnerWidget::setupContent( } else { result->add(SetupDetails(_controller, parent, _peer, origin)); } + if (auto manage = SetupManage(_controller, result.data(), _peer)) { + result->add(object_ptr(result)); + result->add(std::move(manage)); + } result->add(setupSharedMedia(result.data())); if (_topic) { return result; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index f7dbb4b7e..3c146da22 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -49,6 +49,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "dialogs/dialogs_widget.h" #include "history/history_widget.h" #include "history/history_item_helpers.h" // GetErrorTextForSending. +#include "history/admin_log/history_admin_log_section.h" #include "history/view/media/history_view_media.h" #include "history/view/history_view_service_message.h" #include "history/view/history_view_sublist_section.h" @@ -1942,6 +1943,11 @@ void MainWidget::showNonPremiumLimitToast(bool download) { }); } +bool MainWidget::areRecentActionsOpened() { + return _mainSection + && static_cast(_mainSection.data()); +} + void MainWidget::showBackFromStack( const SectionShow ¶ms) { if (preventsCloseSection([=] { showBackFromStack(params); }, params)) { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index ff821e658..7758b1e59 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -236,6 +236,7 @@ public: void showNonPremiumLimitToast(bool download); + bool areRecentActionsOpened(); void dialogsCancelled(); private: