From b8f23bda59260dc5ca80e84757372cbe194dd9ce Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 27 Nov 2020 18:51:24 +0300 Subject: [PATCH] Allow to toggle group call members mute. --- Telegram/SourceFiles/boxes/peer_list_box.cpp | 8 ++--- Telegram/SourceFiles/boxes/peer_list_box.h | 5 ++- .../SourceFiles/calls/calls_group_call.cpp | 21 +++++++++++ Telegram/SourceFiles/calls/calls_group_call.h | 2 ++ .../SourceFiles/calls/calls_group_members.cpp | 36 ++++++++++++++++--- .../SourceFiles/calls/calls_group_members.h | 8 ++++- .../SourceFiles/calls/calls_group_panel.cpp | 7 ++++ 7 files changed, 76 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index 922a1bdcf3..8754a149e9 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -1150,7 +1150,7 @@ void PeerListContent::mousePressEvent(QMouseEvent *e) { updateRow(row, hint); }; if (_selected.action) { - auto actionRect = getActionRect(row, _selected.index); + auto actionRect = getActiveActionRect(row, _selected.index); if (!actionRect.isEmpty()) { auto point = mapFromGlobal(QCursor::pos()) - actionRect.topLeft(); row->addActionRipple(point, std::move(updateCallback)); @@ -1627,7 +1627,7 @@ void PeerListContent::selectByMouse(QPoint globalPosition) { if (row->disabled()) { selected = Selected(); } else { - if (getActionRect(row, selected.index).contains(point)) { + if (getActiveActionRect(row, selected.index).contains(point)) { selected.action = true; } } @@ -1635,9 +1635,9 @@ void PeerListContent::selectByMouse(QPoint globalPosition) { setSelected(selected); } -QRect PeerListContent::getActionRect(not_null row, RowIndex index) const { +QRect PeerListContent::getActiveActionRect(not_null row, RowIndex index) const { auto actionSize = row->actionSize(); - if (actionSize.isEmpty()) { + if (actionSize.isEmpty() || row->actionDisabled()) { return QRect(); } auto actionMargins = row->actionMargins(); diff --git a/Telegram/SourceFiles/boxes/peer_list_box.h b/Telegram/SourceFiles/boxes/peer_list_box.h index 36df9e66ce..189c379f81 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.h +++ b/Telegram/SourceFiles/boxes/peer_list_box.h @@ -102,6 +102,9 @@ public: virtual QSize actionSize() const { return QSize(); } + virtual bool actionDisabled() const { + return false; + } virtual QMargins actionMargins() const { return QMargins(); } @@ -607,7 +610,7 @@ private: int getRowTop(RowIndex row) const; PeerListRow *getRow(RowIndex element); RowIndex findRowIndex(not_null row, RowIndex hint = RowIndex()); - QRect getActionRect(not_null row, RowIndex index) const; + QRect getActiveActionRect(not_null row, RowIndex index) const; crl::time paintRow(Painter &p, crl::time ms, RowIndex index); diff --git a/Telegram/SourceFiles/calls/calls_group_call.cpp b/Telegram/SourceFiles/calls/calls_group_call.cpp index 4a65adaf1c..08838d9164 100644 --- a/Telegram/SourceFiles/calls/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/calls_group_call.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/application.h" #include "core/core_settings.h" #include "data/data_changes.h" +#include "data/data_user.h" #include "data/data_channel.h" #include "data/data_group_call.h" @@ -395,8 +396,10 @@ void GroupCall::sendMutedUpdate() { inputCall(), MTP_inputUserSelf() )).done([=](const MTPUpdates &result) { + _updateMuteRequestId = 0; _channel->session().api().applyUpdates(result); }).fail([=](const RPCError &error) { + _updateMuteRequestId = 0; if (error.type() == u"GROUP_CALL_FORBIDDEN"_q && _state.current() == State::Joined) { setState(State::Joining); @@ -416,6 +419,24 @@ void GroupCall::setCurrentAudioDevice(bool input, const QString &deviceId) { } } +void GroupCall::toggleMute(not_null user, bool mute) { + _api.request(MTPphone_EditGroupCallMember( + MTP_flags(mute + ? MTPphone_EditGroupCallMember::Flag::f_muted + : MTPphone_EditGroupCallMember::Flag(0)), + inputCall(), + user->inputUser + )).done([=](const MTPUpdates &result) { + _channel->session().api().applyUpdates(result); + }).fail([=](const RPCError &error) { + if (error.type() == u"GROUP_CALL_FORBIDDEN"_q + && _state.current() == State::Joined) { + setState(State::Joining); + rejoin(); + } + }).send(); +} + //void GroupCall::setAudioVolume(bool input, float level) { // if (_instance) { // if (input) { diff --git a/Telegram/SourceFiles/calls/calls_group_call.h b/Telegram/SourceFiles/calls/calls_group_call.h index fe348e678d..2a5495ae14 100644 --- a/Telegram/SourceFiles/calls/calls_group_call.h +++ b/Telegram/SourceFiles/calls/calls_group_call.h @@ -80,6 +80,8 @@ public: //void setAudioVolume(bool input, float level); void setAudioDuckingEnabled(bool enabled); + void toggleMute(not_null user, bool mute); + [[nodiscard]] rpl::lifetime &lifetime() { return _lifetime; } diff --git a/Telegram/SourceFiles/calls/calls_group_members.cpp b/Telegram/SourceFiles/calls/calls_group_members.cpp index 3edf6f2d40..a26f63e790 100644 --- a/Telegram/SourceFiles/calls/calls_group_members.cpp +++ b/Telegram/SourceFiles/calls/calls_group_members.cpp @@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/ripple_animation.h" #include "main/main_session.h" #include "lang/lang_keys.h" +#include "facades.h" #include "styles/style_calls.h" namespace Calls { @@ -35,6 +36,9 @@ public: }; void updateState(const Data::GroupCall::Participant *participant); + [[nodiscard]] State state() const { + return _state; + } void addActionRipple(QPoint point, Fn updateCallback) override; void stopLastActionRipple() override; @@ -45,6 +49,9 @@ public: QSize actionSize() const override { return QSize(_st->width, _st->height); } + bool actionDisabled() const override { + return peer()->isSelf() || !_channel->amCreator(); + } QMargins actionMargins() const override { return QMargins( 0, @@ -70,6 +77,7 @@ private: State state); State _state = State::Inactive; + not_null _channel; not_null _st; std::unique_ptr _actionRipple; @@ -82,6 +90,8 @@ class MembersController final public: explicit MembersController(not_null call); + using MuteRequest = GroupMembers::MuteRequest; + Main::Session &session() const override; void prepare() override; void rowClicked(not_null row) override; @@ -94,9 +104,9 @@ public: [[nodiscard]] rpl::producer fullCountValue() const { return _fullCount.value(); } + [[nodiscard]] rpl::producer toggleMuteRequests() const; private: - [[nodiscard]] std::unique_ptr createSelfRow() const; [[nodiscard]] std::unique_ptr createRow( const Data::GroupCall::Participant &participant) const; @@ -114,6 +124,7 @@ private: const base::weak_ptr _call; const not_null _channel; + rpl::event_stream _toggleMuteRequests; rpl::variable _fullCount = 1; Ui::BoxPointer _addBox; rpl::lifetime _lifetime; @@ -123,6 +134,7 @@ private: Row::Row(not_null channel, not_null user) : PeerListRow(user) , _state(ComputeState(channel, user)) +, _channel(channel) , _st(ComputeIconStyle(_state)) { refreshStatus(); } @@ -384,17 +396,25 @@ void MembersController::loadMoreRows() { } } -void MembersController::rowClicked(not_null row) { - Expects(row->peer()->isUser()); +auto MembersController::toggleMuteRequests() const +-> rpl::producer { + return _toggleMuteRequests.events(); +} - const auto user = row->peer()->asUser(); +void MembersController::rowClicked(not_null row) { + Ui::showPeerHistory(row->peer(), ShowAtUnreadMsgId); } void MembersController::rowActionClicked( not_null row) { Expects(row->peer()->isUser()); - const auto user = row->peer()->asUser(); + const auto real = static_cast(row.get()); + const auto mute = (real->state() != Row::State::Muted); + _toggleMuteRequests.fire(MuteRequest{ + .user = row->peer()->asUser(), + .mute = mute, + }); } base::unique_qptr MembersController::rowContextMenu( @@ -440,6 +460,12 @@ GroupMembers::GroupMembers( }, lifetime()); } +auto GroupMembers::toggleMuteRequests() const +-> rpl::producer { + return static_cast( + _listController.get())->toggleMuteRequests(); +} + int GroupMembers::desiredHeight() const { auto desired = _header ? _header->height() : 0; auto count = [this] { diff --git a/Telegram/SourceFiles/calls/calls_group_members.h b/Telegram/SourceFiles/calls/calls_group_members.h index 7883c6120b..5b6d39df64 100644 --- a/Telegram/SourceFiles/calls/calls_group_members.h +++ b/Telegram/SourceFiles/calls/calls_group_members.h @@ -29,7 +29,13 @@ public: QWidget *parent, not_null call); - int desiredHeight() const; + struct MuteRequest { + not_null user; + bool mute = false; + }; + + [[nodiscard]] int desiredHeight() const; + [[nodiscard]] rpl::producer toggleMuteRequests() const; private: using ListWidget = PeerListContent; diff --git a/Telegram/SourceFiles/calls/calls_group_panel.cpp b/Telegram/SourceFiles/calls/calls_group_panel.cpp index 5e6cc20f44..e7e0bd3d19 100644 --- a/Telegram/SourceFiles/calls/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_group_panel.cpp @@ -342,6 +342,13 @@ void GroupPanel::initWithCall(GroupCall *call) { ) | rpl::start_with_next([=] { updateControlsGeometry(); }, _members->lifetime()); + + _members->toggleMuteRequests( + ) | rpl::start_with_next([=](GroupMembers::MuteRequest request) { + if (_call) { + _call->toggleMute(request.user, request.mute); + } + }, _callLifetime); } void GroupPanel::initLayout() {