diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 5ce90423ed..5593233957 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2103,6 +2103,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_group_call_noise_suppression" = "Enable Noise Suppression"; "lng_group_call_limit#one" = "Video is only available\nfor the first {count} member"; "lng_group_call_limit#other" = "Video is only available\nfor the first {count} members"; +"lng_group_call_over_limit#one" = "The voice chat is over {count} member.\nNew participants only have access to audio stream."; +"lng_group_call_over_limit#other" = "The voice chat is over {count} members.\nNew participants only have access to audio stream."; "lng_group_call_video_paused" = "Video is paused"; "lng_group_call_share_speaker" = "Users with this link can speak"; "lng_group_call_copy_speaker_link" = "Copy Speaker Link"; diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index f4247f343a..ddbc02737a 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -742,6 +742,12 @@ groupCallTitleLabel: FlatLabel(groupCallSubtitleLabel) { linkFontOver: font(semibold 14px); } } +groupCallVideoLimitLabel: FlatLabel(defaultFlatLabel) { + align: align(top); + textFg: groupCallMemberNotJoinedStatus; + style: semiboldTextStyle; + minWidth: 96px; +} groupCallAddButtonPosition: point(10px, 7px); groupCallMembersWidthMax: 480px; groupCallRecordingMark: 6px; diff --git a/Telegram/SourceFiles/calls/group/calls_group_members.cpp b/Telegram/SourceFiles/calls/group/calls_group_members.cpp index a3d35adfdd..c34947a0f9 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_members.cpp @@ -46,9 +46,16 @@ constexpr auto kUserpicBlurRadius = 8; using Row = MembersRow; +[[nodiscard]] int VideoParticipantsLimit(not_null session) { + return int(session->account().appConfig().get( + "groupcall_video_participants_max", + 30.)); +} + void SetupVideoPlaceholder( not_null widget, - not_null chat) { + not_null chat, + int limit) { struct State { QImage blurred; QImage rounded; @@ -128,9 +135,6 @@ void SetupVideoPlaceholder( size.width()); const auto skip = st::groupCallVideoLargeSkip; - const auto limit = chat->session().account().appConfig().get( - "groupcall_video_participants_max", - 30.); p.setPen(st::groupCallVideoTextFg); const auto text = QRect( skip, @@ -145,6 +149,22 @@ void SetupVideoPlaceholder( }, widget->lifetime()); } +void SetupVideoAboutLimit( + not_null widget, + not_null session, + int limit) { + const auto label = Ui::CreateChild( + widget.get(), + tr::lng_group_call_over_limit(lt_count, rpl::single(limit * 1.)), + st::groupCallVideoLimitLabel); + widget->widthValue( + ) | rpl::start_with_next([=](int width) { + label->resizeToWidth(width); + label->moveToLeft(0, st::normalFont->height / 3); + widget->resize(width, label->height() + st::normalFont->height); + }, label->lifetime()); +} + } // namespace class Members::Controller final @@ -1605,6 +1625,7 @@ Members::Members( object_ptr(_scroll.data()))) , _videoWrap(_layout->add(object_ptr(_layout.get()))) , _videoPlaceholder(std::make_unique(_videoWrap.get())) +, _videoAboutLimit(std::make_unique(_videoWrap.get())) , _viewport( std::make_unique( _videoWrap.get(), @@ -1842,6 +1863,7 @@ void Members::trackViewportGeometry() { _scroll->scrollTopValue( ) | rpl::skip(1) | rpl::start_with_next(move, _viewport->lifetime()); + const auto videoLimit = VideoParticipantsLimit(&_call->peer()->session()); rpl::combine( _layout->widthValue(), _call->hasNotShownVideoValue() @@ -1850,15 +1872,53 @@ void Members::trackViewportGeometry() { _videoPlaceholder->setGeometry(0, 0, width, height); }, _videoPlaceholder->lifetime()); - SetupVideoPlaceholder(_videoPlaceholder.get(), _call->peer()); + SetupVideoPlaceholder(_videoPlaceholder.get(), _call->peer(), videoLimit); + + _layout->widthValue( + ) | rpl::start_with_next([=](int width) { + _videoAboutLimit->resizeToWidth(width); + }, _videoAboutLimit->lifetime()); + + using namespace rpl::mappers; + auto aboutLimitRelevant = fullCountValue( + ) | rpl::map( + _1 > videoLimit + ) | rpl::distinct_until_changed(); + auto aboutLimitShown = rpl::combine( + std::move(aboutLimitRelevant), + _call->canManageValue(), + _1 && _2); + + SetupVideoAboutLimit( + _videoAboutLimit.get(), + &_call->peer()->session(), + videoLimit); rpl::combine( _videoPlaceholder->heightValue(), - _viewport->fullHeightValue() - ) | rpl::start_with_next([=](int placeholder, int viewport) { + _viewport->fullHeightValue(), + _videoAboutLimit->heightValue(), + std::move(aboutLimitShown) + ) | rpl::start_with_next([=]( + int placeholder, + int viewport, + int aboutLimit, + bool aboutLimitShown) { + if (placeholder > 0 || viewport <= 0 || !aboutLimitShown) { + aboutLimitShown = false; + aboutLimit = 0; + } + + // This call may update _videoAboutLimit->height() :( + _videoAboutLimit->setVisible(aboutLimitShown); + + _videoAboutLimit->move(0, viewport); _videoWrap->resize( _videoWrap->width(), - std::max(placeholder, viewport)); + std::max( + placeholder, + (viewport + + (aboutLimitShown ? _videoAboutLimit->height() : 0)))); if (viewport > 0) { move(); resize(); diff --git a/Telegram/SourceFiles/calls/group/calls_group_members.h b/Telegram/SourceFiles/calls/group/calls_group_members.h index 198fdcaad3..bb8c2a8130 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members.h +++ b/Telegram/SourceFiles/calls/group/calls_group_members.h @@ -102,6 +102,7 @@ private: not_null _layout; const not_null _videoWrap; const std::unique_ptr _videoPlaceholder; + const std::unique_ptr _videoAboutLimit; std::unique_ptr _viewport; rpl::variable _addMemberButton = nullptr; RpWidget *_topSkip = nullptr;