From d0606a3798c33e746496e789f2117f9f73a11182 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 22 Oct 2021 18:33:58 +0400 Subject: [PATCH] Show PeerShortInfoCover in group call context menu. --- Telegram/CMakeLists.txt | 2 + .../boxes/peers/peer_short_info_box.cpp | 23 +++++--- .../boxes/peers/peer_short_info_box.h | 1 + .../boxes/peers/prepare_short_info_box.cpp | 24 ++++---- .../boxes/peers/prepare_short_info_box.h | 13 ++++ Telegram/SourceFiles/calls/calls.style | 19 ++++++ .../calls/group/calls_cover_item.cpp | 59 +++++++++++++++++++ .../calls/group/calls_cover_item.h | 51 ++++++++++++++++ .../calls/group/calls_group_members.cpp | 24 +++++++- 9 files changed, 195 insertions(+), 21 deletions(-) create mode 100644 Telegram/SourceFiles/calls/group/calls_cover_item.cpp create mode 100644 Telegram/SourceFiles/calls/group/calls_cover_item.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index ae5b31d880..c8b9daf8b3 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -258,6 +258,8 @@ PRIVATE boxes/username_box.h calls/group/calls_choose_join_as.cpp calls/group/calls_choose_join_as.h + calls/group/calls_cover_item.cpp + calls/group/calls_cover_item.h calls/group/calls_group_call.cpp calls/group/calls_group_call.h calls/group/calls_group_common.cpp diff --git a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp index 38a28ae19c..28c0367d86 100644 --- a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp @@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/profile/info_profile_text.h" #include "media/streaming/media_streaming_instance.h" #include "media/streaming/media_streaming_player.h" +#include "base/event_filter.h" #include "lang/lang_keys.h" #include "styles/style_layers.h" #include "styles/style_info.h" @@ -93,6 +94,8 @@ PeerShortInfoCover::PeerShortInfoCover( , _statusStyle(std::make_unique(_st.status)) , _status(_widget.get(), std::move(status), _statusStyle->st) , _videoPaused(std::move(videoPaused)) { + _widget->setCursor(_cursor); + _widget->resize(_st.size, _st.size); std::move( @@ -112,21 +115,23 @@ PeerShortInfoCover::PeerShortInfoCover( paint(p); }, lifetime()); - _widget->events( - ) | rpl::filter([=](not_null e) { - return (e->type() == QEvent::MouseButtonPress) - || (e->type() == QEvent::MouseButtonDblClick); - }) | rpl::start_with_next([=](not_null e) { + base::install_event_filter(_widget.get(), [=](not_null e) { + if (e->type() != QEvent::MouseButtonPress + && e->type() != QEvent::MouseButtonDblClick) { + return base::EventFilterResult::Continue; + } const auto mouse = static_cast(e.get()); const auto x = mouse->pos().x(); if (mouse->button() != Qt::LeftButton) { - return; + return base::EventFilterResult::Continue; } else if (/*_index > 0 && */x < _st.size / 3) { _moveRequests.fire(-1); } else if (/*_index + 1 < _count && */x >= _st.size / 3) { _moveRequests.fire(1); } - }, lifetime()); + e->accept(); + return base::EventFilterResult::Cancel; + }); _name->moveToLeft( _st.namePosition.x(), @@ -148,6 +153,10 @@ PeerShortInfoCover::PeerShortInfoCover( PeerShortInfoCover::~PeerShortInfoCover() = default; +not_null PeerShortInfoCover::widget() const { + return _widget; +} + object_ptr PeerShortInfoCover::takeOwned() { return std::move(_owned); } diff --git a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.h b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.h index 21083f8848..021ad97976 100644 --- a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.h +++ b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.h @@ -62,6 +62,7 @@ public: Fn videoPaused); ~PeerShortInfoCover(); + [[nodiscard]] not_null widget() const; [[nodiscard]] object_ptr takeOwned(); void setScrollTop(int scrollTop); diff --git a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp index 121f1cf3cb..f048c5765f 100644 --- a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp @@ -86,18 +86,20 @@ void ProcessUserpic( st::shortInfoWidth * style::DevicePixelRatio(), ImageRoundRadius::None), false); + state->current.photoLoadingProgress = 1.; state->photoView = nullptr; return; } peer->loadUserpic(); - state->current.photoLoadingProgress = 0.; const auto image = state->userpicView->image(); if (!image) { + state->current.photoLoadingProgress = 0.; state->current.photo = QImage(); state->waitingLoad = true; return; } GenerateImage(state, image, true); + state->current.photoLoadingProgress = peer->userpicPhotoId() ? 0. : 1.; state->photoView = nullptr; } @@ -265,10 +267,6 @@ void ProcessFullPhoto( }); } -void ProcessOld(not_null peer, not_null state) { - -} - void ValidatePhotoId( not_null state, PhotoId oldUserpicPhotoId) { @@ -357,12 +355,8 @@ bool ProcessCurrent( return true; } -struct UserpicResult { - rpl::producer value; - Fn move; -}; - -[[nodiscard]] UserpicResult UserpicValue(not_null peer) { +[[nodiscard]] PreparedShortInfoUserpic UserpicValue( + not_null peer) { const auto moveRequests = std::make_shared>(); auto move = [=](int shift) { moveRequests->fire_copy(shift); @@ -463,3 +457,11 @@ object_ptr PrepareShortInfoBox( open, videoIsPaused); } + +rpl::producer PrepareShortInfoStatus(not_null peer) { + return StatusValue(peer); +} + +PreparedShortInfoUserpic PrepareShortInfoUserpic(not_null peer) { + return UserpicValue(peer); +} diff --git a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h index 5ebb41cae0..18b7fa3c09 100644 --- a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h +++ b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h @@ -19,6 +19,13 @@ namespace Window { class SessionNavigation; } // namespace Window +struct PeerShortInfoUserpic; + +struct PreparedShortInfoUserpic { + rpl::producer value; + Fn move; +}; + [[nodiscard]] object_ptr PrepareShortInfoBox( not_null peer, Fn open, @@ -27,3 +34,9 @@ class SessionNavigation; [[nodiscard]] object_ptr PrepareShortInfoBox( not_null peer, not_null navigation); + +[[nodiscard]] rpl::producer PrepareShortInfoStatus( + not_null peer); + +[[nodiscard]] PreparedShortInfoUserpic PrepareShortInfoUserpic( + not_null peer); diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 52b1bdfee2..3459c91d9b 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -10,6 +10,7 @@ using "ui/basic.style"; using "ui/widgets/widgets.style"; using "ui/layers/layers.style"; using "ui/chat/chat.style"; // GroupCallUserpics +using "info/info.style"; // ShortInfoCover using "window/window.style"; CallSignalBars { @@ -542,6 +543,24 @@ groupCallPopupVolumeMenu: Menu(groupCallMenu) { widthMin: 210px; itemBgOver: groupCallMenuBg; } +groupCallMenuCoverSize: 240px; +groupCallPopupCoverMenu: Menu(groupCallMenu) { + widthMin: groupCallMenuCoverSize; + widthMax: groupCallMenuCoverSize; + itemBgOver: groupCallMenuBg; +} +groupCallPopupMenuWithCover: PopupMenu(groupCallPopupMenu) { + scrollPadding: margins(0px, 0px, 0px, 8px); + menu: Menu(groupCallMenu) { + widthMin: groupCallMenuCoverSize; + widthMax: groupCallMenuCoverSize; + } +} +groupCallMenuCover: ShortInfoCover(shortInfoCover) { + size: groupCallMenuCoverSize; + namePosition: point(17px, 28px); + statusPosition: point(17px, 8px); +} groupCallRecordingTimerPadding: margins(0px, 4px, 0px, 4px); groupCallRecordingTimerFont: font(12px); diff --git a/Telegram/SourceFiles/calls/group/calls_cover_item.cpp b/Telegram/SourceFiles/calls/group/calls_cover_item.cpp new file mode 100644 index 0000000000..f5a0400e20 --- /dev/null +++ b/Telegram/SourceFiles/calls/group/calls_cover_item.cpp @@ -0,0 +1,59 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "calls/group/calls_cover_item.h" + +#include "boxes/peers/prepare_short_info_box.h" +#include "styles/style_calls.h" +#include "styles/style_info.h" + +namespace Calls { +namespace { + +} // namespace + +CoverItem::CoverItem( + not_null parent, + const style::Menu &stMenu, + const style::ShortInfoCover &st, + rpl::producer name, + rpl::producer status, + PreparedShortInfoUserpic userpic) +: Ui::Menu::ItemBase(parent, stMenu) +, _cover( + this, + st, + std::move(name), + std::move(status), + std::move(userpic.value), + [] { return false; }) +, _dummyAction(new QAction(parent)) +, _st(st) { + setPointerCursor(false); + + initResizeHook(parent->sizeValue()); + enableMouseSelecting(); + enableMouseSelecting(_cover.widget()); + + _cover.widget()->move(0, 0); + _cover.moveRequests( + ) | rpl::start_with_next(userpic.move, lifetime()); +} + +not_null CoverItem::action() const { + return _dummyAction; +} + +bool CoverItem::isEnabled() const { + return false; +} + +int CoverItem::contentHeight() const { + return _st.size + st::groupCallMenu.separatorPadding.bottom(); +} + +} // namespace Calls diff --git a/Telegram/SourceFiles/calls/group/calls_cover_item.h b/Telegram/SourceFiles/calls/group/calls_cover_item.h new file mode 100644 index 0000000000..94c4dd1e8a --- /dev/null +++ b/Telegram/SourceFiles/calls/group/calls_cover_item.h @@ -0,0 +1,51 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "ui/rp_widget.h" +#include "ui/widgets/menu/menu_item_base.h" +#include "boxes/peers/peer_short_info_box.h" + +struct PreparedShortInfoUserpic; + +namespace style { +struct ShortInfoCover; +} // namespace style + +namespace Calls { + +namespace Group { +struct MuteRequest; +struct VolumeRequest; +struct ParticipantState; +} // namespace Group + +class CoverItem final : public Ui::Menu::ItemBase { +public: + CoverItem( + not_null parent, + const style::Menu &stMenu, + const style::ShortInfoCover &st, + rpl::producer name, + rpl::producer status, + PreparedShortInfoUserpic userpic); + + not_null action() const override; + bool isEnabled() const override; + +private: + int contentHeight() const override; + + const PeerShortInfoCover _cover; + const not_null _dummyAction; + const style::ShortInfoCover &_st; + + +}; + +} // namespace Calls diff --git a/Telegram/SourceFiles/calls/group/calls_group_members.cpp b/Telegram/SourceFiles/calls/group/calls_group_members.cpp index 5c6c3b1d60..c831f5a73a 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_members.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "calls/group/calls_group_members.h" +#include "calls/group/calls_cover_item.h" #include "calls/group/calls_group_call.h" #include "calls/group/calls_group_menu.h" #include "calls/group/calls_volume_item.h" @@ -31,7 +32,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "main/main_account.h" // account().appConfig(). #include "main/main_app_config.h" // appConfig().get(). +#include "info/profile/info_profile_values.h" // Info::Profile::NameValue. #include "boxes/peers/edit_participants_box.h" // SubscribeToMigration. +#include "boxes/peers/prepare_short_info_box.h" // PrepareShortInfo... #include "window/window_controller.h" // Controller::sessionController. #include "window/window_session_controller.h" #include "webrtc/webrtc_video_track.h" @@ -1189,6 +1192,7 @@ base::unique_qptr Members::Controller::createRowContextMenu( const auto muteState = real->state(); const auto muted = (muteState == Row::State::Muted) || (muteState == Row::State::RaisedHand); + const auto addCover = true; const auto addVolumeItem = !muted || isMe(participantPeer); const auto admin = IsGroupCallAdmin(_peer, participantPeer); const auto session = &_peer->session(); @@ -1213,7 +1217,9 @@ base::unique_qptr Members::Controller::createRowContextMenu( auto result = base::make_unique_q( parent, - (addVolumeItem + (addCover + ? st::groupCallPopupMenuWithCover + : addVolumeItem ? st::groupCallPopupMenuWithVolume : st::groupCallPopupMenu)); const auto weakMenu = Ui::MakeWeak(result.get()); @@ -1247,6 +1253,18 @@ base::unique_qptr Members::Controller::createRowContextMenu( _kickParticipantRequests.fire_copy(participantPeer); }); + if (addCover) { + result->addAction(base::make_unique_q( + result->menu(), + st::groupCallPopupCoverMenu, + st::groupCallMenuCover, + Info::Profile::NameValue( + participantPeer + ) | rpl::map([](const auto &text) { return text.text; }), + PrepareShortInfoStatus(participantPeer), + PrepareShortInfoUserpic(participantPeer))); + } + if (const auto real = _call->lookupReal()) { auto oneFound = false; auto hasTwoOrMore = false; @@ -1357,7 +1375,7 @@ base::unique_qptr Members::Controller::createRowContextMenu( removeFromVoiceChat)); } } - if (result->empty()) { + if (result->actions().size() < (addCover ? 2 : 1)) { return nullptr; } return result; @@ -1451,7 +1469,7 @@ void Members::Controller::addMuteActionsToContextMenu( } }, volumeItem->lifetime()); - if (!menu->empty()) { + if (menu->actions().size() > 1) { // First - cover. menu->addSeparator(); }