/* This file is part of Telegram Desktop, the official desktop version of Telegram messaging app, see https://telegram.org Telegram Desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "boxes/peers/manage_peer_box.h" #include <rpl/combine.h> #include "lang/lang_keys.h" #include "boxes/peers/edit_peer_info_box.h" #include "ui/wrap/vertical_layout.h" #include "ui/widgets/labels.h" #include "history/history_admin_log_section.h" #include "window/window_controller.h" #include "profile/profile_channel_controllers.h" #include "info/profile/info_profile_button.h" #include "info/profile/info_profile_icon.h" #include "info/profile/info_profile_values.h" #include "styles/style_boxes.h" #include "styles/style_info.h" namespace { base::lambda<QString()> ManagePeerTitle( not_null<ChannelData*> channel) { return langFactory(channel->isMegagroup() ? lng_manage_group_title : lng_manage_channel_title); } auto ToPositiveNumberString() { return rpl::map([](int count) { return count ? QString::number(count) : QString(); }); } template <typename Callback> Info::Profile::Button *AddButton( not_null<Ui::VerticalLayout*> parent, rpl::producer<QString> &&text, Callback callback, const style::icon &icon) { auto button = parent->add( object_ptr<Info::Profile::Button>( parent, std::move(text), st::managePeerButton)); button->addClickHandler(std::forward<Callback>(callback)); Ui::CreateChild<Info::Profile::FloatingIcon>( button, icon, st::managePeerButtonIconPosition); return button; } template <typename Callback> void AddButtonWithCount( not_null<Ui::VerticalLayout*> parent, rpl::producer<QString> &&text, rpl::producer<QString> &&count, Callback callback, const style::icon &icon) { auto button = AddButton( parent, std::move(text), std::forward<Callback>(callback), icon); auto label = Ui::CreateChild<Ui::FlatLabel>( button, std::move(count), st::managePeerButtonLabel); label->setAttribute(Qt::WA_TransparentForMouseEvents); rpl::combine(button->widthValue(), label->widthValue()) | rpl::start_with_next([label](int outerWidth, int width) { label->moveToRight( st::managePeerButtonLabelPosition.x(), st::managePeerButtonLabelPosition.y(), outerWidth); }, label->lifetime()); } bool HasRecentActions(not_null<ChannelData*> channel) { return channel->hasAdminRights() || channel->amCreator(); } void ShowRecentActions( not_null<Window::Controller*> controller, not_null<ChannelData*> channel) { controller->showSection( AdminLog::SectionMemento(channel), Window::SectionShow()); } void FillManageBox( not_null<Window::Controller*> controller, not_null<ChannelData*> channel, not_null<Ui::VerticalLayout*> content) { using Profile::ParticipantsBoxController; auto isGroup = channel->isMegagroup(); if (channel->canEditInformation()) { AddButton( content, Lang::Viewer(isGroup ? lng_manage_group_info : lng_manage_channel_info), [=] { Ui::show(Box<EditPeerInfoBox>(channel)); }, st::infoIconInformation); } if (HasRecentActions(channel)) { AddButton( content, Lang::Viewer(lng_manage_peer_recent_actions), [=] { ShowRecentActions(controller, channel); }, st::infoIconRecentActions); } if (channel->canViewMembers()) { AddButtonWithCount( content, Lang::Viewer(lng_manage_peer_members), Info::Profile::MembersCountValue(channel) | ToPositiveNumberString(), [=] { ParticipantsBoxController::Start( controller, channel, ParticipantsBoxController::Role::Members); }, st::infoIconMembers); } if (channel->canViewAdmins()) { AddButtonWithCount( content, Lang::Viewer(lng_manage_peer_administrators), Info::Profile::AdminsCountValue(channel) | ToPositiveNumberString(), [=] { ParticipantsBoxController::Start( controller, channel, ParticipantsBoxController::Role::Admins); }, st::infoIconAdministrators); } if (channel->canViewBanned()) { AddButtonWithCount( content, Lang::Viewer(lng_manage_peer_restricted_users), Info::Profile::RestrictedCountValue(channel) | ToPositiveNumberString(), [=] { ParticipantsBoxController::Start( controller, channel, ParticipantsBoxController::Role::Restricted); }, st::infoIconRestrictedUsers); AddButtonWithCount( content, Lang::Viewer(lng_manage_peer_banned_users), Info::Profile::KickedCountValue(channel) | ToPositiveNumberString(), [=] { ParticipantsBoxController::Start( controller, channel, ParticipantsBoxController::Role::Kicked); }, st::infoIconBlacklist); } } } // namespace ManagePeerBox::ManagePeerBox( QWidget*, not_null<ChannelData*> channel) : _channel(channel) { } bool ManagePeerBox::Available(not_null<ChannelData*> channel) { // canViewMembers() is removed, because in supergroups you // see them in profile and in channels only admins can see them. // canViewAdmins() is removed, because in supergroups it is // always true and in channels it is equal to canViewBanned(). return false // || channel->canViewMembers() // || channel->canViewAdmins() || channel->canViewBanned() || channel->canEditInformation() || HasRecentActions(channel); } void ManagePeerBox::prepare() { _channel->updateFull(); setTitle(ManagePeerTitle(_channel)); addButton(langFactory(lng_cancel), [this] { closeBox(); }); setupContent(); } void ManagePeerBox::setupContent() { auto content = Ui::CreateChild<Ui::VerticalLayout>(this); FillManageBox(controller(), _channel, content); widthValue() | rpl::start_with_next([=](int width) { content->resizeToWidth(width); }, content->lifetime()); content->heightValue() | rpl::start_with_next([=](int height) { setDimensions(st::boxWidth, height); }, content->lifetime()); }