diff --git a/Telegram/SourceFiles/calls/calls_group_call.cpp b/Telegram/SourceFiles/calls/calls_group_call.cpp index 15ff367de3..c08b5b054c 100644 --- a/Telegram/SourceFiles/calls/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/calls_group_call.cpp @@ -183,7 +183,6 @@ void GroupCall::checkParticipants() { } } _instance->setSsrcs(std::move(ssrcs)); - _instance->setIsMuted(false); } void GroupCall::hangup() { @@ -342,9 +341,7 @@ void GroupCall::createAndStartController() { std::move(descriptor)); const auto raw = _instance.get(); - if (_muted.current()) { - raw->setIsMuted(_muted.current()); - } + raw->setIsMuted(_muted.current()); //raw->setAudioOutputDuckingEnabled(settings.callAudioDuckingEnabled()); } diff --git a/Telegram/SourceFiles/calls/calls_group_call.h b/Telegram/SourceFiles/calls/calls_group_call.h index 6286f3de57..23424ef2d7 100644 --- a/Telegram/SourceFiles/calls/calls_group_call.h +++ b/Telegram/SourceFiles/calls/calls_group_call.h @@ -53,7 +53,7 @@ public: return _muted.value(); } [[nodiscard]] bool joined() const { - return _mySsrc != 0; + return (_state.current() == State::Joined); } enum State { @@ -103,7 +103,7 @@ private: MTP::Sender _api; rpl::variable _state = State::Creating; - rpl::variable _muted = false; + rpl::variable _muted = true; bool _acceptFields = false; uint64 _id = 0; diff --git a/Telegram/SourceFiles/calls/calls_top_bar.cpp b/Telegram/SourceFiles/calls/calls_top_bar.cpp index 84f3111855..97f074714a 100644 --- a/Telegram/SourceFiles/calls/calls_top_bar.cpp +++ b/Telegram/SourceFiles/calls/calls_top_bar.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "calls/calls_instance.h" #include "calls/calls_signal_bars.h" #include "data/data_user.h" +#include "data/data_channel.h" #include "data/data_changes.h" #include "main/main_session.h" #include "boxes/abstract_box.h" @@ -77,10 +78,28 @@ void DebugInfoBox::updateText() { TopBar::TopBar( QWidget *parent, const base::weak_ptr &call) +: TopBar(parent, call, nullptr) { +} + +TopBar::TopBar( + QWidget *parent, + const base::weak_ptr &call) +: TopBar(parent, nullptr, call) { +} + +TopBar::TopBar( + QWidget *parent, + const base::weak_ptr &call, + const base::weak_ptr &groupCall) : RpWidget(parent) , _call(call) -, _durationLabel(this, st::callBarLabel) -, _signalBars(this, _call.get(), st::callBarSignalBars) +, _groupCall(groupCall) +, _durationLabel(_call + ? object_ptr(this, st::callBarLabel) + : object_ptr(nullptr)) +, _signalBars(_call + ? object_ptr(this, _call.get(), st::callBarSignalBars) + : object_ptr(nullptr)) , _fullInfoLabel(this, st::callBarInfoLabel) , _shortInfoLabel(this, st::callBarInfoLabel) , _hangupLabel(this, st::callBarLabel, tr::lng_call_bar_hangup(tr::now).toUpper()) @@ -95,22 +114,31 @@ void TopBar::initControls() { _mute->setClickedCallback([=] { if (const auto call = _call.get()) { call->setMuted(!call->muted()); + } else if (const auto group = _groupCall.get()) { + group->setMuted(!group->muted()); } }); - _call->mutedValue( + + auto muted = _call + ? _call->mutedValue() + : _groupCall->mutedValue(); + std::move( + muted ) | rpl::start_with_next([=](bool muted) { setMuted(muted); update(); }, lifetime()); - _call->user()->session().changes().peerUpdates( - Data::PeerUpdate::Flag::Name - ) | rpl::filter([=](const Data::PeerUpdate &update) { - // _user may change for the same Panel. - return (_call != nullptr) && (update.peer == _call->user()); - }) | rpl::start_with_next([=] { - updateInfoLabels(); - }, lifetime()); + if (const auto call = _call.get()) { + call->user()->session().changes().peerUpdates( + Data::PeerUpdate::Flag::Name + ) | rpl::filter([=](const Data::PeerUpdate &update) { + // _user may change for the same Panel. + return (_call != nullptr) && (update.peer == _call->user()); + }) | rpl::start_with_next([=] { + updateInfoLabels(); + }, lifetime()); + } setInfoLabels(); _info->setClickedCallback([=] { @@ -121,11 +149,15 @@ void TopBar::initControls() { } else { Core::App().calls().showInfoPanel(call); } + } else if (const auto group = _groupCall.get()) { + Core::App().calls().showInfoPanel(group); } }); _hangup->setClickedCallback([this] { - if (auto call = _call.get()) { + if (const auto call = _call.get()) { call->hangup(); + } else if (const auto group = _groupCall.get()) { + group->hangup(); } }); _updateDurationTimer.setCallback([this] { updateDurationText(); }); @@ -144,6 +176,11 @@ void TopBar::setInfoLabels() { const auto shortName = user->firstName; _fullInfoLabel->setText(fullName.toUpper()); _shortInfoLabel->setText(shortName.toUpper()); + } else if (const auto group = _groupCall.get()) { + const auto channel = group->channel(); + const auto name = channel->name; + _fullInfoLabel->setText(name.toUpper()); + _shortInfoLabel->setText(name.toUpper()); } } @@ -155,7 +192,7 @@ void TopBar::setMuted(bool mute) { } void TopBar::updateDurationText() { - if (!_call) { + if (!_call || !_durationLabel) { return; } auto wasWidth = _durationLabel->width(); @@ -181,10 +218,14 @@ void TopBar::updateControlsGeometry() { auto left = 0; _mute->moveToLeft(left, 0); left += _mute->width(); - _durationLabel->moveToLeft(left, st::callBarLabelTop); - left += _durationLabel->width() + st::callBarSkip; - _signalBars->moveToLeft(left, (height() - _signalBars->height()) / 2); - left += _signalBars->width() + st::callBarSkip; + if (_durationLabel) { + _durationLabel->moveToLeft(left, st::callBarLabelTop); + left += _durationLabel->width() + st::callBarSkip; + } + if (_signalBars) { + _signalBars->moveToLeft(left, (height() - _signalBars->height()) / 2); + left += _signalBars->width() + st::callBarSkip; + } auto right = st::callBarRightSkip; _hangupLabel->moveToRight(right, st::callBarLabelTop); diff --git a/Telegram/SourceFiles/calls/calls_top_bar.h b/Telegram/SourceFiles/calls/calls_top_bar.h index 72ae98e1fa..20c9641879 100644 --- a/Telegram/SourceFiles/calls/calls_top_bar.h +++ b/Telegram/SourceFiles/calls/calls_top_bar.h @@ -26,11 +26,13 @@ class Session; namespace Calls { class Call; +class GroupCall; class SignalBars; class TopBar : public Ui::RpWidget { public: TopBar(QWidget *parent, const base::weak_ptr &call); + TopBar(QWidget *parent, const base::weak_ptr &call); ~TopBar(); @@ -39,6 +41,11 @@ protected: void paintEvent(QPaintEvent *e) override; private: + TopBar( + QWidget *parent, + const base::weak_ptr &call, + const base::weak_ptr &groupCall); + void initControls(); void updateInfoLabels(); void setInfoLabels(); @@ -48,6 +55,7 @@ private: void setMuted(bool mute); const base::weak_ptr _call; + const base::weak_ptr _groupCall; bool _muted = false; object_ptr _durationLabel; diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 47a09086a5..b150fdda2e 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -682,10 +682,14 @@ void ChannelData::setCall(const MTPInputGroupCall &call) { clearCall(); return; } + if (_call) { + owner().unregisterGroupCall(_call.get()); + } _call = std::make_unique( this, data.vid().v, data.vaccess_hash().v); + owner().registerGroupCall(_call.get()); session().changes().peerUpdated(this, UpdateFlag::GroupCall); }); } @@ -694,6 +698,7 @@ void ChannelData::clearCall() { if (!_call) { return; } + owner().unregisterGroupCall(_call.get()); _call = nullptr; session().changes().peerUpdated(this, UpdateFlag::GroupCall); } diff --git a/Telegram/SourceFiles/history/view/history_view_group_call_tracker.cpp b/Telegram/SourceFiles/history/view/history_view_group_call_tracker.cpp index 9712d559f0..39de068eb6 100644 --- a/Telegram/SourceFiles/history/view/history_view_group_call_tracker.cpp +++ b/Telegram/SourceFiles/history/view/history_view_group_call_tracker.cpp @@ -12,6 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_group_call.h" #include "main/main_session.h" #include "ui/chat/group_call_bar.h" +#include "calls/calls_group_call.h" +#include "calls/calls_instance.h" +#include "core/application.h" namespace HistoryView { @@ -21,12 +24,15 @@ GroupCallTracker::GroupCallTracker(not_null channel) rpl::producer GroupCallTracker::content() const { const auto channel = _channel; - return channel->session().changes().peerFlagsValue( - channel, - Data::PeerUpdate::Flag::GroupCall - ) | rpl::map([=]() -> Ui::GroupCallBarContent { + return rpl::combine( + channel->session().changes().peerFlagsValue( + channel, + Data::PeerUpdate::Flag::GroupCall), + Core::App().calls().currentGroupCallValue() + ) | rpl::map([=](const auto&, Calls::GroupCall *current) + -> Ui::GroupCallBarContent { const auto call = channel->call(); - if (!call) { + if (!call || (current && current->channel() == channel)) { return { .shown = false }; } else if (!call->fullCount() && !call->participantsLoaded()) { call->requestParticipants(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index c3b2a27f96..c0d7423fce 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -254,6 +254,10 @@ MainWidget::MainWidget( ) | rpl::start_with_next([=](Calls::Call *call) { setCurrentCall(call); }, lifetime()); + Core::App().calls().currentGroupCallValue( + ) | rpl::start_with_next([=](Calls::GroupCall *call) { + setCurrentGroupCall(call); + }, lifetime()); if (_callTopBar) { _callTopBar->finishAnimating(); } @@ -942,6 +946,9 @@ void MainWidget::playerHeightUpdated() { } void MainWidget::setCurrentCall(Calls::Call *call) { + if (!call && _currentGroupCall) { + return; + } _currentCallLifetime.destroy(); _currentCall = call; if (_currentCall) { @@ -959,10 +966,35 @@ void MainWidget::setCurrentCall(Calls::Call *call) { } } -void MainWidget::createCallTopBar() { - Expects(_currentCall != nullptr); +void MainWidget::setCurrentGroupCall(Calls::GroupCall *call) { + if (!call && _currentCall) { + return; + } + _currentCallLifetime.destroy(); + _currentGroupCall = call; + if (_currentGroupCall) { + _currentGroupCall->stateValue( + ) | rpl::start_with_next([=](Calls::GroupCall::State state) { + using State = Calls::GroupCall::State; + if (state == State::Joined) { + createCallTopBar(); + } else { + destroyCallTopBar(); + } + }, _currentCallLifetime); + } else { + destroyCallTopBar(); + } +} - _callTopBar.create(this, object_ptr(this, _currentCall)); +void MainWidget::createCallTopBar() { + Expects(_currentCall != nullptr || _currentGroupCall != nullptr); + + _callTopBar.create( + this, + (_currentCall + ? object_ptr(this, _currentCall) + : object_ptr(this, _currentGroupCall))); _callTopBar->heightValue( ) | rpl::start_with_next([this](int value) { callTopBarHeightUpdated(value); @@ -986,7 +1018,7 @@ void MainWidget::destroyCallTopBar() { } void MainWidget::callTopBarHeightUpdated(int callTopBarHeight) { - if (!callTopBarHeight && !_currentCall) { + if (!callTopBarHeight && !_currentCall && !_currentGroupCall) { _callTopBar.destroyDelayed(); } if (callTopBarHeight != _callTopBarHeight) { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 67f62919bc..6a1f0e666c 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -85,6 +85,7 @@ class HistoryHider; namespace Calls { class Call; +class GroupCall; class TopBar; } // namespace Calls @@ -257,6 +258,7 @@ private: void playerHeightUpdated(); void setCurrentCall(Calls::Call *call); + void setCurrentGroupCall(Calls::GroupCall *call); void createCallTopBar(); void destroyCallTopBar(); void callTopBarHeightUpdated(int callTopBarHeight); @@ -350,6 +352,7 @@ private: std::unique_ptr _connecting; base::weak_ptr _currentCall; + base::weak_ptr _currentGroupCall; rpl::lifetime _currentCallLifetime; object_ptr> _callTopBar = { nullptr }; diff --git a/Telegram/SourceFiles/media/player/media_player_instance.cpp b/Telegram/SourceFiles/media/player/media_player_instance.cpp index 673f814900..7d3016df3d 100644 --- a/Telegram/SourceFiles/media/player/media_player_instance.cpp +++ b/Telegram/SourceFiles/media/player/media_player_instance.cpp @@ -114,8 +114,12 @@ Instance::Instance() handleSongUpdate(audioId); }); - Core::App().calls().currentCallValue( - ) | rpl::start_with_next([=](Calls::Call *call) { + using namespace rpl::mappers; + rpl::combine( + Core::App().calls().currentCallValue(), + Core::App().calls().currentGroupCallValue(), + _1 || _2 + ) | rpl::start_with_next([=](bool call) { if (call) { pauseOnCall(AudioMsgId::Type::Voice); pauseOnCall(AudioMsgId::Type::Song); diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 1036ae393e..d6c8fc1413 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -395,8 +395,12 @@ OverlayWidget::OverlayWidget() _touchbarFullscreenToggled.events()); #endif // Q_OS_MAC && !OS_OSX - Core::App().calls().currentCallValue( - ) | rpl::start_with_next([=](Calls::Call *call) { + using namespace rpl::mappers; + rpl::combine( + Core::App().calls().currentCallValue(), + Core::App().calls().currentGroupCallValue(), + _1 || _2 + ) | rpl::start_with_next([=](bool call) { if (!_streamed || videoIsGifOrUserpic()) { return; } else if (call) {