diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 5f525b01a..bdd02cc73 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -818,14 +818,6 @@ groupCallSettingsSmall: CallButton(groupCallSettings) { } bgPosition: point(8px, 12px); } -groupCallShareSmall: CallButton(groupCallShare) { - button: IconButton(groupCallShareInner) { - width: 60px; - height: 68px; - rippleAreaPosition: point(8px, 12px); - } - bgPosition: point(8px, 12px); -} groupCallHangupSmall: CallButton(groupCallHangup) { button: IconButton(groupCallHangupInner) { width: 60px; @@ -834,13 +826,12 @@ groupCallHangupSmall: CallButton(groupCallHangup) { } bgPosition: point(8px, 12px); } -groupCallVideoSmall: CallButton(groupCallShareSmall) { +groupCallVideoSmall: CallButton(groupCallSettingsSmall) { button: IconButton(groupCallVideoInner) { width: 60px; height: 68px; rippleAreaPosition: point(8px, 12px); } - bgPosition: point(8px, 12px); } groupCallVideoActiveSmall: CallButton(groupCallVideoSmall) { button: IconButton(groupCallVideoInnerActive) { @@ -848,16 +839,14 @@ groupCallVideoActiveSmall: CallButton(groupCallVideoSmall) { height: 68px; rippleAreaPosition: point(8px, 12px); } - bgPosition: point(8px, 12px); } -groupCallScreenShareSmall: CallButton(groupCallShareSmall) { +groupCallScreenShareSmall: CallButton(groupCallSettingsSmall) { button: IconButton(groupCallSettingsInner) { icon: icon {{ "calls/calls_present", groupCallIconFg }}; width: 60px; height: 68px; rippleAreaPosition: point(8px, 12px); } - bgPosition: point(8px, 12px); } groupCallButtonSkip: 40px; groupCallButtonSkipSmall: 5px; diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp index b0674d760..a5ab0e7f8 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp @@ -647,6 +647,7 @@ void Panel::initControls() { initShareAction(); refreshLeftButton(); + refreshVideoButtons(); _hangup->setClickedCallback([=] { endCall(); }); @@ -677,6 +678,7 @@ void Panel::initControls() { }, _callLifetime); std::move(started) | rpl::start_with_next([=] { + refreshVideoButtons(); updateButtonsStyles(); setupMembers(); }, _callLifetime); @@ -727,14 +729,29 @@ void Panel::refreshLeftButton() { } const auto raw = _callShare ? _callShare.data() : _settings.data(); raw->show(); + raw->setColorOverrides(_mute->colorOverrides()); +} - auto overrides = _mute->colorOverrides(); - raw->setColorOverrides(rpl::duplicate(overrides)); - +void Panel::refreshVideoButtons(std::optional overrideWideMode) { + const auto real = _call->lookupReal(); + const auto canStartVideo = !_call->scheduleDate() + && real + && real->canStartVideo(); + const auto create = overrideWideMode.value_or(mode() == PanelMode::Wide) + || canStartVideo; + const auto created = _video && _screenShare; + if (created == create) { + return; + } else if (created) { + _video.destroy(); + _screenShare.destroy(); + updateButtonsGeometry(); + return; + } auto toggleableOverrides = [&](rpl::producer active) { return rpl::combine( std::move(active), - rpl::duplicate(overrides) + _mute->colorOverrides() ) | rpl::map([](bool active, Ui::CallButtonColors colors) { if (active && colors.bg) { colors.bg->setAlpha(kOverrideActiveColorBgAlpha); @@ -772,6 +789,7 @@ void Panel::refreshLeftButton() { }, _screenShare->lifetime()); } updateButtonsStyles(); + updateButtonsGeometry(); } void Panel::initShareAction() { @@ -1336,6 +1354,11 @@ void Panel::subscribeToChanges(not_null real) { _menuToggle.destroy(); _joinAsToggle.destroy(); } + real->canStartVideoValue( + ) | rpl::start_with_next([=] { + refreshVideoButtons(); + }, widget()->lifetime()); + updateControlsGeometry(); } @@ -1666,6 +1689,7 @@ bool Panel::updateMode() { if (!wide && _call->videoEndpointPinned()) { _call->pinVideoEndpoint({}); } + refreshVideoButtons(wide); _mode = mode; if (_title) { _title->setTextColorOverride(wide @@ -1712,14 +1736,6 @@ void Panel::updateButtonsStyles() { ? st::groupCallSettingsSmall : st::groupCallSettings); } - if (_callShare) { - _callShare->setText(wide - ? rpl::single(QString()) - : tr::lng_group_call_share_button()); - _callShare->setStyle(wide - ? st::groupCallShareSmall - : st::groupCallShare); - } _hangup->setText(wide ? rpl::single(QString()) : _call->scheduleDate() @@ -1898,7 +1914,6 @@ void Panel::trackControls(bool track) { trackOne(_video); trackOne(_screenShare); trackOne(_settings); - trackOne(_callShare); trackOne(_hangup); trackOne(_controlsBackgroundWide); } @@ -1935,6 +1950,9 @@ void Panel::updateControlsGeometry() { } void Panel::updateButtonsGeometry() { + if (widget()->size().isEmpty() || (!_settings && !_callShare)) { + return; + } const auto toggle = [&](bool shown) { const auto toggleOne = [&](auto &widget) { if (widget && widget->isHidden() == shown) { @@ -1949,6 +1967,11 @@ void Panel::updateButtonsGeometry() { toggleOne(_hangup); }; if (mode() == PanelMode::Wide) { + Assert(_video != nullptr); + Assert(_screenShare != nullptr); + Assert(_settings != nullptr); + Assert(_callShare == nullptr); + const auto shown = _wideControlsAnimation.value( _wideControlsShown ? 1. : 0.); toggle(shown > 0.); @@ -1964,10 +1987,10 @@ void Panel::updateButtonsGeometry() { const auto addSkip = st::callMuteButtonSmall.active.outerRadius; const auto muteSize = _mute->innerSize().width() + 2 * addSkip; const auto skip = st::groupCallButtonSkipSmall; - const auto fullWidth = muteSize - + (_video ? _video->width() + skip : 0) - + (_screenShare ? _screenShare->width() + skip : 0) - + (_settings ? _settings : _callShare)->width() + skip + const auto fullWidth = (_video->width() + skip) + + (_screenShare->width() + skip) + + muteSize + + (_settings ->width() + skip) + _hangup->width() + skip; const auto membersSkip = st::groupCallNarrowSkip; const auto membersWidth = st::groupCallNarrowMembersWidth @@ -1976,27 +1999,17 @@ void Panel::updateButtonsGeometry() { - membersWidth - membersSkip - fullWidth) / 2; - if (_screenShare) { - _screenShare->setVisible(true); - _screenShare->moveToLeft(left, buttonsTop); - left += _screenShare->width() + skip; - } - if (_video) { - _video->moveToLeft(left, buttonsTop); - left += _video->width() + skip; - } + _screenShare->setVisible(true); + _screenShare->moveToLeft(left, buttonsTop); + left += _screenShare->width() + skip; + _screenShare->setVisible(true); + _video->moveToLeft(left, buttonsTop); + left += _video->width() + skip; _mute->moveInner({ left + addSkip, buttonsTop + addSkip }); left += muteSize + skip; - if (_settings) { - _settings->setVisible(true); - _settings->moveToLeft(left, buttonsTop); - left += _settings->width() + skip; - } - if (_callShare) { - _callShare->setVisible(true); - _callShare->moveToLeft(left, buttonsTop); - left += _callShare->width() + skip; - } + _settings->setVisible(true); + _settings->moveToLeft(left, buttonsTop); + left += _settings->width() + skip; _hangup->moveToLeft(left, buttonsTop); left += _hangup->width(); if (_controlsBackgroundWide) { @@ -2024,18 +2037,18 @@ void Panel::updateButtonsGeometry() { if (_screenShare) { _screenShare->setVisible(false); } + if (_callShare) { + _callShare->moveToLeft(leftButtonLeft, buttonsTop); + } if (_video) { + _video->setVisible(!_callShare); _video->setStyle(st::groupCallVideo, &st::groupCallVideoActive); _video->moveToLeft(leftButtonLeft, buttonsTop); } if (_settings) { - _settings->setVisible(!_video); + _settings->setVisible(!_callShare && !_video); _settings->moveToLeft(leftButtonLeft, buttonsTop); } - if (_callShare) { - _callShare->setVisible(!_video); - _callShare->moveToLeft(leftButtonLeft, buttonsTop); - } _hangup->moveToRight(leftButtonLeft, buttonsTop); } if (_controlsBackgroundNarrow) { diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.h b/Telegram/SourceFiles/calls/group/calls_group_panel.h index c89f6cbff..fd2231a09 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.h +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.h @@ -109,6 +109,8 @@ private: void setupControlsBackgroundNarrow(); void showControls(); void refreshLeftButton(); + void refreshVideoButtons( + std::optional overrideWideMode = std::nullopt); void refreshTilesGeometry(); void toggleWideControls(bool shown); diff --git a/Telegram/SourceFiles/calls/group/calls_group_viewport_raster.cpp b/Telegram/SourceFiles/calls/group/calls_group_viewport_raster.cpp index 8860bcadc..8236bc2af 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_viewport_raster.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_viewport_raster.cpp @@ -183,6 +183,7 @@ void Viewport::Renderer::paintTileControls( MembersRowStyle::LargeVideo); // Name. + row->lazyInitialize(st::groupCallMembersListItem); p.setPen(st::groupCallVideoTextFg); const auto hasWidth = width - st.iconPosition.x() - icon.width() diff --git a/Telegram/SourceFiles/data/data_group_call.cpp b/Telegram/SourceFiles/data/data_group_call.cpp index 588d90c3c..7aee12714 100644 --- a/Telegram/SourceFiles/data/data_group_call.cpp +++ b/Telegram/SourceFiles/data/data_group_call.cpp @@ -387,6 +387,7 @@ void GroupCall::applyCallFields(const MTPDgroupCall &data) { _recordStartDate = data.vrecord_start_date().value_or_empty(); _scheduleDate = data.vschedule_date().value_or_empty(); _scheduleStartSubscribed = data.is_schedule_start_subscribed(); + _canStartVideo = data.is_can_start_video(); _allParticipantsLoaded = (_serverParticipantsCount == _participants.size()); } diff --git a/Telegram/SourceFiles/data/data_group_call.h b/Telegram/SourceFiles/data/data_group_call.h index 298fc4b94..c1c915ab1 100644 --- a/Telegram/SourceFiles/data/data_group_call.h +++ b/Telegram/SourceFiles/data/data_group_call.h @@ -90,6 +90,12 @@ public: [[nodiscard]] rpl::producer scheduleStartSubscribedValue() const { return _scheduleStartSubscribed.value(); } + [[nodiscard]] bool canStartVideo() const { + return _canStartVideo.current(); + } + [[nodiscard]] rpl::producer canStartVideoValue() const { + return _canStartVideo.value(); + } void setPeer(not_null peer); @@ -205,6 +211,7 @@ private: rpl::variable _recordStartDate = 0; rpl::variable _scheduleDate = 0; rpl::variable _scheduleStartSubscribed = false; + rpl::variable _canStartVideo = false; base::flat_map _unknownSpokenSsrcs; base::flat_map _unknownSpokenPeerIds;