Allow inviting members in channel voice chats.

This commit is contained in:
John Preston 2021-03-15 22:40:59 +04:00
parent 2fddeb478b
commit 4659cc50f2
8 changed files with 225 additions and 171 deletions

View File

@ -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<Row> MembersController::createInvitedRow(
} // namespace
GroupMembers::GroupMembers(
Members::Members(
not_null<QWidget*> parent,
not_null<GroupCall*> call)
: RpWidget(parent)
@ -1762,25 +1761,25 @@ GroupMembers::GroupMembers(
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
}
auto GroupMembers::toggleMuteRequests() const
auto Members::toggleMuteRequests() const
-> rpl::producer<Group::MuteRequest> {
return static_cast<MembersController*>(
_listController.get())->toggleMuteRequests();
}
auto GroupMembers::changeVolumeRequests() const
auto Members::changeVolumeRequests() const
-> rpl::producer<Group::VolumeRequest> {
return static_cast<MembersController*>(
_listController.get())->changeVolumeRequests();
}
auto GroupMembers::kickParticipantRequests() const
auto Members::kickParticipantRequests() const
-> rpl::producer<not_null<PeerData*>> {
return static_cast<MembersController*>(
_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<int> GroupMembers::desiredHeightValue() const {
rpl::producer<int> Members::desiredHeightValue() const {
const auto controller = static_cast<MembersController*>(
_listController.get());
return rpl::combine(
@ -1810,12 +1809,28 @@ rpl::producer<int> GroupMembers::desiredHeightValue() const {
});
}
void GroupMembers::setupAddMember(not_null<GroupCall*> call) {
void Members::setupAddMember(not_null<GroupCall*> 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<GroupCall*> call) {
}, lifetime());
}
rpl::producer<int> GroupMembers::fullCountValue() const {
rpl::producer<int> Members::fullCountValue() const {
return static_cast<MembersController*>(
_listController.get())->fullCountValue();
}
void GroupMembers::setupList() {
void Members::setupList() {
_listController->setStyleOverrides(&st::groupCallMembersList);
_list = _scroll->setOwnedWidget(object_ptr<ListWidget>(
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<QString> title) {
void Members::peerListSetTitle(rpl::producer<QString> title) {
}
void GroupMembers::peerListSetAdditionalTitle(rpl::producer<QString> title) {
void Members::peerListSetAdditionalTitle(rpl::producer<QString> title) {
}
void GroupMembers::peerListSetHideEmpty(bool hide) {
void Members::peerListSetHideEmpty(bool hide) {
}
bool GroupMembers::peerListIsRowChecked(not_null<PeerListRow*> row) {
bool Members::peerListIsRowChecked(not_null<PeerListRow*> row) {
return false;
}
void GroupMembers::peerListScrollToTop() {
void Members::peerListScrollToTop() {
}
int GroupMembers::peerListSelectedRowsCount() {
int Members::peerListSelectedRowsCount() {
return 0;
}
void GroupMembers::peerListAddSelectedPeerInBunch(not_null<PeerData*> peer) {
Unexpected("Item selection in Calls::GroupMembers.");
void Members::peerListAddSelectedPeerInBunch(not_null<PeerData*> peer) {
Unexpected("Item selection in Calls::Members.");
}
void GroupMembers::peerListAddSelectedRowInBunch(not_null<PeerListRow*> row) {
Unexpected("Item selection in Calls::GroupMembers.");
void Members::peerListAddSelectedRowInBunch(not_null<PeerListRow*> row) {
Unexpected("Item selection in Calls::Members.");
}
void GroupMembers::peerListFinishSelectedRowsBunch() {
void Members::peerListFinishSelectedRowsBunch() {
}
void GroupMembers::peerListSetDescription(
void Members::peerListSetDescription(
object_ptr<Ui::FlatLabel> description) {
description.destroy();
}
} // namespace Calls
} // namespace Calls::Group

View File

@ -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<QWidget*> parent,
not_null<GroupCall*> call);

View File

@ -49,7 +49,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtWidgets/QApplication>
#include <QtGui/QWindow>
namespace Calls {
namespace Calls::Group {
namespace {
constexpr auto kSpacePushToTalkDelay = crl::time(250);
@ -247,7 +247,7 @@ std::unique_ptr<PeerListRow> InviteContactsController::createRow(
} // namespace
GroupPanel::GroupPanel(not_null<GroupCall*> call)
Panel::Panel(not_null<GroupCall*> call)
: _call(call)
, _peer(call->peer())
, _window(std::make_unique<Ui::Window>(Core::App().getModalParent()))
@ -308,13 +308,13 @@ GroupPanel::GroupPanel(not_null<GroupCall*> call)
}, widget()->lifetime());
}
GroupPanel::~GroupPanel() {
Panel::~Panel() {
if (_menu) {
_menu.destroy();
}
}
void GroupPanel::setupRealCallViewers(not_null<GroupCall*> call) {
void Panel::setupRealCallViewers(not_null<GroupCall*> call) {
const auto peer = call->peer();
peer->session().changes().peerFlagsValue(
peer,
@ -330,21 +330,21 @@ void GroupPanel::setupRealCallViewers(not_null<GroupCall*> 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<ChannelData*> channel) {
void Panel::migrate(not_null<ChannelData*> channel) {
_peer = channel;
_peerLifetime.destroy();
subscribeToPeerChanges();
@ -365,7 +365,7 @@ void GroupPanel::migrate(not_null<ChannelData*> 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<Ui::BoxContent> 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<Data::GroupCall*> real) {
void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
_titleText = real->titleValue();
const auto validateRecordingMark = [=](bool recording) {
@ -634,7 +651,7 @@ void GroupPanel::subscribeToChanges(not_null<Data::GroupCall*> 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<PeerData*> joinAs) {
auto joinAsToggle = object_ptr<Ui::UserpicButton>(
@ -656,9 +673,9 @@ void GroupPanel::subscribeToChanges(not_null<Data::GroupCall*> 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<PeerListsBox>(std::move(controllers), initBox));
}
void GroupPanel::kickMember(not_null<UserData*> user) {
void Panel::kickMember(not_null<UserData*> user) {
_layerBg->showBox(Box([=](not_null<Ui::GenericBox*> box) {
box->addRow(
object_ptr<Ui::FlatLabel>(
@ -889,7 +906,7 @@ void GroupPanel::kickMember(not_null<UserData*> user) {
}));
}
void GroupPanel::kickMemberSure(not_null<UserData*> user) {
void Panel::kickMemberSure(not_null<UserData*> 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<UserData*> 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<Ui::RpWidget*> GroupPanel::widget() const {
not_null<Ui::RpWidget*> Panel::widget() const {
return _window->body();
}
} // namespace Calls
} // namespace Calls::Group

View File

@ -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<GroupCall*> call);
~GroupPanel();
Panel(not_null<GroupCall*> call);
~Panel();
[[nodiscard]] bool isActive() const;
void minimize();
@ -119,9 +116,9 @@ private:
object_ptr<Ui::IconButton> _menuToggle = { nullptr };
object_ptr<Ui::DropdownMenu> _menu = { nullptr };
object_ptr<Ui::AbstractButton> _joinAsToggle = { nullptr };
object_ptr<GroupMembers> _members;
object_ptr<Members> _members;
rpl::variable<QString> _titleText;
Group::ChooseJoinAsProcess _joinAsProcess;
ChooseJoinAsProcess _joinAsProcess;
object_ptr<Ui::CallButton> _settings;
std::unique_ptr<Ui::CallMuteButton> _mute;
@ -131,4 +128,4 @@ private:
};
} // namespace Calls
} // namespace Calls::Group

View File

@ -216,14 +216,6 @@ void SettingsBox(
const auto weakBox = Ui::MakeWeak(box);
struct State {
State(not_null<Main::Session*> session) : session(session) {
}
~State() {
session->api().request(linkListenerRequestId).cancel();
session->api().request(linkSpeakerRequestId).cancel();
}
not_null<Main::Session*> session;
rpl::event_stream<QString> outputNameStream;
rpl::event_stream<QString> inputNameStream;
std::unique_ptr<Webrtc::AudioInputTester> micTester;
@ -231,14 +223,10 @@ void SettingsBox(
float micLevel = 0.;
Ui::Animations::Simple micLevelAnimation;
base::Timer levelUpdateTimer;
std::optional<QString> linkSpeaker;
QString linkListener;
bool generatingLink = false;
mtpRequestId linkListenerRequestId = 0;
mtpRequestId linkSpeakerRequestId = 0;
};
const auto peer = call->peer();
const auto state = box->lifetime().make_state<State>(&peer->session());
const auto state = box->lifetime().make_state<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<void()>();
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<Ui::BoxContent> 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<Fn<void()>, rpl::lifetime> ShareInviteLinkAction(
not_null<PeerData*> peer,
Fn<void(object_ptr<Ui::BoxContent>)> showBox,
Fn<void(QString)> showToast) {
auto lifetime = rpl::lifetime();
struct State {
State(not_null<Main::Session*> session) : session(session) {
}
~State() {
session->api().request(linkListenerRequestId).cancel();
session->api().request(linkSpeakerRequestId).cancel();
}
not_null<Main::Session*> session;
std::optional<QString> linkSpeaker;
QString linkListener;
mtpRequestId linkListenerRequestId = 0;
mtpRequestId linkSpeakerRequestId = 0;
bool generatingLink = false;
};
const auto state = lifetime.make_state<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

View File

@ -19,4 +19,9 @@ void SettingsBox(
not_null<Ui::GenericBox*> box,
not_null<GroupCall*> call);
[[nodiscard]] std::pair<Fn<void()>, rpl::lifetime> ShareInviteLinkAction(
not_null<PeerData*> peer,
Fn<void(object_ptr<Ui::BoxContent>)> showBox,
Fn<void(QString)> showToast);
} // namespace Calls::Group

View File

@ -224,7 +224,7 @@ void Instance::createGroupCall(
destroyGroupCall(raw);
}, raw->lifetime());
_currentGroupCallPanel = std::make_unique<GroupPanel>(raw);
_currentGroupCallPanel = std::make_unique<Group::Panel>(raw);
_currentGroupCall = std::move(call);
_currentGroupCallChanges.fire_copy(raw);
}

View File

@ -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<GroupCall> _currentGroupCall;
rpl::event_stream<GroupCall*> _currentGroupCallChanges;
std::unique_ptr<GroupPanel> _currentGroupCallPanel;
std::unique_ptr<Group::Panel> _currentGroupCallPanel;
base::flat_map<QString, std::unique_ptr<Media::Audio::Track>> _tracks;