diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 1b6b4aa79..47d636dc2 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -1167,7 +1167,8 @@ desktopCaptureSubmit: RoundButton(desktopCaptureCancel) { } groupCallNarrowSkip: 9px; -groupCallNarrowMembersWidth: 202px; +groupCallNarrowMembersWidth: 204px; +groupCallNarrowVideoHeight: 120px; //groupCallNarrowRowSkip: 4px; //groupCallNarrowSize: size(144px, 90px); //groupCallNarrowUserpicTop: 13px; diff --git a/Telegram/SourceFiles/calls/group/calls_group_members.cpp b/Telegram/SourceFiles/calls/group/calls_group_members.cpp index 6d146cdf7..e9d1a7b87 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_members.cpp @@ -783,9 +783,6 @@ Row *Members::Controller::findRow( } void Members::Controller::setMode(PanelMode mode) { - if (_mode == mode) { - return; - } _mode = mode; } @@ -1648,27 +1645,30 @@ std::unique_ptr Members::Controller::createInvitedRow( Members::Members( not_null parent, not_null call, - not_null viewport, PanelMode mode) : RpWidget(parent) , _call(call) -, _viewport(viewport) , _mode(mode) , _scroll(this) , _listController(std::make_unique(call, parent, mode)) , _layout(_scroll->setOwnedWidget( object_ptr(_scroll.data()))) -, _videoWrap(_layout->add(object_ptr(_layout.get()))) { +, _videoWrap(_layout->add(object_ptr(_layout.get()))) +, _viewport( + std::make_unique( + _videoWrap.get(), + PanelMode::Default)) { setupAddMember(call); setupList(); setContent(_list); setupFakeRoundCorners(); _listController->setDelegate(static_cast(this)); - grabViewport(); trackViewportGeometry(); } -Members::~Members() = default; +Members::~Members() { + _viewport = nullptr; +} auto Members::toggleMuteRequests() const -> rpl::producer { @@ -1685,6 +1685,10 @@ auto Members::kickParticipantRequests() const return _listController->kickParticipantRequests(); } +not_null Members::viewport() const { + return _viewport.get(); +} + int Members::desiredHeight() const { const auto count = [&] { if (const auto real = _call->lookupReal()) { @@ -1808,10 +1812,8 @@ void Members::setMode(PanelMode mode) { if (_mode.current() == mode) { return; } - grabViewport(mode); _mode = mode; _listController->setMode(mode); - trackViewportGeometry(); //_list->setMode((mode == PanelMode::Wide) // ? PeerListContent::Mode::Custom // : PeerListContent::Mode::Default); @@ -1861,23 +1863,12 @@ void Members::setupList() { updateControlsGeometry(); } -void Members::grabViewport() { - grabViewport(_mode.current()); -} - -void Members::grabViewport(PanelMode mode) { - if (mode != PanelMode::Default) { - _viewportGrabLifetime.destroy(); - _videoWrap->resize(_videoWrap->width(), 0); - return; - } - _viewport->setMode(mode, _videoWrap.get()); -} - void Members::trackViewportGeometry() { - if (_mode.current() != PanelMode::Default) { - return; - } + _call->videoEndpointPinnedValue( + ) | rpl::start_with_next([=](const VideoEndpoint &pinned) { + _viewport->showLarge(pinned); + }, _viewport->lifetime()); + const auto move = [=] { const auto maxTop = _viewport->fullHeight() - _viewport->widget()->height(); @@ -1900,20 +1891,20 @@ void Members::trackViewportGeometry() { ) | rpl::start_with_next([=](int width) { _viewport->resizeToWidth(width); resize(); - }, _viewportGrabLifetime); + }, _viewport->lifetime()); _scroll->heightValue( - ) | rpl::skip(1) | rpl::start_with_next(resize, _viewportGrabLifetime); + ) | rpl::skip(1) | rpl::start_with_next(resize, _viewport->lifetime()); _scroll->scrollTopValue( - ) | rpl::skip(1) | rpl::start_with_next(move, _viewportGrabLifetime); + ) | rpl::skip(1) | rpl::start_with_next(move, _viewport->lifetime()); _viewport->fullHeightValue( ) | rpl::start_with_next([=](int height) { _videoWrap->resize(_videoWrap->width(), height); move(); resize(); - }, _viewportGrabLifetime); + }, _viewport->lifetime()); } void Members::resizeEvent(QResizeEvent *e) { diff --git a/Telegram/SourceFiles/calls/group/calls_group_members.h b/Telegram/SourceFiles/calls/group/calls_group_members.h index 3e36aff4b..f221cdb0f 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members.h +++ b/Telegram/SourceFiles/calls/group/calls_group_members.h @@ -39,10 +39,10 @@ public: Members( not_null parent, not_null call, - not_null viewport, PanelMode mode); ~Members(); + [[nodiscard]] not_null viewport() const; [[nodiscard]] int desiredHeight() const; [[nodiscard]] rpl::producer desiredHeightValue() const override; [[nodiscard]] rpl::producer fullCountValue() const; @@ -89,18 +89,16 @@ private: void setupList(); void setupFakeRoundCorners(); - void grabViewport(); - void grabViewport(PanelMode mode); void trackViewportGeometry(); void updateControlsGeometry(); const not_null _call; - const not_null _viewport; rpl::variable _mode = PanelMode(); object_ptr _scroll; std::unique_ptr _listController; not_null _layout; const not_null _videoWrap; + std::unique_ptr _viewport; rpl::event_stream<> _enlargeVideoClicks; rpl::variable _addMemberButton = nullptr; ListWidget *_list = nullptr; @@ -108,8 +106,6 @@ private: rpl::variable _canAddMembers; - rpl::lifetime _viewportGrabLifetime; - }; } // namespace Calls diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp index 7ceede4fb..df42c6e98 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp @@ -404,7 +404,7 @@ Panel::Panel(not_null call) _window->body(), st::groupCallTitle)) #endif // !Q_OS_MAC -, _viewport(std::make_unique(widget(), _mode.current())) +, _viewport(std::make_unique(widget(), PanelMode::Wide)) , _mute(std::make_unique( widget(), st::callMuteButton, @@ -425,6 +425,7 @@ Panel::Panel(not_null call) _layerBg->setStyleOverrides(&st::groupCallBox, &st::groupCallLayerBox); _layerBg->setHideByBackgroundClick(true); + _viewport->widget()->hide(); if (!_viewport->requireARGB32()) { _call->setNotRequireARGB32(); } @@ -975,8 +976,9 @@ void Panel::setupMembers() { _countdown.destroy(); _startsWhen.destroy(); - _members.create(widget(), _call, _viewport.get(), mode()); - setupVideo(); + _members.create(widget(), _call, mode()); + setupVideo(_viewport.get()); + setupVideo(_members->viewport()); _members->show(); refreshControlsBackground(); @@ -1117,16 +1119,14 @@ void Panel::raiseControls() { _mute->raise(); } -void Panel::setupVideo() { - const auto raw = _viewport.get(); - +void Panel::setupVideo(not_null viewport) { const auto setupTile = [=]( const VideoEndpoint &endpoint, const GroupCall::VideoTrack &track) { using namespace rpl::mappers; const auto row = _members->lookupRow(track.peer); Assert(row != nullptr); - _viewport->add( + viewport->add( endpoint, LargeVideoTrack{ track.track.get(), row }, _call->videoEndpointPinnedValue() | rpl::map(_1 == endpoint)); @@ -1138,7 +1138,7 @@ void Panel::setupVideo() { ) | rpl::start_with_next([=](const VideoEndpoint &endpoint) { if (_call->activeVideoTracks().contains(endpoint)) { // Add async (=> the participant row is definitely in Members). - crl::on_main(widget(), [=] { + crl::on_main(viewport->widget(), [=] { const auto &tracks = _call->activeVideoTracks(); const auto i = tracks.find(endpoint); if (i != end(tracks)) { @@ -1147,32 +1147,32 @@ void Panel::setupVideo() { }); } else { // Remove sync. - _viewport->remove(endpoint); + viewport->remove(endpoint); } - }, raw->lifetime()); + }, viewport->lifetime()); - raw->pinToggled( + viewport->pinToggled( ) | rpl::start_with_next([=](const VideoPinToggle &value) { _call->pinVideoEndpoint( value.pinned ? value.endpoint : VideoEndpoint{}); - }, raw->lifetime()); + }, viewport->lifetime()); - raw->clicks( + viewport->clicks( ) | rpl::filter([=] { return (_mode.current() == PanelMode::Default); }) | rpl::start_with_next([=] { enlargeVideo(); - }, raw->lifetime()); + }, viewport->lifetime()); - raw->qualityRequests( + viewport->qualityRequests( ) | rpl::start_with_next([=](const VideoQualityRequest &request) { _call->requestVideoQuality(request.endpoint, request.quality); - }, raw->lifetime()); + }, viewport->lifetime()); - raw->mouseInsideValue( + viewport->mouseInsideValue( ) | rpl::start_with_next([=](bool inside) { toggleWideControls(inside); - }, raw->lifetime()); + }, viewport->lifetime()); } void Panel::toggleWideControls(bool shown) { @@ -1808,9 +1808,7 @@ bool Panel::updateMode() { } _wideControlsShown = _showWideControls = true; _wideControlsAnimation.stop(); - if (wide) { - _viewport->setMode(mode, widget()); - } + _viewport->widget()->setVisible(wide); if (_members) { _members->setMode(mode); } diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.h b/Telegram/SourceFiles/calls/group/calls_group_panel.h index 27b0606a3..4e56f2d42 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.h +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.h @@ -87,7 +87,7 @@ private: void initGeometry(); void setupScheduledLabels(rpl::producer date); void setupMembers(); - void setupVideo(); + void setupVideo(not_null viewport); void setupToasts(); void setupJoinAsChangedToasts(); void setupTitleChangedToasts(); diff --git a/Telegram/SourceFiles/calls/group/calls_group_viewport.cpp b/Telegram/SourceFiles/calls/group/calls_group_viewport.cpp index 4da576a4c..b0c8eb9ca 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_viewport.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_viewport.cpp @@ -241,9 +241,7 @@ void Viewport::showLarge(const VideoEndpoint &endpoint) { const auto large = (i != end(_tiles)) ? i->get() : nullptr; if (_large != large) { _large = large; - if (wide()) { - updateTilesGeometry(); - } + updateTilesGeometry(); } } @@ -387,6 +385,22 @@ void Viewport::updateTilesGeometryWide(int outerWidth, int outerHeight) { void Viewport::updateTilesGeometryNarrow(int outerWidth) { const auto y = -_scrollTop; + if (outerWidth <= st::groupCallNarrowMembersWidth) { + auto top = 0; + for (const auto &tile : _tiles) { + const auto video = tile.get(); + const auto size = video->trackSize(); + const auto shown = !size.isEmpty() && _large && video != _large; + const auto height = shown + ? st::groupCallNarrowVideoHeight + : 0; + video->setGeometry({ 0, y + top, outerWidth, height }); + top += height ? (height + st::groupCallVideoSmallSkip) : 0; + } + _fullHeight = top; + return; + } + auto sizes = base::flat_map, QSize>(); sizes.reserve(_tiles.size()); for (const auto &tile : _tiles) {