From d18b29efb827a17f95c77b5daaf9a8758e3c8fcc Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 28 Nov 2020 10:18:46 +0300 Subject: [PATCH] Track three-state muted value. --- .../SourceFiles/calls/calls_group_call.cpp | 21 ++++++++++++------- Telegram/SourceFiles/calls/calls_group_call.h | 14 +++++++++---- .../SourceFiles/calls/calls_group_panel.cpp | 21 ++++++++++++++----- Telegram/SourceFiles/calls/calls_top_bar.cpp | 21 +++++++++++++++++-- 4 files changed, 59 insertions(+), 18 deletions(-) diff --git a/Telegram/SourceFiles/calls/calls_group_call.cpp b/Telegram/SourceFiles/calls/calls_group_call.cpp index a99229d5ba..4026beaaa0 100644 --- a/Telegram/SourceFiles/calls/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/calls_group_call.cpp @@ -148,7 +148,7 @@ void GroupCall::rejoin() { QJsonDocument::Compact); const auto muted = _muted.current(); _api.request(MTPphone_JoinGroupCall( - MTP_flags(muted + MTP_flags((muted != MuteState::Active) ? MTPphone_JoinGroupCall::Flag::f_muted : MTPphone_JoinGroupCall::Flag(0)), inputCall(), @@ -181,7 +181,9 @@ void GroupCall::applySelfInCallLocally() { using Flag = MTPDgroupCallParticipant::Flag; return MTP_groupCallParticipant( MTP_flags((_mySsrc ? Flag(0) : Flag::f_left) - | (_muted.current() ? Flag::f_muted : Flag(0))), + | ((_muted.current() != MuteState::Active) + ? Flag::f_muted + : Flag(0))), MTP_int(self), MTP_int(now), MTP_int(0), @@ -233,7 +235,7 @@ void GroupCall::finish(FinishType type) { }).send(); } -void GroupCall::setMuted(bool mute) { +void GroupCall::setMuted(MuteState mute) { _muted = mute; } @@ -334,6 +336,11 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) { _mySsrc = 0; hangup(); } + if (data.is_muted() && !data.is_can_self_unmute()) { + setMuted(MuteState::ForceMuted); + } else if (muted() == MuteState::ForceMuted) { + setMuted(MuteState::Muted); + } }); } } @@ -377,11 +384,11 @@ void GroupCall::createAndStartController() { std::move(descriptor)); _muted.value( - ) | rpl::start_with_next([=](bool muted) { + ) | rpl::start_with_next([=](MuteState state) { if (_instance) { - _instance->setIsMuted(muted); + _instance->setIsMuted(state != MuteState::Active); } - if (_mySsrc) { + if (_mySsrc && state != MuteState::ForceMuted) { sendMutedUpdate(); } }, _lifetime); @@ -397,7 +404,7 @@ void GroupCall::myLevelUpdated(float level) { void GroupCall::sendMutedUpdate() { _api.request(_updateMuteRequestId).cancel(); _updateMuteRequestId = _api.request(MTPphone_EditGroupCallMember( - MTP_flags(_muted.current() + MTP_flags((_muted.current() != MuteState::Active) ? MTPphone_EditGroupCallMember::Flag::f_muted : MTPphone_EditGroupCallMember::Flag(0)), inputCall(), diff --git a/Telegram/SourceFiles/calls/calls_group_call.h b/Telegram/SourceFiles/calls/calls_group_call.h index 7551e4a8ab..9069c7a374 100644 --- a/Telegram/SourceFiles/calls/calls_group_call.h +++ b/Telegram/SourceFiles/calls/calls_group_call.h @@ -19,6 +19,12 @@ class GroupInstanceImpl; namespace Calls { +enum class MuteState { + Active, + Muted, + ForceMuted, +}; + class GroupCall final : public base::has_weak_ptr { public: class Delegate { @@ -49,11 +55,11 @@ public: void handleUpdate(const MTPGroupCall &call); void handleUpdate(const MTPDupdateGroupCallParticipants &data); - void setMuted(bool mute); - [[nodiscard]] bool muted() const { + void setMuted(MuteState mute); + [[nodiscard]] MuteState muted() const { return _muted.current(); } - [[nodiscard]] rpl::producer mutedValue() const { + [[nodiscard]] rpl::producer mutedValue() const { return _muted.value(); } [[nodiscard]] bool joined() const { @@ -113,7 +119,7 @@ private: MTP::Sender _api; rpl::variable _state = State::Creating; - rpl::variable _muted = true; + rpl::variable _muted = MuteState::Muted; bool _acceptFields = false; uint64 _id = 0; diff --git a/Telegram/SourceFiles/calls/calls_group_panel.cpp b/Telegram/SourceFiles/calls/calls_group_panel.cpp index e7e0bd3d19..910ad48a61 100644 --- a/Telegram/SourceFiles/calls/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_group_panel.cpp @@ -297,9 +297,20 @@ void GroupPanel::initWidget() { } void GroupPanel::initControls() { + _call->mutedValue( + ) | rpl::start_with_next([=](MuteState state) { + if (state == MuteState::ForceMuted) { + _mute->clearState(); + } + _mute->setAttribute( + Qt::WA_TransparentForMouseEvents, + (state == MuteState::ForceMuted)); + }, _mute->lifetime()); _mute->setClickedCallback([=] { - if (_call) { - _call->setMuted(!_call->muted()); + if (_call && _call->muted() != MuteState::ForceMuted) { + _call->setMuted((_call->muted() == MuteState::Active) + ? MuteState::Muted + : MuteState::Active); } }); _hangup->setClickedCallback([=] { @@ -326,9 +337,9 @@ void GroupPanel::initWithCall(GroupCall *call) { _hangup->setText(tr::lng_box_leave()); _call->mutedValue( - ) | rpl::start_with_next([=](bool mute) { - _mute->setProgress(mute ? 1. : 0.); - _mute->setText(mute + ) | rpl::start_with_next([=](MuteState state) { + _mute->setProgress((state != MuteState::Active) ? 1. : 0.); + _mute->setText((state != MuteState::Active) ? tr::lng_call_unmute_audio() : tr::lng_call_mute_audio()); }, _callLifetime); diff --git a/Telegram/SourceFiles/calls/calls_top_bar.cpp b/Telegram/SourceFiles/calls/calls_top_bar.cpp index 97f074714a..e06097cedf 100644 --- a/Telegram/SourceFiles/calls/calls_top_bar.cpp +++ b/Telegram/SourceFiles/calls/calls_top_bar.cpp @@ -115,13 +115,18 @@ void TopBar::initControls() { if (const auto call = _call.get()) { call->setMuted(!call->muted()); } else if (const auto group = _groupCall.get()) { - group->setMuted(!group->muted()); + if (group->muted() != MuteState::ForceMuted) { + group->setMuted((group->muted() == MuteState::Active) + ? MuteState::Muted + : MuteState::Active); + } } }); + using namespace rpl::mappers; auto muted = _call ? _call->mutedValue() - : _groupCall->mutedValue(); + : (_groupCall->mutedValue() | rpl::map(_1 != MuteState::Active)); std::move( muted ) | rpl::start_with_next([=](bool muted) { @@ -129,6 +134,18 @@ void TopBar::initControls() { update(); }, lifetime()); + if (_groupCall) { + _groupCall->mutedValue( + ) | rpl::start_with_next([=](MuteState state) { + if (state == MuteState::ForceMuted) { + _mute->clearState(); + } + _mute->setAttribute( + Qt::WA_TransparentForMouseEvents, + (state == MuteState::ForceMuted)); + }, _mute->lifetime()); + } + if (const auto call = _call.get()) { call->user()->session().changes().peerUpdates( Data::PeerUpdate::Flag::Name