From f6175e7b7c312394b14bdcc303f43ea54035581b Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 2 Sep 2021 11:04:28 +0300 Subject: [PATCH] Invite by link in case of non-self voice chat join. --- .../calls/group/calls_group_call.cpp | 56 +++++++++---------- .../calls/group/calls_group_call.h | 7 ++- .../calls/group/calls_group_members.cpp | 45 ++++++++++----- .../calls/group/calls_group_members.h | 1 + .../calls/group/calls_group_panel.cpp | 10 +++- 5 files changed, 72 insertions(+), 47 deletions(-) diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.cpp b/Telegram/SourceFiles/calls/group/calls_group_call.cpp index 0c9e0ff09e..50064d7504 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_call.cpp @@ -596,7 +596,7 @@ GroupCall::GroupCall( start(info.scheduleDate); } if (_scheduleDate) { - saveDefaultJoinAs(_joinAs); + saveDefaultJoinAs(joinAs()); } } @@ -740,7 +740,7 @@ void GroupCall::subscribeToReal(not_null real) { }; const auto peer = data.was ? data.was->peer : data.now->peer; - if (peer == _joinAs) { + if (peer == joinAs()) { const auto working = data.now && data.now->videoJoined; if (videoIsWorking() != working) { fillActiveVideoEndpoints(); @@ -1027,7 +1027,7 @@ void GroupCall::setScreenEndpoint(std::string endpoint) { if (!_screenEndpoint.empty()) { markEndpointActive({ VideoEndpointType::Screen, - _joinAs, + joinAs(), _screenEndpoint }, false, false); } @@ -1038,7 +1038,7 @@ void GroupCall::setScreenEndpoint(std::string endpoint) { if (isSharingScreen()) { markEndpointActive({ VideoEndpointType::Screen, - _joinAs, + joinAs(), _screenEndpoint }, true, isScreenPaused()); } @@ -1051,7 +1051,7 @@ void GroupCall::setCameraEndpoint(std::string endpoint) { if (!_cameraEndpoint.empty()) { markEndpointActive({ VideoEndpointType::Camera, - _joinAs, + joinAs(), _cameraEndpoint }, false, false); } @@ -1062,7 +1062,7 @@ void GroupCall::setCameraEndpoint(std::string endpoint) { if (isSharingCamera()) { markEndpointActive({ VideoEndpointType::Camera, - _joinAs, + joinAs(), _cameraEndpoint }, true, isCameraPaused()); } @@ -1189,7 +1189,7 @@ void GroupCall::markTrackPaused(const VideoEndpoint &endpoint, bool paused) { } void GroupCall::rejoin() { - rejoin(_joinAs); + rejoin(joinAs()); } void GroupCall::rejoinWithHash(const QString &hash) { @@ -1202,9 +1202,9 @@ void GroupCall::rejoinWithHash(const QString &hash) { void GroupCall::setJoinAs(not_null as) { _joinAs = as; if (const auto chat = _peer->asChat()) { - chat->setGroupCallDefaultJoinAs(_joinAs->id); + chat->setGroupCallDefaultJoinAs(joinAs()->id); } else if (const auto channel = _peer->asChannel()) { - channel->setGroupCallDefaultJoinAs(_joinAs->id); + channel->setGroupCallDefaultJoinAs(joinAs()->id); } } @@ -1212,7 +1212,7 @@ void GroupCall::saveDefaultJoinAs(not_null as) { setJoinAs(as); _api.request(MTPphone_SaveDefaultGroupCallJoinAs( _peer->input, - _joinAs->input + joinAs()->input )).send(); } @@ -1225,7 +1225,7 @@ void GroupCall::rejoin(not_null as) { return; } - if (_joinAs != as) { + if (joinAs() != as) { toggleVideo(false); toggleScreenSharing(std::nullopt); } @@ -1270,7 +1270,7 @@ void GroupCall::rejoin(not_null as) { _api.request(MTPphone_JoinGroupCall( MTP_flags(flags), inputCall(), - _joinAs->input, + joinAs()->input, MTP_string(_joinHash), MTP_dataJSON(MTP_bytes(json)) )).done([=](const MTPUpdates &updates) { @@ -1451,7 +1451,7 @@ void GroupCall::applyMeInCallLocally() { return; } using Flag = MTPDgroupCallParticipant::Flag; - const auto participant = real->participantByPeer(_joinAs); + const auto participant = real->participantByPeer(joinAs()); const auto date = participant ? participant->date : base::unixtime::now(); @@ -1483,7 +1483,7 @@ void GroupCall::applyMeInCallLocally() { 1, MTP_groupCallParticipant( MTP_flags(flags), - peerToMTP(_joinAs->id), + peerToMTP(joinAs()->id), MTP_int(date), MTP_int(lastActive), MTP_int(_joinState.ssrc), @@ -1519,7 +1519,7 @@ void GroupCall::applyParticipantLocally( | (participant->lastActive ? Flag::f_active_date : Flag(0)) | (isMuted ? Flag::f_muted : Flag(0)) | (isMutedByYou ? Flag::f_muted_by_you : Flag(0)) - | (participantPeer == _joinAs ? Flag::f_self : Flag(0)) + | (participantPeer == joinAs() ? Flag::f_self : Flag(0)) | (participant->raisedHandRating ? Flag::f_raise_hand_rating : Flag(0)); @@ -1566,11 +1566,11 @@ void GroupCall::discard() { void GroupCall::rejoinAs(Group::JoinInfo info) { _possibleJoinAs = std::move(info.possibleJoinAs); - if (info.joinAs == _joinAs) { + if (info.joinAs == joinAs()) { return; } const auto event = Group::RejoinEvent{ - .wasJoinAs = _joinAs, + .wasJoinAs = joinAs(), .nowJoinAs = info.joinAs, }; if (_scheduleDate) { @@ -1855,7 +1855,7 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) { participant.match([&](const MTPDgroupCallParticipant &data) { const auto isSelf = data.is_self() || (data.is_min() - && peerFromMTP(data.vpeer()) == _joinAs->id); + && peerFromMTP(data.vpeer()) == joinAs()->id); if (!isSelf) { applyOtherParticipantUpdate(data); } else if (joined) { @@ -2057,7 +2057,7 @@ void GroupCall::setupOutgoingVideo() { sendSelfUpdate(SendUpdateType::CameraPaused); markTrackPaused({ VideoEndpointType::Camera, - _joinAs, + joinAs(), _cameraEndpoint }, nowPaused); return; @@ -2092,7 +2092,7 @@ void GroupCall::setupOutgoingVideo() { _isSharingCamera = nowActive; markEndpointActive({ VideoEndpointType::Camera, - _joinAs, + joinAs(), _cameraEndpoint }, nowActive, nowPaused); sendSelfUpdate(SendUpdateType::CameraStopped); @@ -2113,7 +2113,7 @@ void GroupCall::setupOutgoingVideo() { sendSelfUpdate(SendUpdateType::ScreenPaused); markTrackPaused({ VideoEndpointType::Screen, - _joinAs, + joinAs(), _screenEndpoint }, nowPaused); return; @@ -2160,7 +2160,7 @@ void GroupCall::setupOutgoingVideo() { _isSharingScreen = nowActive; markEndpointActive({ VideoEndpointType::Screen, - _joinAs, + joinAs(), _screenEndpoint }, nowActive, nowPaused); _screenJoinState.nextActionPending = true; @@ -2607,7 +2607,7 @@ void GroupCall::fillActiveVideoEndpoints() { const auto real = lookupReal(); Assert(real != nullptr); - const auto me = real->participantByPeer(_joinAs); + const auto me = real->participantByPeer(joinAs()); if (me && me->videoJoined) { _videoIsWorking = true; } else { @@ -2642,23 +2642,23 @@ void GroupCall::fillActiveVideoEndpoints() { const auto camera = GetCameraEndpoint(participant.videoParams); if (camera != _cameraEndpoint && camera != _screenEndpoint - && participant.peer != _joinAs) { + && participant.peer != joinAs()) { const auto paused = IsCameraPaused(participant.videoParams); feedOne({ Type::Camera, participant.peer, camera }, paused); } const auto screen = GetScreenEndpoint(participant.videoParams); if (screen != _cameraEndpoint && screen != _screenEndpoint - && participant.peer != _joinAs) { + && participant.peer != joinAs()) { const auto paused = IsScreenPaused(participant.videoParams); feedOne({ Type::Screen, participant.peer, screen }, paused); } } feedOne( - { Type::Camera, _joinAs, cameraSharingEndpoint() }, + { Type::Camera, joinAs(), cameraSharingEndpoint() }, isCameraPaused()); feedOne( - { Type::Screen, _joinAs, screenSharingEndpoint() }, + { Type::Screen, joinAs(), screenSharingEndpoint() }, isScreenPaused()); if (large && !largeFound) { setVideoEndpointLarge({}); @@ -3013,7 +3013,7 @@ void GroupCall::sendSelfUpdate(SendUpdateType type) { ? Flag::f_presentation_paused : Flag::f_muted), inputCall(), - _joinAs->input, + joinAs()->input, MTP_bool(muted() != MuteState::Active), MTP_int(100000), // volume MTP_bool(muted() == MuteState::RaisedHand), diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.h b/Telegram/SourceFiles/calls/group/calls_group_call.h index 6ef9ad6009..db625b4111 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.h +++ b/Telegram/SourceFiles/calls/group/calls_group_call.h @@ -220,7 +220,10 @@ public: return _peer; } [[nodiscard]] not_null joinAs() const { - return _joinAs; + return _joinAs.current(); + } + [[nodiscard]] rpl::producer> joinAsValue() const { + return _joinAs.value(); } [[nodiscard]] bool showChooseJoinAs() const; [[nodiscard]] TimeId scheduleDate() const { @@ -566,7 +569,7 @@ private: MediaChannelDescriptionsTask>, base::pointer_comparator> _mediaChannelDescriptionses; - not_null _joinAs; + rpl::variable> _joinAs; std::vector> _possibleJoinAs; QString _joinHash; diff --git a/Telegram/SourceFiles/calls/group/calls_group_members.cpp b/Telegram/SourceFiles/calls/group/calls_group_members.cpp index 94a4a86ebf..c7bb6115ce 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_members.cpp @@ -1605,30 +1605,47 @@ void Members::setupAddMember(not_null call) { using namespace rpl::mappers; const auto peer = call->peer(); - if (const auto channel = peer->asBroadcast()) { - _canAddMembers = rpl::single( + const auto canAddByPeer = [=](not_null peer) { + if (peer->isBroadcast()) { + return rpl::single(false) | rpl::type_erased(); + } + return rpl::combine( + Data::CanWriteValue(peer.get()), + _call->joinAsValue() + ) | rpl::map([=](bool can, not_null joinAs) { + return can && joinAs->isSelf(); + }); + }; + const auto canInviteByLinkByPeer = [=](not_null peer) { + const auto channel = peer->asChannel(); + if (!channel) { + return rpl::single(false) | rpl::type_erased(); + } + return rpl::single( false ) | rpl::then(_call->real( ) | rpl::map([=] { return Data::PeerFlagValue( channel, ChannelDataFlag::Username); - }) | rpl::flatten_latest()); - } else { - _canAddMembers = Data::CanWriteValue(peer.get()); - SubscribeToMigration( - peer, - lifetime(), - [=](not_null channel) { - _canAddMembers = Data::CanWriteValue(channel.get()); - }); - } + }) | rpl::flatten_latest()) | rpl::type_erased(); + }; + _canAddMembers = canAddByPeer(peer); + _canInviteByLink = canInviteByLinkByPeer(peer); + SubscribeToMigration( + peer, + lifetime(), + [=](not_null channel) { + _canAddMembers = canAddByPeer(channel); + _canInviteByLink = canInviteByLinkByPeer(channel); + }); rpl::combine( _canAddMembers.value(), + _canInviteByLink.value(), _mode.value() - ) | rpl::start_with_next([=](bool can, PanelMode mode) { - if (!can) { + ) | rpl::start_with_next([=](bool add, bool invite, PanelMode mode) { + if (!add && !invite) { if (const auto old = _addMemberButton.current()) { delete old; _addMemberButton = nullptr; diff --git a/Telegram/SourceFiles/calls/group/calls_group_members.h b/Telegram/SourceFiles/calls/group/calls_group_members.h index f828d79105..89d803ea63 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members.h +++ b/Telegram/SourceFiles/calls/group/calls_group_members.h @@ -108,6 +108,7 @@ private: ListWidget *_list = nullptr; rpl::event_stream<> _addMemberRequests; + rpl::variable _canInviteByLink; rpl::variable _canAddMembers; }; diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp index 5fed7d911c..c4fadd28f8 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp @@ -781,10 +781,14 @@ void Panel::setupMembers() { _members->addMembersRequests( ) | rpl::start_with_next([=] { - if (_peer->isBroadcast() && _peer->asChannel()->hasUsername()) { - _callShareLinkCallback(); - } else { + if (!_peer->isBroadcast() + && _peer->canWrite() + && _call->joinAs()->isSelf()) { addMembers(); + } else if (const auto channel = _peer->asChannel()) { + if (channel->hasUsername()) { + _callShareLinkCallback(); + } } }, _callLifetime);