From 4659cc50f227ab6f9d9fc092ccf442c06825aa4a Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 15 Mar 2021 22:40:59 +0400 Subject: [PATCH] Allow inviting members in channel voice chats. --- .../SourceFiles/calls/calls_group_members.cpp | 75 +++++--- .../SourceFiles/calls/calls_group_members.h | 12 +- .../SourceFiles/calls/calls_group_panel.cpp | 105 ++++++----- .../SourceFiles/calls/calls_group_panel.h | 19 +- .../calls/calls_group_settings.cpp | 174 ++++++++++-------- .../SourceFiles/calls/calls_group_settings.h | 5 + Telegram/SourceFiles/calls/calls_instance.cpp | 2 +- Telegram/SourceFiles/calls/calls_instance.h | 4 +- 8 files changed, 225 insertions(+), 171 deletions(-) diff --git a/Telegram/SourceFiles/calls/calls_group_members.cpp b/Telegram/SourceFiles/calls/calls_group_members.cpp index 2bba752fc..4a79cb519 100644 --- a/Telegram/SourceFiles/calls/calls_group_members.cpp +++ b/Telegram/SourceFiles/calls/calls_group_members.cpp @@ -37,7 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "styles/style_calls.h" -namespace Calls { +namespace Calls::Group { namespace { constexpr auto kBlobsEnterDuration = crl::time(250); @@ -1747,8 +1747,7 @@ std::unique_ptr MembersController::createInvitedRow( } // namespace - -GroupMembers::GroupMembers( +Members::Members( not_null parent, not_null call) : RpWidget(parent) @@ -1762,25 +1761,25 @@ GroupMembers::GroupMembers( _listController->setDelegate(static_cast(this)); } -auto GroupMembers::toggleMuteRequests() const +auto Members::toggleMuteRequests() const -> rpl::producer { return static_cast( _listController.get())->toggleMuteRequests(); } -auto GroupMembers::changeVolumeRequests() const +auto Members::changeVolumeRequests() const -> rpl::producer { return static_cast( _listController.get())->changeVolumeRequests(); } -auto GroupMembers::kickParticipantRequests() const +auto Members::kickParticipantRequests() const -> rpl::producer> { return static_cast( _listController.get())->kickParticipantRequests(); } -int GroupMembers::desiredHeight() const { +int Members::desiredHeight() const { const auto top = _addMember ? _addMember->height() : 0; auto count = [&] { if (const auto call = _call.get()) { @@ -1798,7 +1797,7 @@ int GroupMembers::desiredHeight() const { + (use ? st::lineWidth : 0); } -rpl::producer GroupMembers::desiredHeightValue() const { +rpl::producer Members::desiredHeightValue() const { const auto controller = static_cast( _listController.get()); return rpl::combine( @@ -1810,12 +1809,28 @@ rpl::producer GroupMembers::desiredHeightValue() const { }); } -void GroupMembers::setupAddMember(not_null call) { +void Members::setupAddMember(not_null call) { using namespace rpl::mappers; const auto peer = call->peer(); - if (peer->isBroadcast()) { - _canAddMembers = false; + if (const auto channel = peer->asBroadcast()) { + _canAddMembers = rpl::single( + false + ) | rpl::then(peer->session().changes().peerFlagsValue( + peer, + Data::PeerUpdate::Flag::GroupCall + ) | rpl::map([=] { + return peer->groupCall(); + }) | rpl::filter([=](Data::GroupCall *real) { + const auto call = _call.get(); + return call && real && (real->id() == call->id()); + }) | rpl::take( + 1 + ) | rpl::map([=] { + return Data::PeerFlagValue( + channel, + MTPDchannel::Flag::f_username); + }) | rpl::flatten_latest()); } else { _canAddMembers = Data::CanWriteValue(peer.get()); SubscribeToMigration( @@ -1851,12 +1866,12 @@ void GroupMembers::setupAddMember(not_null call) { }, lifetime()); } -rpl::producer GroupMembers::fullCountValue() const { +rpl::producer Members::fullCountValue() const { return static_cast( _listController.get())->fullCountValue(); } -void GroupMembers::setupList() { +void Members::setupList() { _listController->setStyleOverrides(&st::groupCallMembersList); _list = _scroll->setOwnedWidget(object_ptr( this, @@ -1877,11 +1892,11 @@ void GroupMembers::setupList() { updateControlsGeometry(); } -void GroupMembers::resizeEvent(QResizeEvent *e) { +void Members::resizeEvent(QResizeEvent *e) { updateControlsGeometry(); } -void GroupMembers::resizeToList() { +void Members::resizeToList() { if (!_list) { return; } @@ -1898,7 +1913,7 @@ void GroupMembers::resizeToList() { } } -void GroupMembers::updateControlsGeometry() { +void Members::updateControlsGeometry() { if (!_list) { return; } @@ -1912,7 +1927,7 @@ void GroupMembers::updateControlsGeometry() { _list->resizeToWidth(width()); } -void GroupMembers::setupFakeRoundCorners() { +void Members::setupFakeRoundCorners() { const auto size = st::roundRadiusLarge; const auto full = 3 * size; const auto imagePartSize = size * cIntRetinaFactor(); @@ -1975,40 +1990,40 @@ void GroupMembers::setupFakeRoundCorners() { }, lifetime()); } -void GroupMembers::peerListSetTitle(rpl::producer title) { +void Members::peerListSetTitle(rpl::producer title) { } -void GroupMembers::peerListSetAdditionalTitle(rpl::producer title) { +void Members::peerListSetAdditionalTitle(rpl::producer title) { } -void GroupMembers::peerListSetHideEmpty(bool hide) { +void Members::peerListSetHideEmpty(bool hide) { } -bool GroupMembers::peerListIsRowChecked(not_null row) { +bool Members::peerListIsRowChecked(not_null row) { return false; } -void GroupMembers::peerListScrollToTop() { +void Members::peerListScrollToTop() { } -int GroupMembers::peerListSelectedRowsCount() { +int Members::peerListSelectedRowsCount() { return 0; } -void GroupMembers::peerListAddSelectedPeerInBunch(not_null peer) { - Unexpected("Item selection in Calls::GroupMembers."); +void Members::peerListAddSelectedPeerInBunch(not_null peer) { + Unexpected("Item selection in Calls::Members."); } -void GroupMembers::peerListAddSelectedRowInBunch(not_null row) { - Unexpected("Item selection in Calls::GroupMembers."); +void Members::peerListAddSelectedRowInBunch(not_null row) { + Unexpected("Item selection in Calls::Members."); } -void GroupMembers::peerListFinishSelectedRowsBunch() { +void Members::peerListFinishSelectedRowsBunch() { } -void GroupMembers::peerListSetDescription( +void Members::peerListSetDescription( object_ptr description) { description.destroy(); } -} // namespace Calls +} // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/calls_group_members.h b/Telegram/SourceFiles/calls/calls_group_members.h index 88f459adc..23dc33717 100644 --- a/Telegram/SourceFiles/calls/calls_group_members.h +++ b/Telegram/SourceFiles/calls/calls_group_members.h @@ -19,19 +19,19 @@ class GroupCall; } // namespace Data namespace Calls { +class GroupCall; +} // namespace Calls + +namespace Calls::Group { -namespace Group { struct VolumeRequest; struct MuteRequest; -} // namespace Group -class GroupCall; - -class GroupMembers final +class Members final : public Ui::RpWidget , private PeerListContentDelegate { public: - GroupMembers( + Members( not_null parent, not_null call); diff --git a/Telegram/SourceFiles/calls/calls_group_panel.cpp b/Telegram/SourceFiles/calls/calls_group_panel.cpp index 82412b90c..a8882104e 100644 --- a/Telegram/SourceFiles/calls/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_group_panel.cpp @@ -49,7 +49,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include -namespace Calls { +namespace Calls::Group { namespace { constexpr auto kSpacePushToTalkDelay = crl::time(250); @@ -247,7 +247,7 @@ std::unique_ptr InviteContactsController::createRow( } // namespace -GroupPanel::GroupPanel(not_null call) +Panel::Panel(not_null call) : _call(call) , _peer(call->peer()) , _window(std::make_unique(Core::App().getModalParent())) @@ -308,13 +308,13 @@ GroupPanel::GroupPanel(not_null call) }, widget()->lifetime()); } -GroupPanel::~GroupPanel() { +Panel::~Panel() { if (_menu) { _menu.destroy(); } } -void GroupPanel::setupRealCallViewers(not_null call) { +void Panel::setupRealCallViewers(not_null call) { const auto peer = call->peer(); peer->session().changes().peerFlagsValue( peer, @@ -330,21 +330,21 @@ void GroupPanel::setupRealCallViewers(not_null call) { }, _window->lifetime()); } -bool GroupPanel::isActive() const { +bool Panel::isActive() const { return _window->isActiveWindow() && _window->isVisible() && !(_window->windowState() & Qt::WindowMinimized); } -void GroupPanel::minimize() { +void Panel::minimize() { _window->setWindowState(_window->windowState() | Qt::WindowMinimized); } -void GroupPanel::close() { +void Panel::close() { _window->close(); } -void GroupPanel::showAndActivate() { +void Panel::showAndActivate() { if (_window->isHidden()) { _window->show(); } @@ -357,7 +357,7 @@ void GroupPanel::showAndActivate() { _window->setFocus(); } -void GroupPanel::migrate(not_null channel) { +void Panel::migrate(not_null channel) { _peer = channel; _peerLifetime.destroy(); subscribeToPeerChanges(); @@ -365,7 +365,7 @@ void GroupPanel::migrate(not_null channel) { refreshTitle(); } -void GroupPanel::subscribeToPeerChanges() { +void Panel::subscribeToPeerChanges() { Info::Profile::NameValue( _peer ) | rpl::start_with_next([=](const TextWithEntities &name) { @@ -373,7 +373,7 @@ void GroupPanel::subscribeToPeerChanges() { }, _peerLifetime); } -void GroupPanel::initWindow() { +void Panel::initWindow() { _window->setAttribute(Qt::WA_OpaquePaintEvent); _window->setAttribute(Qt::WA_NoSystemBackground); _window->setWindowIcon( @@ -412,7 +412,7 @@ void GroupPanel::initWindow() { }); } -void GroupPanel::initWidget() { +void Panel::initWidget() { widget()->setMouseTracking(true); widget()->paintRequest( @@ -430,7 +430,7 @@ void GroupPanel::initWidget() { }, widget()->lifetime()); } -void GroupPanel::endCall() { +void Panel::endCall() { if (!_call) { return; } else if (!_call->peer()->canManageGroupCall()) { @@ -438,13 +438,13 @@ void GroupPanel::endCall() { return; } _layerBg->showBox(Box( - Group::LeaveBox, + LeaveBox, _call, false, - Group::BoxContext::GroupCallPanel)); + BoxContext::GroupCallPanel)); } -void GroupPanel::initControls() { +void Panel::initControls() { _mute->clicks( ) | rpl::filter([=](Qt::MouseButton button) { return (button == Qt::LeftButton) && (_call != nullptr); @@ -463,7 +463,7 @@ void GroupPanel::initControls() { _hangup->setClickedCallback([=] { endCall(); }); _settings->setClickedCallback([=] { if (_call) { - _layerBg->showBox(Box(Group::SettingsBox, _call)); + _layerBg->showBox(Box(SettingsBox, _call)); } }); @@ -478,7 +478,7 @@ void GroupPanel::initControls() { initWithCall(_call); } -void GroupPanel::initWithCall(GroupCall *call) { +void Panel::initWithCall(GroupCall *call) { _callLifetime.destroy(); _call = call; if (!_call) { @@ -505,14 +505,14 @@ void GroupPanel::initWithCall(GroupCall *call) { }, _callLifetime); _members->toggleMuteRequests( - ) | rpl::start_with_next([=](Group::MuteRequest request) { + ) | rpl::start_with_next([=](MuteRequest request) { if (_call) { _call->toggleMute(request); } }, _callLifetime); _members->changeVolumeRequests( - ) | rpl::start_with_next([=](Group::VolumeRequest request) { + ) | rpl::start_with_next([=](VolumeRequest request) { if (_call) { _call->changeVolume(request); } @@ -525,10 +525,27 @@ void GroupPanel::initWithCall(GroupCall *call) { } }, _callLifetime); + const auto showBox = [=](object_ptr next) { + _layerBg->showBox(std::move(next)); + }; + const auto showToast = [=](QString text) { + Ui::Toast::Show(widget(), text); + }; + auto [shareLinkCallback, shareLinkLifetime] = ShareInviteLinkAction( + _peer, + showBox, + showToast); + auto shareLink = std::move(shareLinkCallback); + _members->lifetime().add(std::move(shareLinkLifetime)); + _members->addMembersRequests( ) | rpl::start_with_next([=] { if (_call) { - addMembers(); + if (_peer->isBroadcast() && _peer->asChannel()->hasUsername()) { + shareLink(); + } else { + addMembers(); + } } }, _callLifetime); @@ -574,7 +591,7 @@ void GroupPanel::initWithCall(GroupCall *call) { }, _callLifetime); } -void GroupPanel::subscribeToChanges(not_null real) { +void Panel::subscribeToChanges(not_null real) { _titleText = real->titleValue(); const auto validateRecordingMark = [=](bool recording) { @@ -634,7 +651,7 @@ void GroupPanel::subscribeToChanges(not_null real) { rpl::single( _call->joinAs() ) | rpl::then(_call->rejoinEvents( - ) | rpl::map([](const Group::RejoinEvent &event) { + ) | rpl::map([](const RejoinEvent &event) { return event.nowJoinAs; })) | rpl::start_with_next([=](not_null joinAs) { auto joinAsToggle = object_ptr( @@ -656,9 +673,9 @@ void GroupPanel::subscribeToChanges(not_null real) { updateControlsGeometry(); } -void GroupPanel::chooseJoinAs() { - const auto context = Group::ChooseJoinAsProcess::Context::Switch; - const auto callback = [=](Group::JoinInfo info) { +void Panel::chooseJoinAs() { + const auto context = ChooseJoinAsProcess::Context::Switch; + const auto callback = [=](JoinInfo info) { if (_call) { _call->rejoinAs(info); } @@ -678,12 +695,12 @@ void GroupPanel::chooseJoinAs() { _call->joinAs()); } -void GroupPanel::showMainMenu() { +void Panel::showMainMenu() { if (_menu || !_call) { return; } _menu.create(widget(), st::groupCallDropdownMenu); - Group::FillMenu( + FillMenu( _menu.data(), _peer, _call, @@ -725,7 +742,7 @@ void GroupPanel::showMainMenu() { } } -void GroupPanel::addMembers() { +void Panel::addMembers() { const auto real = _peer->groupCall(); if (!_call || !real || real->id() != _call->id()) { return; @@ -825,7 +842,7 @@ void GroupPanel::addMembers() { finish(); }; auto box = Box( - Group::ConfirmBox, + ConfirmBox, TextWithEntities{ text }, tr::lng_participant_invite(), [=] { inviteWithAdd(users, nonMembers, finishWithConfirm); }); @@ -866,7 +883,7 @@ void GroupPanel::addMembers() { _layerBg->showBox(Box(std::move(controllers), initBox)); } -void GroupPanel::kickMember(not_null user) { +void Panel::kickMember(not_null user) { _layerBg->showBox(Box([=](not_null box) { box->addRow( object_ptr( @@ -889,7 +906,7 @@ void GroupPanel::kickMember(not_null user) { })); } -void GroupPanel::kickMemberSure(not_null user) { +void Panel::kickMemberSure(not_null user) { if (const auto chat = _peer->asChat()) { chat->session().api().kickParticipant(chat, user); } else if (const auto channel = _peer->asChannel()) { @@ -907,7 +924,7 @@ void GroupPanel::kickMemberSure(not_null user) { } } -void GroupPanel::initLayout() { +void Panel::initLayout() { initGeometry(); #ifndef Q_OS_MAC @@ -922,18 +939,18 @@ void GroupPanel::initLayout() { #endif // !Q_OS_MAC } -void GroupPanel::showControls() { +void Panel::showControls() { Expects(_call != nullptr); widget()->showChildren(); } -void GroupPanel::closeBeforeDestroy() { +void Panel::closeBeforeDestroy() { _window->close(); initWithCall(nullptr); } -void GroupPanel::initGeometry() { +void Panel::initGeometry() { const auto center = Core::App().getPointForCallPanelCenter(); const auto rect = QRect(0, 0, st::groupCallWidth, st::groupCallHeight); _window->setGeometry(rect.translated(center - rect.center())); @@ -942,7 +959,7 @@ void GroupPanel::initGeometry() { updateControlsGeometry(); } -QRect GroupPanel::computeTitleRect() const { +QRect Panel::computeTitleRect() const { const auto skip = st::groupCallTitleTop; const auto remove = skip + (_menuToggle ? (_menuToggle->width() + st::groupCallMenuTogglePosition.x()) @@ -961,7 +978,7 @@ QRect GroupPanel::computeTitleRect() const { #endif // !Q_OS_MAC } -void GroupPanel::updateControlsGeometry() { +void Panel::updateControlsGeometry() { if (widget()->size().isEmpty()) { return; } @@ -1019,7 +1036,7 @@ void GroupPanel::updateControlsGeometry() { } } -void GroupPanel::refreshTitle() { +void Panel::refreshTitle() { if (!_title) { auto text = rpl::combine( Info::Profile::NameValue(_peer), @@ -1060,7 +1077,7 @@ void GroupPanel::refreshTitle() { top); } -void GroupPanel::refreshTitleGeometry() { +void Panel::refreshTitleGeometry() { if (!_title) { return; } @@ -1099,7 +1116,7 @@ void GroupPanel::refreshTitleGeometry() { } } -void GroupPanel::paint(QRect clip) { +void Panel::paint(QRect clip) { Painter p(widget()); auto region = QRegion(clip); @@ -1108,7 +1125,7 @@ void GroupPanel::paint(QRect clip) { } } -bool GroupPanel::handleClose() { +bool Panel::handleClose() { if (_call) { _window->hide(); return true; @@ -1116,8 +1133,8 @@ bool GroupPanel::handleClose() { return false; } -not_null GroupPanel::widget() const { +not_null Panel::widget() const { return _window->body(); } -} // namespace Calls +} // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/calls_group_panel.h b/Telegram/SourceFiles/calls/calls_group_panel.h index 8adc64513..fc848d425 100644 --- a/Telegram/SourceFiles/calls/calls_group_panel.h +++ b/Telegram/SourceFiles/calls/calls_group_panel.h @@ -48,17 +48,14 @@ struct CallSignalBars; struct CallBodyLayout; } // namespace style -namespace Calls { +namespace Calls::Group { -class Userpic; -class SignalBars; +class Members; -class GroupMembers; - -class GroupPanel final { +class Panel final { public: - GroupPanel(not_null call); - ~GroupPanel(); + Panel(not_null call); + ~Panel(); [[nodiscard]] bool isActive() const; void minimize(); @@ -119,9 +116,9 @@ private: object_ptr _menuToggle = { nullptr }; object_ptr _menu = { nullptr }; object_ptr _joinAsToggle = { nullptr }; - object_ptr _members; + object_ptr _members; rpl::variable _titleText; - Group::ChooseJoinAsProcess _joinAsProcess; + ChooseJoinAsProcess _joinAsProcess; object_ptr _settings; std::unique_ptr _mute; @@ -131,4 +128,4 @@ private: }; -} // namespace Calls +} // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/calls_group_settings.cpp b/Telegram/SourceFiles/calls/calls_group_settings.cpp index 7525f922e..b1c254e2f 100644 --- a/Telegram/SourceFiles/calls/calls_group_settings.cpp +++ b/Telegram/SourceFiles/calls/calls_group_settings.cpp @@ -216,14 +216,6 @@ void SettingsBox( const auto weakBox = Ui::MakeWeak(box); struct State { - State(not_null session) : session(session) { - } - ~State() { - session->api().request(linkListenerRequestId).cancel(); - session->api().request(linkSpeakerRequestId).cancel(); - } - - not_null session; rpl::event_stream outputNameStream; rpl::event_stream inputNameStream; std::unique_ptr micTester; @@ -231,14 +223,10 @@ void SettingsBox( float micLevel = 0.; Ui::Animations::Simple micLevelAnimation; base::Timer levelUpdateTimer; - std::optional linkSpeaker; - QString linkListener; bool generatingLink = false; - mtpRequestId linkListenerRequestId = 0; - mtpRequestId linkSpeakerRequestId = 0; }; const auto peer = call->peer(); - const auto state = box->lifetime().make_state(&peer->session()); + const auto state = box->lifetime().make_state(); const auto real = peer->groupCall(); const auto id = call->id(); const auto goodReal = (real && real->id() == id); @@ -538,74 +526,25 @@ void SettingsBox( //AddDivider(layout); //AddSkip(layout); - if (!peer->canManageGroupCall()) { - state->linkSpeaker = QString(); - } - auto shareLink = Fn(); if (peer->isChannel() && peer->asChannel()->hasUsername() && goodReal) { - const auto input = real->input(); - const auto shareReady = [=] { - if (!state->linkSpeaker.has_value() - || state->linkListener.isEmpty()) { - return false; - } - const auto showToast = crl::guard(box, [=](QString text) { - Ui::Toast::Show( - box->getDelegate()->outerContainer(), - text); - }); - box->getDelegate()->show(ShareInviteLinkBox( - peer, - *state->linkSpeaker, - state->linkListener, - showToast)); - return true; - }; - shareLink = [=] { - if (shareReady() || state->generatingLink) { - return; - } - state->generatingLink = true; - - state->linkListenerRequestId = peer->session().api().request( - MTPphone_ExportGroupCallInvite( - MTP_flags(0), - input - ) - ).done(crl::guard(box, [=]( - const MTPphone_ExportedGroupCallInvite &result) { - state->linkListenerRequestId = 0; - result.match([&]( - const MTPDphone_exportedGroupCallInvite &data) { - state->linkListener = qs(data.vlink()); - shareReady(); - }); - })).send(); - - if (!state->linkSpeaker.has_value()) { - using Flag = MTPphone_ExportGroupCallInvite::Flag; - state->linkSpeakerRequestId = peer->session().api().request( - MTPphone_ExportGroupCallInvite( - MTP_flags(Flag::f_can_self_unmute), - input - )).done(crl::guard(box, [=]( - const MTPphone_ExportedGroupCallInvite &result) { - state->linkSpeakerRequestId = 0; - result.match([&]( - const MTPDphone_exportedGroupCallInvite &data) { - state->linkSpeaker = qs(data.vlink()); - shareReady(); - }); - })).fail([=] { - state->linkSpeakerRequestId = 0; - state->linkSpeaker = QString(); - shareReady(); - }).send(); - } - }; + const auto showBox = crl::guard(box, [=]( + object_ptr box) { + box->getDelegate()->show(std::move(box)); + }); + const auto showToast = crl::guard(box, [=](QString text) { + Ui::Toast::Show( + box->getDelegate()->outerContainer(), + text); + }); + auto [shareLinkCallback, shareLinkLifetime] = ShareInviteLinkAction( + peer, + showBox, + showToast); + shareLink = std::move(shareLinkCallback); + box->lifetime().add(std::move(shareLinkLifetime)); } else { const auto lookupLink = [=] { if (const auto group = peer->asMegagroup()) { @@ -698,4 +637,85 @@ void SettingsBox( }); } +std::pair, rpl::lifetime> ShareInviteLinkAction( + not_null peer, + Fn)> showBox, + Fn showToast) { + auto lifetime = rpl::lifetime(); + struct State { + State(not_null session) : session(session) { + } + ~State() { + session->api().request(linkListenerRequestId).cancel(); + session->api().request(linkSpeakerRequestId).cancel(); + } + + not_null session; + std::optional linkSpeaker; + QString linkListener; + mtpRequestId linkListenerRequestId = 0; + mtpRequestId linkSpeakerRequestId = 0; + bool generatingLink = false; + }; + const auto state = lifetime.make_state(&peer->session()); + if (!peer->canManageGroupCall()) { + state->linkSpeaker = QString(); + } + + const auto shareReady = [=] { + if (!state->linkSpeaker.has_value() + || state->linkListener.isEmpty()) { + return false; + } + showBox(ShareInviteLinkBox( + peer, + *state->linkSpeaker, + state->linkListener, + showToast)); + return true; + }; + auto callback = [=] { + const auto real = peer->groupCall(); + if (shareReady() || state->generatingLink || !real) { + return; + } + state->generatingLink = true; + + state->linkListenerRequestId = peer->session().api().request( + MTPphone_ExportGroupCallInvite( + MTP_flags(0), + real->input() + ) + ).done([=](const MTPphone_ExportedGroupCallInvite &result) { + state->linkListenerRequestId = 0; + result.match([&]( + const MTPDphone_exportedGroupCallInvite &data) { + state->linkListener = qs(data.vlink()); + shareReady(); + }); + }).send(); + + if (!state->linkSpeaker.has_value()) { + using Flag = MTPphone_ExportGroupCallInvite::Flag; + state->linkSpeakerRequestId = peer->session().api().request( + MTPphone_ExportGroupCallInvite( + MTP_flags(Flag::f_can_self_unmute), + real->input() + )).done([=](const MTPphone_ExportedGroupCallInvite &result) { + state->linkSpeakerRequestId = 0; + result.match([&]( + const MTPDphone_exportedGroupCallInvite &data) { + state->linkSpeaker = qs(data.vlink()); + shareReady(); + }); + }).fail([=] { + state->linkSpeakerRequestId = 0; + state->linkSpeaker = QString(); + shareReady(); + }).send(); + } + }; + return { std::move(callback), std::move(lifetime) }; +} + } // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/calls_group_settings.h b/Telegram/SourceFiles/calls/calls_group_settings.h index fae25d53c..744b8fc50 100644 --- a/Telegram/SourceFiles/calls/calls_group_settings.h +++ b/Telegram/SourceFiles/calls/calls_group_settings.h @@ -19,4 +19,9 @@ void SettingsBox( not_null box, not_null call); +[[nodiscard]] std::pair, rpl::lifetime> ShareInviteLinkAction( + not_null peer, + Fn)> showBox, + Fn showToast); + } // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index 1ab8a8c1a..fc390f974 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -224,7 +224,7 @@ void Instance::createGroupCall( destroyGroupCall(raw); }, raw->lifetime()); - _currentGroupCallPanel = std::make_unique(raw); + _currentGroupCallPanel = std::make_unique(raw); _currentGroupCall = std::move(call); _currentGroupCallChanges.fire_copy(raw); } diff --git a/Telegram/SourceFiles/calls/calls_instance.h b/Telegram/SourceFiles/calls/calls_instance.h index 891b1c49e..18a217fc4 100644 --- a/Telegram/SourceFiles/calls/calls_instance.h +++ b/Telegram/SourceFiles/calls/calls_instance.h @@ -26,12 +26,12 @@ class Session; namespace Calls::Group { struct JoinInfo; +class Panel; } // namespace Calls::Group namespace Calls { class Panel; -class GroupPanel; class Instance : private Call::Delegate @@ -146,7 +146,7 @@ private: std::unique_ptr _currentGroupCall; rpl::event_stream _currentGroupCallChanges; - std::unique_ptr _currentGroupCallPanel; + std::unique_ptr _currentGroupCallPanel; base::flat_map> _tracks;