diff --git a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp index 2793f20a6e5665..f7326ea19b554b 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp @@ -24,13 +24,16 @@ For license and copyright information please follow this link: #include "info/profile/info_profile_emoji_status_panel.h" #include "info/info_controller.h" #include "boxes/peers/edit_forum_topic_box.h" +#include "boxes/report_messages_box.h" #include "history/view/media/history_view_sticker_player.h" #include "lang/lang_keys.h" #include "ui/boxes/show_or_premium_box.h" #include "ui/controls/userpic_button.h" #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" +#include "ui/widgets/popup_menu.h" #include "ui/text/text_utilities.h" +#include "base/event_filter.h" #include "base/unixtime.h" #include "window/window_session_controller.h" #include "main/main_session.h" @@ -41,6 +44,7 @@ For license and copyright information please follow this link: #include "styles/style_boxes.h" #include "styles/style_info.h" #include "styles/style_dialogs.h" +#include "styles/style_menu_icons.h" namespace Info::Profile { namespace { @@ -504,7 +508,7 @@ void Cover::refreshUploadPhotoOverlay() { return; } - _userpic->switchChangePhotoOverlay([&] { + const auto canChange = [&] { if (const auto chat = _peer->asChat()) { return chat->canEditInformation(); } else if (const auto channel = _peer->asChannel()) { @@ -516,7 +520,10 @@ void Cover::refreshUploadPhotoOverlay() { && !user->isServiceUser()); } Unexpected("Peer type in Info::Profile::Cover."); - }(), [=](Ui::UserpicButton::ChosenImage chosen) { + }(); + + _userpic->switchChangePhotoOverlay(canChange, [=]( + Ui::UserpicButton::ChosenImage chosen) { using ChosenType = Ui::UserpicButton::ChosenType; auto result = Api::PeerPhoto::UserPhoto{ base::take(chosen.image), // Strange MSVC bug with take. @@ -538,6 +545,53 @@ void Cover::refreshUploadPhotoOverlay() { } }); + const auto canReport = [=, peer = _peer] { + if (!peer->hasUserpic()) { + return false; + } + const auto user = peer->asUser(); + if (!user) { + if (canChange) { + return false; + } + } else if (user->hasPersonalPhoto() + || user->isSelf() + || user->isInaccessible() + || user->isRepliesChat() + || (user->botInfo && user->botInfo->canEditInformation) + || user->isServiceUser()) { + return false; + } + return true; + }; + + const auto contextMenu = _userpic->lifetime() + .make_state>(); + const auto showMenu = [=, peer = _peer, controller = _controller]( + not_null parent) { + if (!canReport()) { + return false; + } + *contextMenu = base::make_unique_q( + parent, + st::popupMenuWithIcons); + contextMenu->get()->addAction(tr::lng_profile_report(tr::now), [=] { + controller->show( + ReportProfilePhotoBox( + peer, + peer->owner().photo(peer->userpicPhotoId())), + Ui::LayerOption::CloseOther); + }, &st::menuIconReport); + contextMenu->get()->popup(QCursor::pos()); + return true; + }; + base::install_event_filter(_userpic, [showMenu, raw = _userpic.data()]( + not_null e) { + return (e->type() == QEvent::ContextMenu && showMenu(raw)) + ? base::EventFilterResult::Cancel + : base::EventFilterResult::Continue; + }); + if (const auto user = _peer->asUser()) { _userpic->resetPersonalRequests( ) | rpl::start_with_next([=] { diff --git a/Telegram/SourceFiles/info/profile/info_profile_cover.h b/Telegram/SourceFiles/info/profile/info_profile_cover.h index 59a857eb69c7f1..dec3e44ac8ac7e 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_cover.h +++ b/Telegram/SourceFiles/info/profile/info_profile_cover.h @@ -149,7 +149,7 @@ class Cover final : public Ui::FixedHeightWidget { const std::unique_ptr _badge; rpl::variable _onlineCount; - object_ptr _userpic; + const object_ptr _userpic; Ui::UserpicButton *_changePersonal = nullptr; std::optional _personalChosen; object_ptr _iconButton;